]> git.lyx.org Git - lyx.git/blob - boost/boost/array.hpp
typos
[lyx.git] / boost / boost / array.hpp
1 /* The following code declares class array,
2  * an STL container (as wrapper) for arrays of constant size.
3  *
4  * See
5  *      http://www.boost.org/libs/array/
6  * for documentation.
7  *
8  * The original author site is at: http://www.josuttis.com/
9  *
10  * (C) Copyright Nicolai M. Josuttis 2001.
11  *
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 <boost/throw_exception.hpp>
34 #include <algorithm>
35
36 // FIXES for broken compilers
37 #include <boost/config.hpp>
38
39
40 namespace boost {
41
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
46
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;
56
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; }
62
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
78
79         reverse_iterator rbegin() { return reverse_iterator(end()); }
80         const_reverse_iterator rbegin() const {
81             return const_reverse_iterator(end());
82         }
83         reverse_iterator rend() { return reverse_iterator(begin()); }
84         const_reverse_iterator rend() const {
85             return const_reverse_iterator(begin());
86         }
87
88         // operator[]
89         reference operator[](size_type i) 
90         { 
91             BOOST_ASSERT( i < N && "out of range" ); 
92             return elems[i];
93         }
94         
95         const_reference operator[](size_type i) const 
96         {     
97             BOOST_ASSERT( i < N && "out of range" ); 
98             return elems[i]; 
99         }
100
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]; }
104     
105         // front() and back()
106         reference front() 
107         { 
108             return elems[0]; 
109         }
110         
111         const_reference front() const 
112         {
113             return elems[0];
114         }
115         
116         reference back() 
117         { 
118             return elems[N-1]; 
119         }
120         
121         const_reference back() const 
122         { 
123             return elems[N-1]; 
124         }
125
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 };
131
132         // swap (note: linear complexity)
133         void swap (array<T,N>& y) {
134             std::swap_ranges(begin(),end(),y.begin());
135         }
136
137         // direct access to data (read-only)
138         const T* data() const { return elems; }
139         T* data() { return elems; }
140
141         // use array as C array (direct read/write access to data)
142         T* c_array() { return elems; }
143
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;
149         }
150
151         // assign one value to all elements
152         void assign (const T& value)
153         {
154             std::fill_n(begin(),size(),value);
155         }
156
157         // check range (may be private because it is static)
158         static void rangecheck (size_type i) {
159             if (i >= size()) {
160                 throw std::range_error("array<>: index out of range");
161             }
162         }
163
164     };
165
166 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
167     template< class T >
168     class array< T, 0 > {
169
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;
179
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(); }
185
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
201
202         reverse_iterator rbegin() { return reverse_iterator(end()); }
203         const_reverse_iterator rbegin() const {
204             return const_reverse_iterator(end());
205         }
206         reverse_iterator rend() { return reverse_iterator(begin()); }
207         const_reverse_iterator rend() const {
208             return const_reverse_iterator(begin());
209         }
210
211         // operator[]
212         reference operator[](size_type i)
213         {
214             return failed_rangecheck();
215         }
216
217         const_reference operator[](size_type i) const
218         {
219             return failed_rangecheck();
220         }
221
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(); }
225
226         // front() and back()
227         reference front()
228         {
229             return failed_rangecheck();
230         }
231
232         const_reference front() const
233         {
234             return failed_rangecheck();
235         }
236
237         reference back()
238         {
239             return failed_rangecheck();
240         }
241
242         const_reference back() const
243         {
244             return failed_rangecheck();
245         }
246
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 };
252
253         void swap (array<T,0>& y) {
254         }
255
256         // direct access to data (read-only)
257         const T* data() const { return 0; }
258         T* data() { return 0; }
259
260         // use array as C array (direct read/write access to data)
261         T* c_array() { return 0; }
262
263         // assignment with type conversion
264         template <typename T2>
265         array<T,0>& operator= (const array<T2,0>& ) {
266             return *this;
267         }
268
269         // assign one value to all elements
270         void assign (const T& ) {   }
271
272         // check range (may be private because it is static)
273         static reference failed_rangecheck () {
274                 std::range_error e("attempt to access element of an empty array");
275                 boost::throw_exception(e);
276                 //
277                 // We need to return something here to keep
278                 // some compilers happy: however we will never
279                 // actually get here....
280                 //
281                 static T placeholder;
282                 return placeholder;
283             }
284     };
285 #endif
286
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());
291     }
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());
295     }
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);
299     }
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;
303     }
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);
307     }
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);
311     }
312
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);
317     }
318
319 } /* namespace boost */
320
321 #endif /*BOOST_ARRAY_HPP*/