fix doc example typo
[boost.git] / boost / array.hpp
blob52218aac51383aed26e8ae622c2c891c79319945
1 /* The following code declares class array,
2 * an STL container (as wrapper) for arrays of constant size.
4 * See
5 * http://www.boost.org/libs/array/
6 * for documentation.
8 * The original author site is at: http://www.josuttis.com/
10 * (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)
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)
22 * Jan 29, 2004
24 #ifndef BOOST_ARRAY_HPP
25 #define BOOST_ARRAY_HPP
27 #include <cstddef>
28 #include <stdexcept>
29 #include <boost/assert.hpp>
31 // Handles broken standard libraries better than <iterator>
32 #include <boost/detail/iterator.hpp>
33 #include <boost/throw_exception.hpp>
34 #include <algorithm>
36 // FIXES for broken compilers
37 #include <boost/config.hpp>
40 namespace boost {
42 template<class T, std::size_t N>
43 class array {
44 public:
45 T elems[N]; // fixed-size array of elements of type T
47 public:
48 // type definitions
49 typedef T value_type;
50 typedef T* iterator;
51 typedef const T* const_iterator;
52 typedef T& reference;
53 typedef const T& const_reference;
54 typedef std::size_t size_type;
55 typedef std::ptrdiff_t difference_type;
57 // iterator support
58 iterator begin() { return elems; }
59 const_iterator begin() const { return elems; }
60 iterator end() { return elems+N; }
61 const_iterator end() const { return elems+N; }
63 // reverse iterator support
64 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
65 typedef std::reverse_iterator<iterator> reverse_iterator;
66 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
67 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
68 // workaround for broken reverse_iterator in VC7
69 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
70 reference, iterator, reference> > reverse_iterator;
71 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
72 const_reference, iterator, reference> > const_reverse_iterator;
73 #else
74 // workaround for broken reverse_iterator implementations
75 typedef std::reverse_iterator<iterator,T> reverse_iterator;
76 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
77 #endif
79 reverse_iterator rbegin() { return reverse_iterator(end()); }
80 const_reverse_iterator rbegin() const {
81 return const_reverse_iterator(end());
83 reverse_iterator rend() { return reverse_iterator(begin()); }
84 const_reverse_iterator rend() const {
85 return const_reverse_iterator(begin());
88 // operator[]
89 reference operator[](size_type i)
91 BOOST_ASSERT( i < N && "out of range" );
92 return elems[i];
95 const_reference operator[](size_type i) const
97 BOOST_ASSERT( i < N && "out of range" );
98 return elems[i];
101 // at() with range check
102 reference at(size_type i) { rangecheck(i); return elems[i]; }
103 const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
105 // front() and back()
106 reference front()
108 return elems[0];
111 const_reference front() const
113 return elems[0];
116 reference back()
118 return elems[N-1];
121 const_reference back() const
123 return elems[N-1];
126 // size is constant
127 static size_type size() { return N; }
128 static bool empty() { return false; }
129 static size_type max_size() { return N; }
130 enum { static_size = N };
132 // swap (note: linear complexity)
133 void swap (array<T,N>& y) {
134 std::swap_ranges(begin(),end(),y.begin());
137 // direct access to data (read-only)
138 const T* data() const { return elems; }
139 T* data() { return elems; }
141 // use array as C array (direct read/write access to data)
142 T* c_array() { return elems; }
144 // assignment with type conversion
145 template <typename T2>
146 array<T,N>& operator= (const array<T2,N>& rhs) {
147 std::copy(rhs.begin(),rhs.end(), begin());
148 return *this;
151 // assign one value to all elements
152 void assign (const T& value)
154 std::fill_n(begin(),size(),value);
157 // check range (may be private because it is static)
158 static void rangecheck (size_type i) {
159 if (i >= size()) {
160 throw std::out_of_range("array<>: index out of range");
166 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
167 template< class T >
168 class array< T, 0 > {
170 public:
171 // type definitions
172 typedef T value_type;
173 typedef T* iterator;
174 typedef const T* const_iterator;
175 typedef T& reference;
176 typedef const T& const_reference;
177 typedef std::size_t size_type;
178 typedef std::ptrdiff_t difference_type;
180 // iterator support
181 iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
182 const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
183 iterator end() { return begin(); }
184 const_iterator end() const { return begin(); }
186 // reverse iterator support
187 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
188 typedef std::reverse_iterator<iterator> reverse_iterator;
189 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
190 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
191 // workaround for broken reverse_iterator in VC7
192 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
193 reference, iterator, reference> > reverse_iterator;
194 typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
195 const_reference, iterator, reference> > const_reverse_iterator;
196 #else
197 // workaround for broken reverse_iterator implementations
198 typedef std::reverse_iterator<iterator,T> reverse_iterator;
199 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
200 #endif
202 reverse_iterator rbegin() { return reverse_iterator(end()); }
203 const_reverse_iterator rbegin() const {
204 return const_reverse_iterator(end());
206 reverse_iterator rend() { return reverse_iterator(begin()); }
207 const_reverse_iterator rend() const {
208 return const_reverse_iterator(begin());
211 // operator[]
212 reference operator[](size_type i)
214 return failed_rangecheck();
217 const_reference operator[](size_type i) const
219 return failed_rangecheck();
222 // at() with range check
223 reference at(size_type i) { return failed_rangecheck(); }
224 const_reference at(size_type i) const { return failed_rangecheck(); }
226 // front() and back()
227 reference front()
229 return failed_rangecheck();
232 const_reference front() const
234 return failed_rangecheck();
237 reference back()
239 return failed_rangecheck();
242 const_reference back() const
244 return failed_rangecheck();
247 // size is constant
248 static size_type size() { return 0; }
249 static bool empty() { return true; }
250 static size_type max_size() { return 0; }
251 enum { static_size = 0 };
253 void swap (array<T,0>& y) {
256 // direct access to data (read-only)
257 const T* data() const { return 0; }
258 T* data() { return 0; }
260 // use array as C array (direct read/write access to data)
261 T* c_array() { return 0; }
263 // assignment with type conversion
264 template <typename T2>
265 array<T,0>& operator= (const array<T2,0>& ) {
266 return *this;
269 // assign one value to all elements
270 void assign (const T& ) { }
272 // check range (may be private because it is static)
273 static reference failed_rangecheck () {
274 std::out_of_range e("attempt to access element of an empty array");
275 boost::throw_exception(e);
277 // We need to return something here to keep
278 // some compilers happy: however we will never
279 // actually get here....
281 static T placeholder;
282 return placeholder;
285 #endif
287 // comparisons
288 template<class T, std::size_t N>
289 bool operator== (const array<T,N>& x, const array<T,N>& y) {
290 return std::equal(x.begin(), x.end(), y.begin());
292 template<class T, std::size_t N>
293 bool operator< (const array<T,N>& x, const array<T,N>& y) {
294 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
296 template<class T, std::size_t N>
297 bool operator!= (const array<T,N>& x, const array<T,N>& y) {
298 return !(x==y);
300 template<class T, std::size_t N>
301 bool operator> (const array<T,N>& x, const array<T,N>& y) {
302 return y<x;
304 template<class T, std::size_t N>
305 bool operator<= (const array<T,N>& x, const array<T,N>& y) {
306 return !(y<x);
308 template<class T, std::size_t N>
309 bool operator>= (const array<T,N>& x, const array<T,N>& y) {
310 return !(x<y);
313 // global swap()
314 template<class T, std::size_t N>
315 inline void swap (array<T,N>& x, array<T,N>& y) {
316 x.swap(y);
319 } /* namespace boost */
321 #endif /*BOOST_ARRAY_HPP*/