00001
00002
00003 #ifndef _CARRAY_H
00004 #define _CARRAY_H
00005 #include "osl/player.h"
00006 #include "osl/config.h"
00007 #include <cstddef>
00008 #include <cassert>
00009 #include <algorithm>
00010 #include <iterator>
00011 #include <boost/type_traits.hpp>
00012
00013 #define CONSERVATIVE_PLAYER_ACCESS
00014
00015 namespace osl
00016 {
00017 namespace misc
00018 {
00025 template <typename T>
00026 struct CArrayIterator
00027 {
00028 typedef std::random_access_iterator_tag iterator_category;
00029 typedef T value_type;
00030 typedef int difference_type;
00031 typedef T* pointer;
00032 typedef T& reference;
00033
00034 T *ptr;
00035 CArrayIterator(T *p) : ptr(p) {}
00036 CArrayIterator(const CArrayIterator<typename boost::remove_cv<T>::type>& src) : ptr(src.ptr)
00037 {
00038 }
00039 T& operator*() const { return *ptr; }
00040 T* operator->() const { return ptr; }
00041 CArrayIterator& operator+=(int diff)
00042 {
00043 ptr += diff;
00044 return *this;
00045 }
00046 CArrayIterator& operator-=(int diff) { return operator+=(-diff); }
00047 CArrayIterator& operator++() { return operator+=(1); }
00048 CArrayIterator operator++(int)
00049 {
00050 const CArrayIterator result = *this;
00051 operator++();
00052 return result;
00053 }
00054 CArrayIterator& operator--() { return operator+=(-1); }
00055 CArrayIterator operator--(int)
00056 {
00057 const CArrayIterator result = *this;
00058 operator--();
00059 return result;
00060 }
00061 private:
00062 #ifndef _MSC_VER
00063 operator bool();
00064 #endif
00065 };
00066 template <class T> inline
00067 const CArrayIterator<T> operator+(const CArrayIterator<T>& iter, int diff)
00068 {
00069 CArrayIterator<T> result(iter);
00070 result += diff;
00071 return result;
00072 }
00073 template <class T> inline
00074 const CArrayIterator<T> operator-(const CArrayIterator<T>& iter, int diff) {
00075 return iter + (-diff);
00076 }
00077
00078 template <class T, class T2>
00079 inline int operator-(CArrayIterator<T> l, CArrayIterator<T2> r)
00080 {
00081 return l.ptr - r.ptr;
00082 }
00083 template <class T, class T2>
00084 inline bool operator==(CArrayIterator<T> l, CArrayIterator<T2> r)
00085 {
00086 return l.ptr == r.ptr;
00087 }
00088 template <class T, class T2>
00089 inline bool operator!=(CArrayIterator<T> l, CArrayIterator<T2> r)
00090 {
00091 return l.ptr != r.ptr;
00092 }
00093 template <class T, class T2>
00094 inline bool operator<(CArrayIterator<T> l, CArrayIterator<T2> r)
00095 {
00096 return l.ptr < r.ptr;
00097 }
00098 template <class T, class T2>
00099 inline bool operator>(CArrayIterator<T> l, CArrayIterator<T2> r)
00100 {
00101 return l.ptr > r.ptr;
00102 }
00103
00107 template <typename T, size_t Capacity>
00108 class CArray
00109 {
00110 public:
00112 T elements[Capacity];
00113 typedef typename boost::remove_cv<T>::type T_simple;
00114 public:
00115 typedef T value_type;
00116 typedef CArrayIterator<T> iterator;
00117 iterator begin() { return &elements[0]; }
00118 iterator end() { return &elements[Capacity]; }
00119
00120 void fill(T_simple value=T_simple())
00121 {
00122 std::fill(begin(), end(), value);
00123 }
00124 T& operator[] (size_t i)
00125 {
00126 assert(i < Capacity);
00127 return elements[i];
00128 }
00129
00130 static size_t size() { return Capacity; }
00131
00132 T const& operator[] (size_t i) const
00133 {
00134 assert(i < Capacity);
00135 return elements[i];
00136 }
00137
00138 typedef CArrayIterator<const T> const_iterator;
00139 const_iterator begin() const { return &elements[0]; }
00140 const_iterator end() const { return &elements[Capacity]; }
00141
00142 bool operator==(const CArray& other) const
00143 {
00144 return std::equal(begin(), end(), other.begin());
00145 }
00146
00147 T& operator[] (Player p)
00148 {
00149 #ifndef CONSERVATIVE_PLAYER_ACCESS
00150
00151 assert(1 < Capacity);
00152 return *((T*)((char *)&elements[0] +
00153 (p & ((char *)&elements[1]-(char *)&elements[0]))));
00154 #else
00155 return operator[](playerToIndex(p));
00156 #endif
00157 }
00158 const T& operator[] (Player p) const
00159 {
00160 #ifndef CONSERVATIVE_PLAYER_ACCESS
00161 assert(1 < Capacity);
00162 return *((T*)((char *)&elements[0] +
00163 (p & ((char *)&elements[1]-(char *)&elements[0]))));
00164 #else
00165 return operator[](playerToIndex(p));
00166 #endif
00167 }
00168 };
00169 }
00170 using misc::CArray;
00171 }
00172
00173
00174 #endif
00175
00176
00177
00178