Go to the documentation of this file.00001
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();
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
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
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 }
00186 using misc::CArray;
00187 }
00188
00189
00190 #endif
00191
00192
00193
00194