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