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