Issue 163
[zxing.git] / cpp / core / src / common / Array.h
1 #ifndef __ARRAY_H__
2 #define __ARRAY_H__
3
4 /*
5  *  Array.h
6  *  zxing
7  *
8  *  Created by Christian Brunschen on 07/05/2008.
9  *  Copyright 2008 Google UK. All rights reserved.
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23
24 #include <valarray>
25 #include <cstdarg>
26
27 #ifdef DEBUG_COUNTING
28 #include <iostream>
29 #include <typeinfo>
30 #endif
31
32 #include "Counted.h"
33
34 using namespace std;
35 namespace common {
36   template<typename T> class Array : public Counted {
37   protected:
38   public:
39     valarray<T> values_;
40     Array(size_t n) : Counted(), values_(T(), n) { }
41     Array(T *ts, size_t n) : Counted(), values_(ts, n) { }
42     Array(T v, size_t n) : Counted(), values_(v, n) { }
43     Array(valarray<T> &v) : Counted(), values_(v) { }
44     Array(Array<T> &other) : Counted(), values_(other.values_) { }
45     Array(Array<T> *other) : Counted(), values_(other->values_) { }
46     virtual ~Array() { }
47     Array<T>& operator=(const Array<T> &other) { 
48 #ifdef DEBUG_COUNTING
49       cout << "assigning values from Array " << 
50       &other << " to this Array " << this << ", ";
51 #endif
52       values_ = other.values_; 
53 #ifdef DEBUG_COUNTING
54       cout << "new size = " << values_.size() << "\n";
55 #endif
56       return *this; 
57     }
58     Array<T>& operator=(const valarray<T> &array) { 
59 #ifdef DEBUG_COUNTING
60       cout << "assigning values from Array " << 
61         &array << " to this Array " << this << ", ";
62 #endif
63       values_ = array; 
64 #ifdef DEBUG_COUNTING
65       cout << "new size = " << values_.size() << "\n";
66 #endif
67       return *this; 
68     }
69     T operator[](size_t i) const { return values_[i]; }
70     T& operator[](size_t i) { return values_[i]; }
71     size_t size() const { return values_.size(); }
72     valarray<T> values() const { return values_; }
73     valarray<T>& values() { return values_; }
74   };
75   
76   template<typename T> class ArrayRef {
77   private:
78   public:
79     Array<T> *array_;
80     ArrayRef() : array_(0) { 
81 #ifdef DEBUG_COUNTING
82       cout << "instantiating empty ArrayRef " << this << "\n";
83 #endif
84     }
85     ArrayRef(size_t n) : array_(0) {
86 #ifdef DEBUG_COUNTING
87       cout << "instantiating ArrayRef " << this << 
88       "with size " << n << "\n";
89 #endif
90       reset(new Array<T>(n));
91     }
92     ArrayRef(T *ts, size_t n) : array_(0) {
93 #ifdef DEBUG_COUNTING
94       cout << "instantiating ArrayRef " << this << 
95       "with " << n << " elements at " << (void *)ts << "\n";
96 #endif
97       reset(new Array<T>(ts, n));
98     }
99     ArrayRef(Array<T> *a) : array_(0) { 
100 #ifdef DEBUG_COUNTING
101       cout << "instantiating ArrayRef " << this << " from pointer:\n";
102 #endif
103       reset(a);
104     }
105     ArrayRef(const Array<T> &a) : array_(0) { 
106 #ifdef DEBUG_COUNTING
107       cout << "instantiating ArrayRef " << this << 
108         " from reference to Array " << (void *)&a << ":\n";
109 #endif
110       reset(const_cast<Array<T> *>(&a));
111     }
112     ArrayRef(const ArrayRef &other) : array_(0) {
113 #ifdef DEBUG_COUNTING
114       cout << "instantiating ArrayRef " << this << " from ArrayRef " << 
115         &other << ":\n";
116 #endif
117       reset(other.array_);
118     }
119     
120     template<class Y>
121     ArrayRef(const ArrayRef<Y> &other) : array_(0) {
122 #ifdef DEBUG_COUNTING
123       cout << "instantiating ArrayRef " << this << " from ArrayRef " << 
124       &other << ":\n";
125 #endif
126       reset(static_cast<const Array<T> *>(other.array_));
127     }
128
129     ~ArrayRef() { 
130 #ifdef DEBUG_COUNTING
131       cout << "destroying ArrayRef " << this << " with " <<
132         (array_ ? typeid(*array_).name() : "NULL") << " " << array_ << "\n";
133 #endif
134       if (array_) { 
135         array_->release(); 
136       } 
137       array_ = 0; 
138     }
139
140     T operator[](size_t i) const { return (*array_)[i]; }
141     T& operator[](size_t i) { return (*array_)[i]; }
142     size_t size() const { return array_->size(); }
143     
144     void reset(Array<T> *a) {
145 #ifdef DEBUG_COUNTING
146       cout << "resetting ArrayRef " << this << " from " <<
147         (array_ ? typeid(*array_).name() : "NULL") << " " << array_ <<
148         " to "  << (a ? typeid(*a).name() : "NULL") << " " << a << "\n";
149 #endif
150       if (a) { a->retain(); }
151       if (array_) { array_->release(); }
152       array_ = a;
153     }
154     void reset(const ArrayRef<T> &other) {
155       reset(other.array_);
156     }
157     ArrayRef<T>& operator=(const ArrayRef<T> &other) {
158       reset(other);
159       return *this;
160     }
161     ArrayRef<T>& operator=(Array<T> *a) {
162       reset(a);
163       return *this;
164     }
165     
166     
167     Array<T>& operator*() { return *array_; }
168     Array<T>* operator->() { return array_; }
169   };
170 }
171
172 #endif // __ARRAY_H__