// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*- #ifndef __ARRAY_H__ #define __ARRAY_H__ /* * Array.h * zxing * * Copyright 2010 ZXing authors All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #ifdef DEBUG_COUNTING #include #include #endif #include namespace zxing { template class Array : public Counted { protected: public: std::vector values_; Array(size_t n) : Counted(), values_(n, T()) { } Array(T *ts, size_t n) : Counted(), values_(ts, ts+n) { } Array(T v, size_t n) : Counted(), values_(n, v) { } Array(std::vector &v) : Counted(), values_(v) { } Array(Array &other) : Counted(), values_(other.values_) { } Array(Array *other) : Counted(), values_(other->values_) { } virtual ~Array() { } Array& operator=(const Array &other) { #ifdef DEBUG_COUNTING cout << "assigning values from Array " << &other << " to this Array " << this << ", "; #endif values_ = other.values_; #ifdef DEBUG_COUNTING cout << "new size = " << values_.size() << "\n"; #endif return *this; } Array& operator=(const std::vector &array) { #ifdef DEBUG_COUNTING cout << "assigning values from Array " << &array << " to this Array " << this << ", "; #endif values_ = array; #ifdef DEBUG_COUNTING cout << "new size = " << values_.size() << "\n"; #endif return *this; } T operator[](size_t i) const { return values_[i]; } T& operator[](size_t i) { return values_[i]; } size_t size() const { return values_.size(); } std::vector values() const { return values_; } std::vector& values() { return values_; } }; template class ArrayRef : public Counted { private: public: Array *array_; ArrayRef() : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating empty ArrayRef " << this << "\n"; #endif } ArrayRef(size_t n) : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << "with size " << n << "\n"; #endif reset(new Array (n)); } ArrayRef(T *ts, size_t n) : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << "with " << n << " elements at " << (void *)ts << "\n"; #endif reset(new Array (ts, n)); } ArrayRef(Array *a) : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << " from pointer:\n"; #endif reset(a); } ArrayRef(const Array &a) : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << " from reference to Array " << (void *)&a << ":\n"; #endif reset(const_cast *>(&a)); } ArrayRef(const ArrayRef &other) : Counted(), array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n"; #endif reset(other.array_); } template ArrayRef(const ArrayRef &other) : array_(0) { #ifdef DEBUG_COUNTING cout << "instantiating ArrayRef " << this << " from ArrayRef " << &other << ":\n"; #endif reset(static_cast *>(other.array_)); } ~ArrayRef() { #ifdef DEBUG_COUNTING cout << "destroying ArrayRef " << this << " with " << (array_ ? typeid(*array_).name() : "NULL") << " " << array_ << "\n"; #endif if (array_) { array_->release(); } array_ = 0; } T operator[](size_t i) const { return (*array_)[i]; } T& operator[](size_t i) { return (*array_)[i]; } size_t size() const { return array_->size(); } void reset(Array *a) { #ifdef DEBUG_COUNTING cout << "resetting ArrayRef " << this << " from " << (array_ ? typeid(*array_).name() : "NULL") << " " << array_ << " to " << (a ? typeid(*a).name() : "NULL") << " " << a << "\n"; #endif if (a) { a->retain(); } if (array_) { array_->release(); } array_ = a; } void reset(const ArrayRef &other) { reset(other.array_); } ArrayRef& operator=(const ArrayRef &other) { reset(other); return *this; } ArrayRef& operator=(Array *a) { reset(a); return *this; } Array& operator*() { return *array_; } Array* operator->() { return array_; } }; } // namespace zxing #endif // __ARRAY_H__