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