Updates to 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 <vector>\r
25 \r
26 #ifdef DEBUG_COUNTING\r
27 #include <iostream>\r
28 #include <typeinfo>\r
29 #endif\r
30 \r
31 #include <zxing/common/Counted.h>\r
32 \r
33 \r
34 namespace zxing {\r
35 \r
36 template<typename T> class Array : public Counted {\r
37 protected:\r
38 public:\r
39   std::vector<T> values_;\r
40   Array(size_t n) :\r
41       Counted(), values_(n, T()) {\r
42   }\r
43   Array(T *ts, size_t n) :\r
44       Counted(), values_(ts, ts+n) {\r
45   }\r
46   Array(T v, size_t n) :\r
47       Counted(), values_(n, v) {\r
48   }\r
49   Array(std::vector<T> &v) :\r
50       Counted(), values_(v) {\r
51   }\r
52   Array(Array<T> &other) :\r
53       Counted(), values_(other.values_) {\r
54   }\r
55   Array(Array<T> *other) :\r
56       Counted(), values_(other->values_) {\r
57   }\r
58   virtual ~Array() {\r
59   }\r
60   Array<T>& operator=(const Array<T> &other) {\r
61 #ifdef DEBUG_COUNTING\r
62     cout << "assigning values from Array " << &other << " to this Array " << this << ", ";\r
63 #endif\r
64     values_ = other.values_;\r
65 #ifdef DEBUG_COUNTING\r
66     cout << "new size = " << values_.size() << "\n";\r
67 #endif\r
68     return *this;\r
69   }\r
70   Array<T>& operator=(const std::vector<T> &array) {\r
71 #ifdef DEBUG_COUNTING\r
72     cout << "assigning values from Array " << &array << " to this Array " << this << ", ";\r
73 #endif\r
74     values_ = array;\r
75 #ifdef DEBUG_COUNTING\r
76     cout << "new size = " << values_.size() << "\n";\r
77 #endif\r
78     return *this;\r
79   }\r
80   T operator[](size_t i) const {\r
81     return values_[i];\r
82   }\r
83   T& operator[](size_t i) {\r
84     return values_[i];\r
85   }\r
86   size_t size() const {\r
87     return values_.size();\r
88   }\r
89   std::vector<T> values() const {\r
90     return values_;\r
91   }\r
92   std::vector<T>& values() {\r
93     return values_;\r
94   }\r
95 };\r
96 \r
97 template<typename T> class ArrayRef {\r
98 private:\r
99 public:\r
100   Array<T> *array_;\r
101   ArrayRef() :\r
102       array_(0) {\r
103 #ifdef DEBUG_COUNTING\r
104     cout << "instantiating empty ArrayRef " << this << "\n";\r
105 #endif\r
106   }\r
107   ArrayRef(size_t n) :\r
108       array_(0) {\r
109 #ifdef DEBUG_COUNTING\r
110     cout << "instantiating ArrayRef " << this << "with size " << n << "\n";\r
111 #endif\r
112     reset(new Array<T> (n));\r
113   }\r
114   ArrayRef(T *ts, size_t n) :\r
115       array_(0) {\r
116 #ifdef DEBUG_COUNTING\r
117     cout << "instantiating ArrayRef " << this << "with " << n << " elements at " << (void *)ts << "\n";\r
118 #endif\r
119     reset(new Array<T> (ts, n));\r
120   }\r
121   ArrayRef(Array<T> *a) :\r
122       array_(0) {\r
123 #ifdef DEBUG_COUNTING\r
124     cout << "instantiating ArrayRef " << this << " from pointer:\n";\r
125 #endif\r
126     reset(a);\r
127   }\r
128   ArrayRef(const Array<T> &a) :\r
129       array_(0) {\r
130 #ifdef DEBUG_COUNTING\r
131     cout << "instantiating ArrayRef " << this << " from reference to Array " << (void *)&a << ":\n";\r
132 #endif\r
133     reset(const_cast<Array<T> *>(&a));\r
134   }\r
135   ArrayRef(const ArrayRef &other) :\r
136       array_(0) {\r
137 #ifdef DEBUG_COUNTING\r
138     cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";\r
139 #endif\r
140     reset(other.array_);\r
141   }\r
142 \r
143   template<class Y>\r
144   ArrayRef(const ArrayRef<Y> &other) :\r
145       array_(0) {\r
146 #ifdef DEBUG_COUNTING\r
147     cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n";\r
148 #endif\r
149     reset(static_cast<const Array<T> *>(other.array_));\r
150   }\r
151 \r
152   ~ArrayRef() {\r
153 #ifdef DEBUG_COUNTING\r
154     cout << "destroying ArrayRef " << this << " with " << (array_ ? typeid(*array_).name() : "NULL") << " "\r
155          << array_ << "\n";\r
156 #endif\r
157     if (array_) {\r
158       array_->release();\r
159     }\r
160     array_ = 0;\r
161   }\r
162 \r
163   T operator[](size_t i) const {\r
164     return (*array_)[i];\r
165   }\r
166   T& operator[](size_t i) {\r
167     return (*array_)[i];\r
168   }\r
169   size_t size() const {\r
170     return array_->size();\r
171   }\r
172 \r
173   void reset(Array<T> *a) {\r
174 #ifdef DEBUG_COUNTING\r
175     cout << "resetting ArrayRef " << this << " from " << (array_ ? typeid(*array_).name() : "NULL") << " "\r
176          << array_ << " to " << (a ? typeid(*a).name() : "NULL") << " " << a << "\n";\r
177 #endif\r
178     if (a) {\r
179       a->retain();\r
180     }\r
181     if (array_) {\r
182       array_->release();\r
183     }\r
184     array_ = a;\r
185   }\r
186   void reset(const ArrayRef<T> &other) {\r
187     reset(other.array_);\r
188   }\r
189   ArrayRef<T>& operator=(const ArrayRef<T> &other) {\r
190     reset(other);\r
191     return *this;\r
192   }\r
193   ArrayRef<T>& operator=(Array<T> *a) {\r
194     reset(a);\r
195     return *this;\r
196   }\r
197 \r
198   Array<T>& operator*() {\r
199     return *array_;\r
200   }\r
201   Array<T>* operator->() {\r
202     return array_;\r
203   }\r
204 };\r
205 \r
206 } // namespace zxing\r
207 \r
208 #endif // __ARRAY_H__\r