00001 #ifndef SimTK_SimTKCOMMON_ARRAY_H_
00002 #define SimTK_SimTKCOMMON_ARRAY_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "SimTKcommon/internal/common.h"
00036
00037 #include <cstddef>
00038 #include <cassert>
00039 #include <ostream>
00040
00041
00042 namespace SimTKimpl {
00043
00044 class ArrayHelperImpl;
00045
00050 class SimTK_SimTKCOMMON_EXPORT ArrayHelper {
00051 public:
00052
00053 explicit ArrayHelper(const TypeManipulatorT&, int n=0);
00054 ArrayHelper(const TypeManipulatorT&, int n, const void* ival, bool repeat);
00055 ArrayHelper(const ArrayHelper&);
00056
00057
00058 ArrayHelper(const ArrayHelper&, int offset, int length);
00059 ArrayHelper(ArrayHelper&, int offset, int length);
00060
00061 ~ArrayHelper();
00062 ArrayHelper& operator=(const ArrayHelper&);
00063
00064 void reverse();
00065
00066
00067 int capacity() const;
00068 int size() const;
00069
00070 const void* operator[](int i) const;
00071 void* operator[](int i);
00072
00073 void push_back(const void*);
00074 void pop_back();
00075 void clear();
00076 void resize(int n, const void* x=0);
00077 void reserve(int n);
00078
00079 private:
00080 ArrayHelperImpl* impl;
00081
00082 ArrayHelperImpl& updImpl() {assert(impl); return *impl;}
00083 const ArrayHelperImpl& getImpl() const {assert(impl); return *impl;}
00084 };
00085
00086 }
00087
00088 namespace SimTK {
00089 template <class T> class Array;
00090 template <class T> class ArrayView;
00091
00092 template <class T> class ArrayBase {
00093 public:
00094 ArrayBase() : ah(type()) { }
00095 explicit ArrayBase(int n) : ah(type(),n) { }
00096 ArrayBase(int n, const T& ival) : ah(type(),n,&ival,true) { }
00097 ArrayBase(int n, const T* ivals) : ah(type(),n,ivals,false) { }
00098
00099
00100 ArrayBase(const ArrayBase& a, int offset, int length) : ah(a.ah,offset,length) { }
00101 ArrayBase(ArrayBase& a, int offset, int length) : ah(a.ah,offset,length) { }
00102
00103
00104
00105 ArrayBase(const ArrayBase& src) : ah(src.ah) { }
00106 ~ArrayBase() { }
00107 ArrayBase& operator=(const ArrayBase& src) {
00108 if (this != &src)
00109 ah = src.ah;
00110 return *this;
00111 }
00112
00113
00114 ArrayBase& operator=(const T& x) {
00115 for (int i=0; i < size(); ++i)
00116 (*this)[i] = x;
00117 return *this;
00118 }
00119
00120 typedef T* iterator;
00121 typedef const T* const_iterator;
00122 typedef T& reference;
00123 typedef const T& const_reference;
00124
00125 reference front() {assert(size()); return (*this)[0];}
00126 const_reference front() const {assert(size()); return (*this)[0];}
00127 reference back() {assert(size()); return (*this)[size()-1];}
00128 const_reference back() const {assert(size()); return (*this)[size()-1];}
00129
00130
00131
00132 iterator begin() {return size() ? &front() : 0;}
00133 const_iterator begin() const {return size() ? &front() : 0;}
00134 iterator end() {return size() ? &back() + 1 : 0;}
00135 const_iterator end() const {return size() ? &back() + 1 : 0;}
00136
00137 void reverse() {ah.reverse();}
00138
00139 int capacity() const { return ah.capacity(); }
00140 int size() const { return ah.size(); }
00141
00142 const T& operator[](int i) const {return getAs(ah[i]);}
00143 T& operator[](int i) {return updAs(ah[i]);}
00144
00145
00146 ArrayBase& operator+=(const T& x) { push_back(x); return *this; }
00147
00148 void push_back(const T& x) {ah.push_back(&x);}
00149 void pop_back() {ah.pop_back();}
00150 void clear() {ah.clear();}
00151 void resize(int n) {ah.resize(n);}
00152 void resize(int n, const T& x) {ah.resize(n,&x);}
00153 void reserve(int n) {ah.reserve(n);}
00154
00155 private:
00156 SimTKimpl::ArrayHelper ah;
00157
00158 static const SimTKimpl::TypeManipulatorT& type() {
00159 return SimTKimpl::MakeTypeManipulator<T>::getTypeManipulatorT();
00160 }
00161 static const T& getAs(const void* p) {return SimTKimpl::MakeTypeManipulator<T>::getAs(p);}
00162 static T& updAs(void* p) {return SimTKimpl::MakeTypeManipulator<T>::updAs(p);}
00163 };
00164
00181 template <class T> class ArrayView : public ArrayBase<T> {
00182 typedef ArrayBase<T> Base;
00183 public:
00184
00185 ArrayView(const ArrayView& v) : Base(v, 0, v.size()) { }
00186 explicit ArrayView(const Base& l) : Base(l, 0, l.size()) { }
00187 ~ArrayView() { }
00188
00189
00190 ArrayView(const ArrayView& a, int offset, int length) : Base(a,offset,length) { }
00191 ArrayView(ArrayView& a, int offset, int length) : Base(a,offset,length) { }
00192 ArrayView operator()(int offset, int length) const { return ArrayView(*this, offset, length); }
00193 ArrayView operator()(int offset, int length) { return ArrayView(*this, offset, length); }
00194
00195
00196 ArrayView& operator=(const ArrayView& v) { Base::operator=(v); return *this; }
00197 ArrayView& operator=(const Base& b) { Base::operator=(b); return *this; }
00198
00199
00200 operator const Array<T>&() const { return *reinterpret_cast<const Array<T>*>(this); }
00201 operator Array<T>&() { return *reinterpret_cast<Array<T>*>(this); }
00202 private:
00203
00204 ArrayView() { assert(false); }
00205 };
00206
00215 template <class T> class Array : public ArrayBase<T> {
00216 typedef ArrayBase<T> Base;
00217 public:
00218 Array() : Base() { }
00219 explicit Array(int n) : Base(n) { }
00220
00221
00222
00223 Array(const Array& src) : Base(src) { }
00224 ~Array() { }
00225 Array& operator=(const Array& src) {Base::operator=(src); return *this;}
00226
00227 Array& operator=(const T& x) {Base::operator=(x); return *this;}
00228
00229
00230 Array(int n, const T& ival) : Base(n,ival) { }
00231 Array(int n, const T* ivals) : Base(n,ivals) { }
00232
00233
00234 Array(const Array& a, int offset, int length) : Base(a,offset,length) { }
00235 Array(Array& a, int offset, int length) : Base(a,offset,length) { }
00236
00237 const ArrayView<T> operator()(int offset, int length) const
00238 { return ArrayView<T>(*this, offset, length); }
00239 ArrayView<T> operator()(int offset, int length)
00240 { return ArrayView<T>(*this, offset, length); }
00241
00242
00243 Array& operator+=(const T& x) { Base::operator+=(x); return *this; }
00244
00245
00246 operator const ArrayView<T>&() const
00247 { return *reinterpret_cast<const ArrayView<T>*>(this); }
00248 operator ArrayView<T>&()
00249 { return *reinterpret_cast<ArrayView<T>*>(this); }
00250 private:
00251
00252 };
00253
00257 template <class T> inline int
00258 findFirstOf(const Array<T>& a, const T& test) {
00259 for (int i=0; i<a.size(); ++i)
00260 if (a[i] == test) return i;
00261 return -1;
00262 }
00263 template <class T> inline int
00264 findFirstOf(const ArrayView<T>& a, const T& test)
00265 { return findFirstOf((const Array<T>&)a,test); }
00266
00271
00272 template <class T> inline Array<int>
00273 findAllOf(const Array<T>& a, const T& test) {
00274 Array<int> matches;
00275 for (int i=0; i<a.size(); ++i)
00276 if (a[i] == test) matches.push_back(i);
00277 return matches;
00278 }
00279
00280 template <class T> inline Array<int>
00281 findAllOf(const ArrayView<T>& a, const T& test) {
00282 return findAllOf((const Array<T>&)a,test);
00283 }
00284
00288 template <class T> inline bool
00289 contains(const Array<T>& a, const T& test) {
00290 return findFirstOf(a,test) != -1;
00291 }
00292 template <class T> inline bool
00293 contains(const ArrayView<T>& a, const T& test) {
00294 return findFirstOf(a,test) != -1;
00295 }
00296
00297 template <class T> inline std::ostream&
00298 operator<<(std::ostream& s, const Array<T>& a) {
00299 for (int i=0; i<a.size(); ++i)
00300 s << a[i] << std::endl;
00301 return s;
00302 }
00303 template <class T> inline std::ostream&
00304 operator<<(std::ostream& s, const ArrayView<T>& a) {
00305 return s << (const Array<T>&)a;
00306 }
00307
00308 }
00309
00310 #endif // SimTK_SimTKCOMMON_ARRAY_H_