List.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_LIST_H_
00002 #define SimTK_SimTKCOMMON_LIST_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-6 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
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     // default copy, assignment, destructor made explicit here for convenient debugging
00055     ListBase(const ListBase& lb) : Base(lb) { }
00056     ~ListBase() { }
00057     ListBase& operator=(const ListBase& lb) {Base::operator=(lb); return *this;}
00058     
00059     // These make copies of the supplied objects    
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     // This steals all the space and zeroes out the passed-in array of pointers.        
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     // Sub-ListBase constructors, read only and writable.
00072     // These share space with the original ListBase.
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));} // copies x
00080     void push_back(T* p)         {Base::push_back(Element(p)); } // steals p
00081     void push_back(T*& pr)       {Base::push_back(Element(pr));} // steals p and clears it
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 // Partial specialization for pointers -- these are just Arrays of pointers
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     // default copy, assignment, destructor made explicit here for convenient debugging
00102     ListBase(const ListBase& lb) : Base(lb) { }
00103     ~ListBase() { }
00104     ListBase& operator=(const ListBase& lb) { Base::operator=(lb); return *this; }
00105  
00106     // inherit most operators and methods from Base   
00107     
00108     ListBase& operator+=(Element x) { Base::operator+=(x); return *this; }
00109     bool isEmpty(int) const { return false; }
00110 };
00111 
00112 // ListBase template specializations for known concrete objects
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     /* default copy, assignment, destructor; inherit most operators & methods */            \
00124     ListBase& operator+=(const T& x) { Base::operator+=(x); return *this; } \
00125     bool isEmpty(int) const { return false; }                            \
00126 };
00127 
00128 // Built-in types
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     // no default constructor
00157     ListView(const ListView& v) : Base(v, 0, v.size()) { } // an identical view
00158     explicit ListView(const Base& l) : Base(l, 0, l.size()) { }  // a view of the whole thing
00159     ~ListView() { } // convenient for debugging
00160        
00161     // Sub-array constructors, read only and writable, and their operator equivalents
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     // Shallow assignment only (ListBase understands)
00168     ListView& operator=(const ListView& v) {Base::operator=(v); return *this;}
00169     ListView& operator=(const Base&     b) {Base::operator=(b); return *this;}
00170     
00171     // Conversions
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     // NO DATA MEMBERS ALLOWED
00176     ListView() { assert(false); } // default construction not allowed
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() { } // convenient for debugging
00194     
00195     // default copy, assignment, destructor (these will be "deep" copies)
00196     
00197     // These allocate new space and fill it with copies of the supplied objects    
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     // This allocates a new List but steals the initializing objects rather
00203     // than copying them. For safety it zeroes out the passed-in array of pointers.        
00204     List(int n, T** pp) : Base(n,pp) { }
00205     
00206     // Sub-list constructors, read only and writable, and their operator equivalents.
00207     // These share space with the original List.
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     // Conversions
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     // NO DATA MEMBERS ALLOWED
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 } // namespace SimTK
00276 
00277 
00278 #endif // SimTK_SimTKCOMMON_LIST_H_

Generated on Thu Feb 28 01:34:29 2008 for SimTKcommon by  doxygen 1.4.7