carray.h
Go to the documentation of this file.
00001 /* carray.h
00002  */
00003 #ifndef OSL_CARRAY_H
00004 #define OSL_CARRAY_H
00005 #include "osl/player.h"
00006 #include "osl/ptype.h"
00007 #include "osl/config.h"
00008 #include <cstddef>
00009 #include <cassert>
00010 #include <algorithm>
00011 #include <iterator>
00012 #include <boost/type_traits.hpp>
00013 
00014 #define CONSERVATIVE_PLAYER_ACCESS
00015 
00016 namespace osl
00017 {
00018   namespace misc
00019   {
00026   template <typename T>
00027   struct CArrayIterator
00028   {
00029     typedef std::random_access_iterator_tag iterator_category;
00030     typedef T   value_type;
00031     typedef int difference_type;
00032     typedef T*  pointer;
00033     typedef T&  reference;
00034 
00035     T *ptr;
00036     CArrayIterator(T *p) : ptr(p) {}
00037     CArrayIterator(const CArrayIterator<typename boost::remove_cv<T>::type>& src) : ptr(src.ptr)
00038     {
00039     }
00040     T& operator*() const { return *ptr; }
00041     T* operator->() const { return ptr; }
00042     CArrayIterator& operator+=(int diff)
00043     {
00044       ptr += diff;
00045       return *this;
00046     }
00047     CArrayIterator& operator-=(int diff) { return operator+=(-diff); }
00048     CArrayIterator& operator++() { return operator+=(1); }
00049     CArrayIterator operator++(int)
00050     {
00051       const CArrayIterator result = *this;
00052       operator++();
00053       return result;
00054     }
00055     CArrayIterator& operator--() { return operator+=(-1); }
00056     CArrayIterator operator--(int)
00057     {
00058       const CArrayIterator result = *this;
00059       operator--();
00060       return result;
00061     }
00062   private:
00063 #ifndef _MSC_VER
00064     operator bool();            // not implemented
00065 #endif
00066   };
00067   template <class T> inline
00068   const CArrayIterator<T> operator+(const CArrayIterator<T>& iter, int diff) 
00069   {
00070     CArrayIterator<T> result(iter);
00071     result += diff;
00072     return result;
00073   }
00074   template <class T> inline
00075   const CArrayIterator<T> operator-(const CArrayIterator<T>& iter, int diff) { 
00076     return iter + (-diff); 
00077   }
00078   // T と const T の違いを吸収,それ以外はcompile error になるはず
00079   template <class T, class T2>
00080   inline int operator-(CArrayIterator<T> l, CArrayIterator<T2> r)
00081   {
00082     return l.ptr - r.ptr;
00083   }
00084   template <class T, class T2>
00085   inline bool operator==(CArrayIterator<T> l, CArrayIterator<T2> r)
00086   {
00087     return l.ptr == r.ptr;
00088   }
00089   template <class T, class T2>
00090   inline bool operator!=(CArrayIterator<T> l, CArrayIterator<T2> r)
00091   {
00092     return l.ptr != r.ptr;
00093   }
00094   template <class T, class T2>
00095   inline bool operator<(CArrayIterator<T> l, CArrayIterator<T2> r)
00096   {
00097     return l.ptr < r.ptr;
00098   }
00099   template <class T, class T2>
00100   inline bool operator>(CArrayIterator<T> l, CArrayIterator<T2> r)
00101   {
00102     return l.ptr > r.ptr;
00103   }
00104 
00108   template <typename T, size_t Capacity>
00109   class CArray
00110   {
00111   public:
00113     T elements[Capacity];
00114     typedef typename boost::remove_cv<T>::type T_simple;
00115   public:
00116     typedef T value_type;
00117     typedef CArrayIterator<T> iterator;
00118     iterator begin() { return &elements[0]; }
00119     iterator end() { return &elements[Capacity]; }
00120 
00121     void fill(T_simple value=T_simple())
00122     {
00123       std::fill(begin(), end(), value);
00124     }
00125     T& operator[] (size_t i) 
00126     {
00127       assert(i < Capacity);
00128       return elements[i];
00129     }
00130 
00131     static size_t size() { return Capacity; }
00132     
00133     T const& operator[] (size_t i) const
00134     {
00135       assert(i < Capacity);
00136       return elements[i];
00137     }
00138 
00139     typedef CArrayIterator<const T> const_iterator;
00140     const_iterator begin() const { return &elements[0]; }
00141     const_iterator end()   const { return &elements[Capacity]; }
00142 
00143     bool operator==(const CArray& other) const
00144     {
00145       return std::equal(begin(), end(), other.begin());
00146     }
00147 
00148     T& operator[] (Player p) 
00149     {
00150       assert(1 < Capacity);
00151 #ifndef CONSERVATIVE_PLAYER_ACCESS
00152       // equivalent to operator[](playerToIndex(p))
00153       return *((T*)((char *)&elements[0] + 
00154                     (p & ((char *)&elements[1]-(char *)&elements[0]))));
00155 #else
00156       return operator[](playerToIndex(p));
00157 #endif
00158     }
00159     const T& operator[] (Player p) const
00160     {
00161       assert(1 < Capacity);
00162 #ifndef CONSERVATIVE_PLAYER_ACCESS
00163       return *((T*)((char *)&elements[0] + 
00164                     (p & ((char *)&elements[1]-(char *)&elements[0]))));
00165 #else
00166       return operator[](playerToIndex(p));
00167 #endif
00168     }
00169     T& operator[] (PtypeO ptypeo) 
00170     {
00171       assert(PTYPEO_SIZE <= (int)Capacity);
00172       return operator[](ptypeOIndex(ptypeo));
00173     }
00174     const T& operator[] (PtypeO ptypeo) const
00175     {
00176       assert(PTYPEO_SIZE <= (int)Capacity);
00177       return operator[](ptypeOIndex(ptypeo));
00178     }
00179     
00180     T& front() { return *begin(); }
00181     T& back() { return *(end() - 1); }
00182     const T& front() const { return *begin(); }
00183     const T& back() const { return *(end() - 1); }
00184   };
00185   } // namespace misc
00186   using misc::CArray;
00187 } // namespace osl
00188 
00189 
00190 #endif /* _FIXED_CAPACITY_VECTOR_H */
00191 // ;;; Local Variables:
00192 // ;;; mode:c++
00193 // ;;; c-basic-offset:2
00194 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines