1 /* The following code declares class array,
2 * an STL container (as wrapper) for arrays of constant size.
5 * http://www.boost.org/libs/array/
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)
24 #ifndef BOOST_ARRAY_HPP
25 #define BOOST_ARRAY_HPP
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>
36 // FIXES for broken compilers
37 #include <boost/config.hpp>
42 template<class T
, std::size_t N
>
45 T elems
[N
]; // fixed-size array of elements of type T
51 typedef const T
* const_iterator
;
53 typedef const T
& const_reference
;
54 typedef std::size_t size_type
;
55 typedef std::ptrdiff_t difference_type
;
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
;
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
;
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());
89 reference
operator[](size_type i
)
91 BOOST_ASSERT( i
< N
&& "out of range" );
95 const_reference
operator[](size_type i
) const
97 BOOST_ASSERT( i
< N
&& "out of range" );
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()
111 const_reference
front() const
121 const_reference
back() const
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());
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
) {
160 throw std::out_of_range("array<>: index out of range");
166 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
168 class array
< T
, 0 > {
172 typedef T value_type
;
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
;
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
;
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
;
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());
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()
229 return failed_rangecheck();
232 const_reference
front() const
234 return failed_rangecheck();
239 return failed_rangecheck();
242 const_reference
back() const
244 return failed_rangecheck();
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>& ) {
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
;
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
) {
300 template<class T
, std::size_t N
>
301 bool operator> (const array
<T
,N
>& x
, const array
<T
,N
>& y
) {
304 template<class T
, std::size_t N
>
305 bool operator<= (const array
<T
,N
>& x
, const array
<T
,N
>& y
) {
308 template<class T
, std::size_t N
>
309 bool operator>= (const array
<T
,N
>& x
, const array
<T
,N
>& y
) {
314 template<class T
, std::size_t N
>
315 inline void swap (array
<T
,N
>& x
, array
<T
,N
>& y
) {
319 } /* namespace boost */
321 #endif /*BOOST_ARRAY_HPP*/