1 /* The following code declares class array, 2 * an STL container (as wrapper) for arrays of constant size. 3 * 4 * See 5 * http://www.josuttis.com/cppcode 6 * for details and the latest version. 7 * See 8 * http://www.boost.org/libs/array for Documentation. 9 * for documentation. 10 * 11 * (C) Copyright Nicolai M. Josuttis 2001. 12 * Distributed under the Boost Software License, Version 1.0. (See 13 * accompanying file LICENSE_1_0.txt or copy at 14 * http://www.boost.org/LICENSE_1_0.txt) 15 * 16 * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) 17 * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. 18 * 05 Aug 2001 - minor update (Nico Josuttis) 19 * 20 Jan 2001 - STLport fix (Beman Dawes) 20 * 29 Sep 2000 - Initial Revision (Nico Josuttis) 21 * 22 * Jan 29, 2004 23 */ 24 #ifndef BOOST_ARRAY_HPP 25 #define BOOST_ARRAY_HPP 26 27 #include <cstddef> 28 #include <stdexcept> 29 #include <boost/assert.hpp> 30 31 // Handles broken standard libraries better than <iterator> 32 #include <boost/detail/iterator.hpp> 33 #include <algorithm> 34 35 // FIXES for broken compilers 36 #include <boost/config.hpp> 37 38 39 namespace boost { 40 41 template<class T, std::size_t N> 42 class array { 43 public: 44 T elems[N]; // fixed-size array of elements of type T 45 46 public: 47 // type definitions 48 typedef T value_type; 49 typedef T* iterator; 50 typedef const T* const_iterator; 51 typedef T& reference; 52 typedef const T& const_reference; 53 typedef std::size_t size_type; 54 typedef std::ptrdiff_t difference_type; 55 56 // iterator support begin()57 iterator begin() { return elems; } begin() const58 const_iterator begin() const { return elems; } end()59 iterator end() { return elems+N; } end() const60 const_iterator end() const { return elems+N; } 61 62 // reverse iterator support 63 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) 64 typedef std::reverse_iterator<iterator> reverse_iterator; 65 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 66 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) 67 // workaround for broken reverse_iterator in VC7 68 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator, 69 reference, iterator, reference> > reverse_iterator; 70 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator, 71 const_reference, iterator, reference> > const_reverse_iterator; 72 #else 73 // workaround for broken reverse_iterator implementations 74 typedef std::reverse_iterator<iterator,T> reverse_iterator; 75 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator; 76 #endif 77 rbegin()78 reverse_iterator rbegin() { return reverse_iterator(end()); } rbegin() const79 const_reverse_iterator rbegin() const { 80 return const_reverse_iterator(end()); 81 } rend()82 reverse_iterator rend() { return reverse_iterator(begin()); } rend() const83 const_reverse_iterator rend() const { 84 return const_reverse_iterator(begin()); 85 } 86 87 // operator[] operator [](size_type i)88 reference operator[](size_type i) 89 { 90 BOOST_ASSERT( i < N && "out of range" ); 91 return elems[i]; 92 } 93 operator [](size_type i) const94 const_reference operator[](size_type i) const 95 { 96 BOOST_ASSERT( i < N && "out of range" ); 97 return elems[i]; 98 } 99 100 // at() with range check at(size_type i)101 reference at(size_type i) { rangecheck(i); return elems[i]; } at(size_type i) const102 const_reference at(size_type i) const { rangecheck(i); return elems[i]; } 103 104 // front() and back() front()105 reference front() 106 { 107 return elems[0]; 108 } 109 front() const110 const_reference front() const 111 { 112 return elems[0]; 113 } 114 back()115 reference back() 116 { 117 return elems[N-1]; 118 } 119 back() const120 const_reference back() const 121 { 122 return elems[N-1]; 123 } 124 125 // size is constant size()126 static size_type size() { return N; } empty()127 static bool empty() { return false; } max_size()128 static size_type max_size() { return N; } 129 enum { static_size = N }; 130 131 // swap (note: linear complexity) swap(array<T,N> & y)132 void swap (array<T,N>& y) { 133 std::swap_ranges(begin(),end(),y.begin()); 134 } 135 136 // direct access to data (read-only) data() const137 const T* data() const { return elems; } 138 139 // use array as C array (direct read/write access to data) c_array()140 T* c_array() { return elems; } 141 142 // assignment with type conversion 143 template <typename T2> operator =(const array<T2,N> & rhs)144 array<T,N>& operator= (const array<T2,N>& rhs) { 145 std::copy(rhs.begin(),rhs.end(), begin()); 146 return *this; 147 } 148 149 // assign one value to all elements assign(const T & value)150 void assign (const T& value) 151 { 152 std::fill_n(begin(),size(),value); 153 } 154 155 // check range (may be private because it is static) rangecheck(size_type i)156 static void rangecheck (size_type i) { 157 if (i >= size()) { 158 throw std::range_error("array<>: index out of range"); 159 } 160 } 161 162 }; 163 164 // comparisons 165 template<class T, std::size_t N> operator ==(const array<T,N> & x,const array<T,N> & y)166 bool operator== (const array<T,N>& x, const array<T,N>& y) { 167 return std::equal(x.begin(), x.end(), y.begin()); 168 } 169 template<class T, std::size_t N> operator <(const array<T,N> & x,const array<T,N> & y)170 bool operator< (const array<T,N>& x, const array<T,N>& y) { 171 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); 172 } 173 template<class T, std::size_t N> operator !=(const array<T,N> & x,const array<T,N> & y)174 bool operator!= (const array<T,N>& x, const array<T,N>& y) { 175 return !(x==y); 176 } 177 template<class T, std::size_t N> operator >(const array<T,N> & x,const array<T,N> & y)178 bool operator> (const array<T,N>& x, const array<T,N>& y) { 179 return y<x; 180 } 181 template<class T, std::size_t N> operator <=(const array<T,N> & x,const array<T,N> & y)182 bool operator<= (const array<T,N>& x, const array<T,N>& y) { 183 return !(y<x); 184 } 185 template<class T, std::size_t N> operator >=(const array<T,N> & x,const array<T,N> & y)186 bool operator>= (const array<T,N>& x, const array<T,N>& y) { 187 return !(x<y); 188 } 189 190 // global swap() 191 template<class T, std::size_t N> swap(array<T,N> & x,array<T,N> & y)192 inline void swap (array<T,N>& x, array<T,N>& y) { 193 x.swap(y); 194 } 195 196 } /* namespace boost */ 197 198 #endif /*BOOST_ARRAY_HPP*/ 199