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