00001 #ifndef SimTK_SimTKCOMMON_LIST_H_
00002 #define SimTK_SimTKCOMMON_LIST_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 #include "SimTKcommon/internal/Array.h"
00037 #include "SimTKcommon/internal/Concretize.h"
00038
00039 #include <complex>
00040 #include <cassert>
00041
00042 namespace SimTK {
00043
00044 template <class T> class List;
00045 template <class T> class ListView;
00046
00047 template <class T> class ListBase : public ArrayBase< Concretize<T> > {
00048 typedef Concretize<T> Element;
00049 typedef ArrayBase<Element> Base;
00050 public:
00051 ListBase() { }
00052 ListBase(int n) : Base(n) {assert(n>=0);}
00053
00054
00055 ListBase(const ListBase& lb) : Base(lb) { }
00056 ~ListBase() { }
00057 ListBase& operator=(const ListBase& lb) {Base::operator=(lb); return *this;}
00058
00059
00060 ListBase(int n, const T& initVal) : Base(n,Element(&initVal)) { }
00061 ListBase(int n, const T* initVal) : Base(n,Element(initVal)) { }
00062 ListBase(int n, const T* const* initVals) : Base(n) {
00063 for (int i=0; i<n; ++i) Base::operator[](i) = *initVals[i];
00064 }
00065
00066
00067 ListBase(int n, T** pp) : Base(n) {
00068 for (int i=0;i<n;++i) Base::operator[](i).replace(&pp[i]);
00069 }
00070
00071
00072
00073 ListBase(const ListBase& l, int offset, int length) : Base(l,offset,length) { }
00074 ListBase(ListBase& l, int offset, int length) : Base(l,offset,length) { }
00075
00076 Element& operator[](int i) {return Base::operator[](i);}
00077 const T& operator[](int i) const {return Base::operator[](i).getRef();}
00078
00079 void push_back(const T& x) {Base::push_back(Element(&x));}
00080 void push_back(T* p) {Base::push_back(Element(p)); }
00081 void push_back(T*& pr) {Base::push_back(Element(pr));}
00082 ListBase& operator+=(const T& x) {push_back(x); }
00083 ListBase& operator+=(T* p) {push_back(p); }
00084 ListBase& operator+=(T*& pr) {push_back(pr);}
00085
00086 bool isEmpty(int i) const {return Base::operator[](i).isEmpty();}
00087 };
00088
00089
00090 template <class T> class ListBase<T*>: public ArrayBase<T*> {
00091 typedef T* Element;
00092 typedef ArrayBase<Element> Base;
00093 public:
00094 ListBase() { }
00095 ListBase(int n) : Base(n) { }
00096 ListBase(int n, Element initVal) : Base(n,initVal) { }
00097 ListBase(int n, const Element* initVals) : Base(n,initVals) { }
00098 ListBase(const ListBase& l, int offset, int length) : Base(l,offset,length) { }
00099 ListBase(ListBase& l, int offset, int length) : Base(l,offset,length) { }
00100
00101
00102 ListBase(const ListBase& lb) : Base(lb) { }
00103 ~ListBase() { }
00104 ListBase& operator=(const ListBase& lb) { Base::operator=(lb); return *this; }
00105
00106
00107
00108 ListBase& operator+=(Element x) { Base::operator+=(x); return *this; }
00109 bool isEmpty(int) const { return false; }
00110 };
00111
00112
00113 #define SimTK_LIST_SPECIALIZE(T) \
00114 template <> class ListBase< T > : public ArrayBase< T > { \
00115 typedef ArrayBase< T > Base; \
00116 public: \
00117 ListBase() { } \
00118 ListBase(int n) : Base(n) { } \
00119 ListBase(int n, const T& initVal) : Base(n,initVal) { } \
00120 ListBase(int n, const T* initVals): Base(n,initVals) { } \
00121 ListBase(const ListBase& l, int offset, int length) : Base(l,offset,length) { } \
00122 ListBase(ListBase& l, int offset, int length) : Base(l,offset,length) { } \
00123 \
00124 ListBase& operator+=(const T& x) { Base::operator+=(x); return *this; } \
00125 bool isEmpty(int) const { return false; } \
00126 };
00127
00128
00129 SimTK_LIST_SPECIALIZE(bool); SimTK_LIST_SPECIALIZE(signed char);
00130 SimTK_LIST_SPECIALIZE(char); SimTK_LIST_SPECIALIZE(unsigned char);
00131 SimTK_LIST_SPECIALIZE(short); SimTK_LIST_SPECIALIZE(int);
00132 SimTK_LIST_SPECIALIZE(long);
00133 SimTK_LIST_SPECIALIZE(unsigned short); SimTK_LIST_SPECIALIZE(unsigned int);
00134 SimTK_LIST_SPECIALIZE(unsigned long);
00135 SimTK_LIST_SPECIALIZE(float); SimTK_LIST_SPECIALIZE(double);
00136 SimTK_LIST_SPECIALIZE(long double);
00137 SimTK_LIST_SPECIALIZE(std::complex<float>);
00138 SimTK_LIST_SPECIALIZE(std::complex<double>);
00139 SimTK_LIST_SPECIALIZE(std::complex<long double>);
00140
00141
00153 template <class T> class ListView : public ListBase<T> {
00154 typedef ListBase<T> Base;
00155 public:
00156
00157 ListView(const ListView& v) : Base(v, 0, v.size()) { }
00158 explicit ListView(const Base& l) : Base(l, 0, l.size()) { }
00159 ~ListView() { }
00160
00161
00162 ListView(const Base& a, int offset, int length) : Base(a,offset,length) { }
00163 ListView(Base& a, int offset, int length) : Base(a,offset,length) { }
00164 ListView operator()(int offset, int length) const {return ListView(*this, offset, length);}
00165 ListView operator()(int offset, int length) {return ListView(*this, offset, length);}
00166
00167
00168 ListView& operator=(const ListView& v) {Base::operator=(v); return *this;}
00169 ListView& operator=(const Base& b) {Base::operator=(b); return *this;}
00170
00171
00172 operator const List<T>&() const {return *reinterpret_cast<const List<T>*>(this);}
00173 operator List<T>&() {return *reinterpret_cast<List<T>*>(this);}
00174 private:
00175
00176 ListView() { assert(false); }
00177 };
00178
00188 template <class T> class List : public ListBase<T> {
00189 typedef ListBase<T> Base;
00190 public:
00191 List() : Base() { }
00192 explicit List(int n) : Base(n) { }
00193 ~List() { }
00194
00195
00196
00197
00198 List(int n, const T& initVal) : Base(n,initVal) { }
00199 List(int n, const T* initVal) : Base(n,initVal) { }
00200 List(int n, const T* const* initVals) : Base(n,initVals) { }
00201
00202
00203
00204 List(int n, T** pp) : Base(n,pp) { }
00205
00206
00207
00208 List(const List& l, int offset, int length) : Base(l,offset,length) { }
00209 List(List& l, int offset, int length) : Base(l,offset,length) { }
00210
00211 const ListView<T> operator()(int offset, int length) const
00212 { return ListView<T>(*this, offset, length); }
00213 ListView<T> operator()(int offset, int length)
00214 { return ListView<T>(*this, offset, length); }
00215
00216 List& operator+=(const T& x) { Base::operator+=(x); return *this; }
00217 List& operator+=(T* p) { Base::operator+=(p); return *this; }
00218 List& operator+=(T*& x) { Base::operator+=(x); return *this; }
00219
00220
00221 operator const ListView<T>&() const
00222 { return *reinterpret_cast<const ListView<T>*>(this); }
00223 operator ListView<T>&()
00224 { return *reinterpret_cast<ListView<T>*>(this); }
00225 private:
00226
00227 };
00228
00232 template <class T> inline int
00233 findFirstOf(const List<T>& l, const T& test) {
00234 for (int i=0; i<l.size(); ++i)
00235 if (l[i] == test) return i;
00236 return -1;
00237 }
00238
00239 template <class T> inline int
00240 findFirstOf(const ListView<T>& lv, const T& test) {
00241 return findFirstOf((const List<T>&)lv, test);
00242 }
00243
00248
00249 template <class T> inline Array<int>
00250 findAllOf(const List<T>& l, const T& test) {
00251 Array<int> matches;
00252 for (int i=0; i<l.size(); ++i)
00253 if (l[i] == test) matches.push_back(i);
00254 return matches;
00255 }
00256
00257 template <class T> inline Array<int>
00258 findAllOf(const ListView<T>& lv, const T& test) {
00259 return findAllOf((const List<T>&)lv, test);
00260 }
00261
00265 template <class T> inline bool
00266 contains(const List<T>& l, const T& test) {
00267 return findFirstOf(l,test) != -1;
00268 }
00269
00270 template <class T> inline bool
00271 contains(const ListView<T>& lv, const T& test) {
00272 return contains((const List<T>&)lv, test);
00273 }
00274
00275 }
00276
00277
00278 #endif // SimTK_SimTKCOMMON_LIST_H_