]> git.lyx.org Git - lyx.git/blob - boost/boost/array.hpp
boost: update to 1.42.0
[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 <boost/detail/workaround.hpp>
28
29 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)  
30 # pragma warning(push)  
31 # pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe
32 #endif
33
34 #include <cstddef>
35 #include <stdexcept>
36 #include <boost/assert.hpp>
37 #include <boost/swap.hpp>
38
39 // Handles broken standard libraries better than <iterator>
40 #include <boost/detail/iterator.hpp>
41 #include <boost/throw_exception.hpp>
42 #include <algorithm>
43
44 // FIXES for broken compilers
45 #include <boost/config.hpp>
46
47
48 namespace boost {
49
50     template<class T, std::size_t N>
51     class array {
52       public:
53         T elems[N];    // fixed-size array of elements of type T
54
55       public:
56         // type definitions
57         typedef T              value_type;
58         typedef T*             iterator;
59         typedef const T*       const_iterator;
60         typedef T&             reference;
61         typedef const T&       const_reference;
62         typedef std::size_t    size_type;
63         typedef std::ptrdiff_t difference_type;
64
65         // iterator support
66         iterator begin() { return elems; }
67         const_iterator begin() const { return elems; }
68         iterator end() { return elems+N; }
69         const_iterator end() const { return elems+N; }
70
71         // reverse iterator support
72 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
73         typedef std::reverse_iterator<iterator> reverse_iterator;
74         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
75 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
76         // workaround for broken reverse_iterator in VC7
77         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
78                                       reference, iterator, reference> > reverse_iterator;
79         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
80                                       const_reference, iterator, reference> > const_reverse_iterator;
81 #else
82         // workaround for broken reverse_iterator implementations
83         typedef std::reverse_iterator<iterator,T> reverse_iterator;
84         typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
85 #endif
86
87         reverse_iterator rbegin() { return reverse_iterator(end()); }
88         const_reverse_iterator rbegin() const {
89             return const_reverse_iterator(end());
90         }
91         reverse_iterator rend() { return reverse_iterator(begin()); }
92         const_reverse_iterator rend() const {
93             return const_reverse_iterator(begin());
94         }
95
96         // operator[]
97         reference operator[](size_type i) 
98         { 
99             BOOST_ASSERT( i < N && "out of range" ); 
100             return elems[i];
101         }
102         
103         const_reference operator[](size_type i) const 
104         {     
105             BOOST_ASSERT( i < N && "out of range" ); 
106             return elems[i]; 
107         }
108
109         // at() with range check
110         reference at(size_type i) { rangecheck(i); return elems[i]; }
111         const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
112     
113         // front() and back()
114         reference front() 
115         { 
116             return elems[0]; 
117         }
118         
119         const_reference front() const 
120         {
121             return elems[0];
122         }
123         
124         reference back() 
125         { 
126             return elems[N-1]; 
127         }
128         
129         const_reference back() const 
130         { 
131             return elems[N-1]; 
132         }
133
134         // size is constant
135         static size_type size() { return N; }
136         static bool empty() { return false; }
137         static size_type max_size() { return N; }
138         enum { static_size = N };
139
140         // swap (note: linear complexity)
141         void swap (array<T,N>& y) {
142             for (size_type i = 0; i < N; ++i)
143                 boost::swap(elems[i],y.elems[i]);
144         }
145
146         // direct access to data (read-only)
147         const T* data() const { return elems; }
148         T* data() { return elems; }
149
150         // use array as C array (direct read/write access to data)
151         T* c_array() { return elems; }
152
153         // assignment with type conversion
154         template <typename T2>
155         array<T,N>& operator= (const array<T2,N>& rhs) {
156             std::copy(rhs.begin(),rhs.end(), begin());
157             return *this;
158         }
159
160         // assign one value to all elements
161         void assign (const T& value)
162         {
163             std::fill_n(begin(),size(),value);
164         }
165
166         // check range (may be private because it is static)
167         static void rangecheck (size_type i) {
168             if (i >= size()) {
169                 throw std::out_of_range("array<>: index out of range");
170             }
171         }
172
173     };
174
175 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
176     template< class T >
177     class array< T, 0 > {
178
179       public:
180         // type definitions
181         typedef T              value_type;
182         typedef T*             iterator;
183         typedef const T*       const_iterator;
184         typedef T&             reference;
185         typedef const T&       const_reference;
186         typedef std::size_t    size_type;
187         typedef std::ptrdiff_t difference_type;
188
189         // iterator support
190         iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
191         const_iterator begin() const { return const_iterator(  reinterpret_cast< const T * >( this ) ); }
192         iterator end() { return begin(); }
193         const_iterator end() const { return begin(); }
194
195         // reverse iterator support
196 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
197         typedef std::reverse_iterator<iterator> reverse_iterator;
198         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
199 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
200         // workaround for broken reverse_iterator in VC7
201         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
202                                       reference, iterator, reference> > reverse_iterator;
203         typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
204                                       const_reference, iterator, reference> > const_reverse_iterator;
205 #else
206         // workaround for broken reverse_iterator implementations
207         typedef std::reverse_iterator<iterator,T> reverse_iterator;
208         typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
209 #endif
210
211         reverse_iterator rbegin() { return reverse_iterator(end()); }
212         const_reverse_iterator rbegin() const {
213             return const_reverse_iterator(end());
214         }
215         reverse_iterator rend() { return reverse_iterator(begin()); }
216         const_reverse_iterator rend() const {
217             return const_reverse_iterator(begin());
218         }
219
220         // operator[]
221         reference operator[](size_type /*i*/)
222         {
223             return failed_rangecheck();
224         }
225
226         const_reference operator[](size_type /*i*/) const
227         {
228             return failed_rangecheck();
229         }
230
231         // at() with range check
232         reference at(size_type /*i*/)               {   return failed_rangecheck(); }
233         const_reference at(size_type /*i*/) const   {   return failed_rangecheck(); }
234
235         // front() and back()
236         reference front()
237         {
238             return failed_rangecheck();
239         }
240
241         const_reference front() const
242         {
243             return failed_rangecheck();
244         }
245
246         reference back()
247         {
248             return failed_rangecheck();
249         }
250
251         const_reference back() const
252         {
253             return failed_rangecheck();
254         }
255
256         // size is constant
257         static size_type size() { return 0; }
258         static bool empty() { return true; }
259         static size_type max_size() { return 0; }
260         enum { static_size = 0 };
261
262         void swap (array<T,0>& /*y*/) {
263         }
264
265         // direct access to data (read-only)
266         const T* data() const { return 0; }
267         T* data() { return 0; }
268
269         // use array as C array (direct read/write access to data)
270         T* c_array() { return 0; }
271
272         // assignment with type conversion
273         template <typename T2>
274         array<T,0>& operator= (const array<T2,0>& ) {
275             return *this;
276         }
277
278         // assign one value to all elements
279         void assign (const T& ) {   }
280
281         // check range (may be private because it is static)
282         static reference failed_rangecheck () {
283                 std::out_of_range e("attempt to access element of an empty array");
284                 boost::throw_exception(e);
285                 //
286                 // We need to return something here to keep
287                 // some compilers happy: however we will never
288                 // actually get here....
289                 //
290                 static T placeholder;
291                 return placeholder;
292             }
293     };
294 #endif
295
296     // comparisons
297     template<class T, std::size_t N>
298     bool operator== (const array<T,N>& x, const array<T,N>& y) {
299         return std::equal(x.begin(), x.end(), y.begin());
300     }
301     template<class T, std::size_t N>
302     bool operator< (const array<T,N>& x, const array<T,N>& y) {
303         return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
304     }
305     template<class T, std::size_t N>
306     bool operator!= (const array<T,N>& x, const array<T,N>& y) {
307         return !(x==y);
308     }
309     template<class T, std::size_t N>
310     bool operator> (const array<T,N>& x, const array<T,N>& y) {
311         return y<x;
312     }
313     template<class T, std::size_t N>
314     bool operator<= (const array<T,N>& x, const array<T,N>& y) {
315         return !(y<x);
316     }
317     template<class T, std::size_t N>
318     bool operator>= (const array<T,N>& x, const array<T,N>& y) {
319         return !(x<y);
320     }
321
322     // global swap()
323     template<class T, std::size_t N>
324     inline void swap (array<T,N>& x, array<T,N>& y) {
325         x.swap(y);
326     }
327
328 } /* namespace boost */
329
330
331 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)  
332 # pragma warning(pop)  
333 #endif 
334
335 #endif /*BOOST_ARRAY_HPP*/