Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/array.hpp @ 44

Last change on this file since 44 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 10.6 KB
Line 
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
40namespace 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*/
Note: See TracBrowser for help on using the repository browser.