ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_STORAGE_STATIC_ARRAY_HPP 00002 #define VIENNAGRID_STORAGE_STATIC_ARRAY_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 #include <cassert> 00017 #include <cstddef> 00018 #include <iterator> 00019 00024 namespace viennagrid 00025 { 00027 template<typename T, int N> 00028 class static_array 00029 { 00030 T elements_[N]; // fixed-size array of elements of type T 00031 00032 public: 00033 // type definitions 00034 typedef T value_type; 00035 typedef T* pointer; 00036 typedef const T* const_pointer; 00037 00038 typedef T& reference; 00039 typedef const T& const_reference; 00040 typedef std::size_t size_type; 00041 typedef std::ptrdiff_t difference_type; 00042 00043 class const_iterator; 00044 00045 static_array() 00046 { 00047 for (std::size_t i=0; i<static_cast<size_t>(N); ++i) 00048 elements_[i] = T(); 00049 } 00050 00051 // random access iterator: http://www.cplusplus.com/reference/std/iterator/RandomAccessIterator/ 00052 class iterator 00053 { 00054 friend class const_iterator; 00055 public: 00056 00057 typedef std::size_t difference_type; 00058 typedef typename static_array::value_type value_type; 00059 typedef typename static_array::pointer pointer; 00060 typedef typename static_array::reference reference; 00061 typedef typename static_array::const_reference const_reference; 00062 typedef std::random_access_iterator_tag iterator_category; 00063 00064 // default-constructable 00065 iterator() : ptr_(0) {} 00066 00067 // copy- and copy-constructable 00068 iterator(const iterator & it) : ptr_(it.ptr_) {} 00069 iterator & operator=(const iterator & it) { ptr_ = it.ptr_; return *this; } 00070 00071 // constructor for static_array 00072 iterator(pointer ptr) : ptr_(ptr) {} 00073 00074 // equal and inequal compareable 00075 bool operator==(const iterator& i) const { return ptr_ == i.ptr_; } 00076 bool operator!=(const iterator& i) const { return ptr_ != i.ptr_; } 00077 00078 bool operator==(const const_iterator & it) const; 00079 bool operator!=(const const_iterator & it) const; 00080 00081 // dereferenceable 00082 reference operator*() const { return *ptr_; } 00083 pointer operator->() const { return ptr_; } 00084 00085 // increment- and decrementable 00086 iterator & operator++() { ++ptr_; return *this; } 00087 iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } 00088 00089 iterator & operator--() { --ptr_; return *this; } 00090 iterator operator--(int) { iterator tmp = *this; --*this; return tmp; } 00091 00092 // add and subtractable; operator+ and operator- is below 00093 difference_type operator-(const iterator & it) const { return ptr_ - it.ptr_; } 00094 difference_type operator-(const const_iterator & it) const { return ptr_ - it.ptr_; } 00095 00096 // less and greater compareable 00097 bool operator<(const iterator & it) const { return ptr_ < it.ptr; } 00098 bool operator<=(const iterator & it) const { return ptr_ <= it.ptr; } 00099 00100 bool operator>(const iterator & it) const { return ptr_ > it.ptr; } 00101 bool operator>=(const iterator & it) const { return ptr_ >= it.ptr; } 00102 00103 bool operator<(const const_iterator & it) const { return ptr_ < it.ptr; } 00104 bool operator<=(const const_iterator & it) const { return ptr_ <= it.ptr; } 00105 00106 bool operator>(const const_iterator & it) const { return ptr_ > it.ptr; } 00107 bool operator>=(const const_iterator & it) const { return ptr_ >= it.ptr; } 00108 00109 // compound assign add- and subtractable 00110 iterator & operator+=(long diff) { ptr_ += diff; return *this; } 00111 iterator & operator-=(long diff) { ptr_ -= diff; return *this; } 00112 00113 iterator operator+(long diff) { iterator tmp(*this); tmp += diff; return tmp; } 00114 iterator operator-(long diff) { iterator tmp(*this); tmp -= diff; return tmp; } 00115 00116 // offset dereferenceable 00117 reference operator[](std::size_t offset) { return *(ptr_+offset); } 00118 const_reference operator[](std::size_t offset) const { return *(ptr_+offset); } 00119 00120 private: 00121 pointer ptr_; 00122 }; 00123 00124 class const_iterator 00125 { 00126 friend class iterator; 00127 public: 00128 00129 typedef std::size_t difference_type; 00130 typedef typename static_array::value_type value_type; 00131 typedef typename static_array::const_pointer pointer; 00132 typedef typename static_array::const_reference reference; 00133 typedef std::random_access_iterator_tag iterator_category; 00134 00135 00136 // default-constructable 00137 const_iterator() : ptr_(0) {} 00138 00139 // copy- and copy-constructable 00140 const_iterator(const const_iterator & it) : ptr_(it.ptr_) {} 00141 const_iterator(iterator it) : ptr_(it.ptr_) {} 00142 const_iterator & operator=(const iterator & it) { ptr_ = it.ptr_; return *this; } 00143 const_iterator & operator=(const const_iterator & it) { ptr_ = it.ptr_; return *this; } 00144 00145 // constructor for static_array 00146 const_iterator(const_pointer ptr) : ptr_(ptr) {} 00147 00148 // equal and inequal compareable 00149 bool operator==(const const_iterator& i) const { return ptr_ == i.ptr_; } 00150 bool operator!=(const const_iterator& i) const { return ptr_ != i.ptr_; } 00151 00152 bool operator==(const iterator & i) const { return ptr_ == i.ptr_; } 00153 bool operator!=(const iterator & i) const { return ptr_ != i.ptr_; } 00154 00155 // dereferenceable 00156 reference operator*() const { return *ptr_; } 00157 pointer operator->() const { return ptr_; } 00158 00159 00160 // increment- and decrementable 00161 const_iterator & operator++() { ++ptr_; return *this; } 00162 const_iterator operator++(int) { const_iterator tmp = *this; ++*this; return tmp; } 00163 00164 const_iterator & operator--() { --ptr_; return *this; } 00165 const_iterator operator--(int) { const_iterator tmp = *this; --*this; return tmp; } 00166 00167 // add and subtractable; operator+ and operator- is below 00168 difference_type operator-(const iterator & it) const { return ptr_ - it.ptr_; } 00169 difference_type operator-(const const_iterator & it) const { return ptr_ - it.ptr_; } 00170 00171 // less and greater compareable 00172 bool operator<(const iterator & it) const { return ptr_ < it.ptr; } 00173 bool operator<=(const iterator & it) const { return ptr_ <= it.ptr; } 00174 00175 bool operator>(const iterator & it) const { return ptr_ > it.ptr; } 00176 bool operator>=(const iterator & it) const { return ptr_ >= it.ptr; } 00177 00178 bool operator<(const const_iterator & it) const { return ptr_ < it.ptr; } 00179 bool operator<=(const const_iterator & it) const { return ptr_ <= it.ptr; } 00180 00181 bool operator>(const const_iterator & it) const { return ptr_ > it.ptr; } 00182 bool operator>=(const const_iterator & it) const { return ptr_ >= it.ptr; } 00183 00184 // compound assign add- and subtractable 00185 const_iterator & operator+=(long diff) { ptr_ += diff; return *this; } 00186 const_iterator & operator-=(long diff) { ptr_ -= diff; return *this; } 00187 00188 const_iterator operator+(long diff) { const_iterator tmp(*this); tmp += diff; return tmp; } 00189 const_iterator operator-(long diff) { const_iterator tmp(*this); tmp -= diff; return tmp; } 00190 00191 // offset dereferenceable 00192 reference operator[](std::size_t offset) { return *(ptr_+offset); } 00193 00194 private: 00195 pointer ptr_; 00196 }; 00197 00198 // iterator support 00199 iterator begin() { return iterator(elements_); } 00200 const_iterator begin() const { return const_iterator(elements_); } 00201 const_iterator cbegin() const { return const_iterator(elements_); } 00202 00203 iterator end() { return iterator(elements_+N); } 00204 const_iterator end() const { return const_iterator(elements_+N); } 00205 const_iterator cend() const { return const_iterator(elements_+N); } 00206 00207 // reverse iterator support 00208 typedef std::reverse_iterator<iterator> reverse_iterator; 00209 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00210 00211 reverse_iterator rbegin() { return reverse_iterator(end()); } 00212 const_reverse_iterator rbegin() const { 00213 return const_reverse_iterator(end()); 00214 } 00215 const_reverse_iterator crbegin() const { 00216 return const_reverse_iterator(end()); 00217 } 00218 00219 reverse_iterator rend() { return reverse_iterator(begin()); } 00220 const_reverse_iterator rend() const { 00221 return const_reverse_iterator(begin()); 00222 } 00223 const_reverse_iterator crend() const { 00224 return const_reverse_iterator(begin()); 00225 } 00226 00227 // operator[] 00228 reference operator[](size_type i) 00229 { 00230 assert( i < N && "out of range" ); 00231 return elements_[i]; 00232 } 00233 00234 const_reference operator[](size_type i) const 00235 { 00236 assert( i < N && "out of range" ); 00237 return elements_[i]; 00238 } 00239 00240 // at() with range check 00241 reference at(size_type i) { assert( i < N && "out of range" ); return elements_[i]; } 00242 const_reference at(size_type i) const { assert( i < N && "out of range" ); return elements_[i]; } 00243 00244 // front() and back() 00245 reference front() 00246 { 00247 return elements_[0]; 00248 } 00249 00250 const_reference front() const 00251 { 00252 return elements_[0]; 00253 } 00254 00255 reference back() 00256 { 00257 return elements_[N-1]; 00258 } 00259 00260 const_reference back() const 00261 { 00262 return elements_[N-1]; 00263 } 00264 00265 // size is constant 00266 static size_type size() { return N; } 00267 static void resize(size_type s) { assert( s <= N ); (void)s; } 00268 00269 static bool empty() { return false; } 00270 static size_type max_size() { return N; } 00271 static const int static_size = N; 00272 00273 // swap (note: linear complexity) 00274 void swap (static_array<T,N>& y) { 00275 for (size_type i = 0; i < N; ++i) 00276 std::swap(elements_[i],y.elements_[i]); 00277 } 00278 00279 // direct access to data (read-only) 00280 const T* data() const { return elements_; } 00281 T* data() { return elements_; } 00282 00283 // use static_array as C array (direct read/write access to data) 00284 T* c_array() { return elements_; } 00285 00286 // assignment with type conversion 00287 template <typename T2> 00288 static_array<T,N>& operator= (const static_array<T2,N>& rhs) { 00289 std::copy(rhs.begin(),rhs.end(), begin()); 00290 return *this; 00291 } 00292 00293 // assign one value to all elements 00294 void assign (const T& value) { fill ( value ); } // A synonym for fill 00295 void fill (const T& value) 00296 { 00297 std::fill_n(begin(),size(),value); 00298 } 00299 00300 }; 00301 00302 // comparisons 00303 template<class T, std::size_t N> 00304 bool operator== (const static_array<T,N>& x, const static_array<T,N>& y) { 00305 return std::equal(x.begin(), x.end(), y.begin()); 00306 } 00307 template<class T, std::size_t N> 00308 bool operator< (const static_array<T,N>& x, const static_array<T,N>& y) { 00309 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); 00310 } 00311 template<class T, std::size_t N> 00312 bool operator!= (const static_array<T,N>& x, const static_array<T,N>& y) { 00313 return !(x==y); 00314 } 00315 template<class T, std::size_t N> 00316 bool operator> (const static_array<T,N>& x, const static_array<T,N>& y) { 00317 return y<x; 00318 } 00319 template<class T, std::size_t N> 00320 bool operator<= (const static_array<T,N>& x, const static_array<T,N>& y) { 00321 return !(y<x); 00322 } 00323 template<class T, std::size_t N> 00324 bool operator>= (const static_array<T,N>& x, const static_array<T,N>& y) { 00325 return !(x<y); 00326 } 00327 00328 // global swap() 00330 template<class T, std::size_t N> 00331 inline void swap (static_array<T,N>& x, static_array<T,N>& y) { 00332 x.swap(y); 00333 } 00334 00335 } 00336 00337 #endif