os/ossrv/ossrv_pub/boost_apis/boost/array.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* The following code declares class array,
sl@0
     2
 * an STL container (as wrapper) for arrays of constant size.
sl@0
     3
 *
sl@0
     4
 * See
sl@0
     5
 *      http://www.boost.org/libs/array/
sl@0
     6
 * for documentation.
sl@0
     7
 *
sl@0
     8
 * The original author site is at: http://www.josuttis.com/
sl@0
     9
 *
sl@0
    10
 * (C) Copyright Nicolai M. Josuttis 2001.
sl@0
    11
 *
sl@0
    12
 * Distributed under the Boost Software License, Version 1.0. (See
sl@0
    13
 * accompanying file LICENSE_1_0.txt or copy at
sl@0
    14
 * http://www.boost.org/LICENSE_1_0.txt)
sl@0
    15
 *
sl@0
    16
 * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)
sl@0
    17
 * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
sl@0
    18
 * 05 Aug 2001 - minor update (Nico Josuttis)
sl@0
    19
 * 20 Jan 2001 - STLport fix (Beman Dawes)
sl@0
    20
 * 29 Sep 2000 - Initial Revision (Nico Josuttis)
sl@0
    21
 *
sl@0
    22
 * Jan 29, 2004
sl@0
    23
 */
sl@0
    24
#ifndef BOOST_ARRAY_HPP
sl@0
    25
#define BOOST_ARRAY_HPP
sl@0
    26
sl@0
    27
#include <cstddef>
sl@0
    28
#include <stdexcept>
sl@0
    29
#include <boost/assert.hpp>
sl@0
    30
sl@0
    31
// Handles broken standard libraries better than <iterator>
sl@0
    32
#include <boost/detail/iterator.hpp>
sl@0
    33
#include <boost/throw_exception.hpp>
sl@0
    34
#include <algorithm>
sl@0
    35
sl@0
    36
// FIXES for broken compilers
sl@0
    37
#include <boost/config.hpp>
sl@0
    38
sl@0
    39
sl@0
    40
namespace boost {
sl@0
    41
sl@0
    42
    template<class T, std::size_t N>
sl@0
    43
    class array {
sl@0
    44
      public:
sl@0
    45
        T elems[N];    // fixed-size array of elements of type T
sl@0
    46
sl@0
    47
      public:
sl@0
    48
        // type definitions
sl@0
    49
        typedef T              value_type;
sl@0
    50
        typedef T*             iterator;
sl@0
    51
        typedef const T*       const_iterator;
sl@0
    52
        typedef T&             reference;
sl@0
    53
        typedef const T&       const_reference;
sl@0
    54
        typedef std::size_t    size_type;
sl@0
    55
        typedef std::ptrdiff_t difference_type;
sl@0
    56
sl@0
    57
        // iterator support
sl@0
    58
        iterator begin() { return elems; }
sl@0
    59
        const_iterator begin() const { return elems; }
sl@0
    60
        iterator end() { return elems+N; }
sl@0
    61
        const_iterator end() const { return elems+N; }
sl@0
    62
sl@0
    63
        // reverse iterator support
sl@0
    64
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
sl@0
    65
        typedef std::reverse_iterator<iterator> reverse_iterator;
sl@0
    66
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
sl@0
    67
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
sl@0
    68
        // workaround for broken reverse_iterator in VC7
sl@0
    69
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
sl@0
    70
                                      reference, iterator, reference> > reverse_iterator;
sl@0
    71
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
sl@0
    72
                                      const_reference, iterator, reference> > const_reverse_iterator;
sl@0
    73
#else
sl@0
    74
        // workaround for broken reverse_iterator implementations
sl@0
    75
        typedef std::reverse_iterator<iterator,T> reverse_iterator;
sl@0
    76
        typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
sl@0
    77
#endif
sl@0
    78
sl@0
    79
        reverse_iterator rbegin() { return reverse_iterator(end()); }
sl@0
    80
        const_reverse_iterator rbegin() const {
sl@0
    81
            return const_reverse_iterator(end());
sl@0
    82
        }
sl@0
    83
        reverse_iterator rend() { return reverse_iterator(begin()); }
sl@0
    84
        const_reverse_iterator rend() const {
sl@0
    85
            return const_reverse_iterator(begin());
sl@0
    86
        }
sl@0
    87
sl@0
    88
        // operator[]
sl@0
    89
        reference operator[](size_type i) 
sl@0
    90
        { 
sl@0
    91
            BOOST_ASSERT( i < N && "out of range" ); 
sl@0
    92
            return elems[i];
sl@0
    93
        }
sl@0
    94
        
sl@0
    95
        const_reference operator[](size_type i) const 
sl@0
    96
        {     
sl@0
    97
            BOOST_ASSERT( i < N && "out of range" ); 
sl@0
    98
            return elems[i]; 
sl@0
    99
        }
sl@0
   100
sl@0
   101
        // at() with range check
sl@0
   102
        reference at(size_type i) { rangecheck(i); return elems[i]; }
sl@0
   103
        const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
sl@0
   104
    
sl@0
   105
        // front() and back()
sl@0
   106
        reference front() 
sl@0
   107
        { 
sl@0
   108
            return elems[0]; 
sl@0
   109
        }
sl@0
   110
        
sl@0
   111
        const_reference front() const 
sl@0
   112
        {
sl@0
   113
            return elems[0];
sl@0
   114
        }
sl@0
   115
        
sl@0
   116
        reference back() 
sl@0
   117
        { 
sl@0
   118
            return elems[N-1]; 
sl@0
   119
        }
sl@0
   120
        
sl@0
   121
        const_reference back() const 
sl@0
   122
        { 
sl@0
   123
            return elems[N-1]; 
sl@0
   124
        }
sl@0
   125
sl@0
   126
        // size is constant
sl@0
   127
        static size_type size() { return N; }
sl@0
   128
        static bool empty() { return false; }
sl@0
   129
        static size_type max_size() { return N; }
sl@0
   130
        enum { static_size = N };
sl@0
   131
sl@0
   132
        // swap (note: linear complexity)
sl@0
   133
        void swap (array<T,N>& y) {
sl@0
   134
            std::swap_ranges(begin(),end(),y.begin());
sl@0
   135
        }
sl@0
   136
sl@0
   137
        // direct access to data (read-only)
sl@0
   138
        const T* data() const { return elems; }
sl@0
   139
        T* data() { return elems; }
sl@0
   140
sl@0
   141
        // use array as C array (direct read/write access to data)
sl@0
   142
        T* c_array() { return elems; }
sl@0
   143
sl@0
   144
        // assignment with type conversion
sl@0
   145
        template <typename T2>
sl@0
   146
        array<T,N>& operator= (const array<T2,N>& rhs) {
sl@0
   147
            std::copy(rhs.begin(),rhs.end(), begin());
sl@0
   148
            return *this;
sl@0
   149
        }
sl@0
   150
sl@0
   151
        // assign one value to all elements
sl@0
   152
        void assign (const T& value)
sl@0
   153
        {
sl@0
   154
            std::fill_n(begin(),size(),value);
sl@0
   155
        }
sl@0
   156
sl@0
   157
        // check range (may be private because it is static)
sl@0
   158
        static void rangecheck (size_type i) {
sl@0
   159
            if (i >= size()) {
sl@0
   160
                throw std::range_error("array<>: index out of range");
sl@0
   161
            }
sl@0
   162
        }
sl@0
   163
sl@0
   164
    };
sl@0
   165
sl@0
   166
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
sl@0
   167
    template< class T >
sl@0
   168
    class array< T, 0 > {
sl@0
   169
sl@0
   170
      public:
sl@0
   171
        // type definitions
sl@0
   172
        typedef T              value_type;
sl@0
   173
        typedef T*             iterator;
sl@0
   174
        typedef const T*       const_iterator;
sl@0
   175
        typedef T&             reference;
sl@0
   176
        typedef const T&       const_reference;
sl@0
   177
        typedef std::size_t    size_type;
sl@0
   178
        typedef std::ptrdiff_t difference_type;
sl@0
   179
sl@0
   180
        // iterator support
sl@0
   181
        iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
sl@0
   182
        const_iterator begin() const { return const_iterator(  reinterpret_cast< const T * >( this ) ); }
sl@0
   183
        iterator end() { return begin(); }
sl@0
   184
        const_iterator end() const { return begin(); }
sl@0
   185
sl@0
   186
        // reverse iterator support
sl@0
   187
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
sl@0
   188
        typedef std::reverse_iterator<iterator> reverse_iterator;
sl@0
   189
        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
sl@0
   190
#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
sl@0
   191
        // workaround for broken reverse_iterator in VC7
sl@0
   192
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
sl@0
   193
                                      reference, iterator, reference> > reverse_iterator;
sl@0
   194
        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
sl@0
   195
                                      const_reference, iterator, reference> > const_reverse_iterator;
sl@0
   196
#else
sl@0
   197
        // workaround for broken reverse_iterator implementations
sl@0
   198
        typedef std::reverse_iterator<iterator,T> reverse_iterator;
sl@0
   199
        typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
sl@0
   200
#endif
sl@0
   201
sl@0
   202
        reverse_iterator rbegin() { return reverse_iterator(end()); }
sl@0
   203
        const_reverse_iterator rbegin() const {
sl@0
   204
            return const_reverse_iterator(end());
sl@0
   205
        }
sl@0
   206
        reverse_iterator rend() { return reverse_iterator(begin()); }
sl@0
   207
        const_reverse_iterator rend() const {
sl@0
   208
            return const_reverse_iterator(begin());
sl@0
   209
        }
sl@0
   210
sl@0
   211
        // operator[]
sl@0
   212
        reference operator[](size_type i)
sl@0
   213
        {
sl@0
   214
            return failed_rangecheck();
sl@0
   215
        }
sl@0
   216
sl@0
   217
        const_reference operator[](size_type i) const
sl@0
   218
        {
sl@0
   219
            return failed_rangecheck();
sl@0
   220
        }
sl@0
   221
sl@0
   222
        // at() with range check
sl@0
   223
        reference at(size_type i)               {   return failed_rangecheck(); }
sl@0
   224
        const_reference at(size_type i) const   {   return failed_rangecheck(); }
sl@0
   225
sl@0
   226
        // front() and back()
sl@0
   227
        reference front()
sl@0
   228
        {
sl@0
   229
            return failed_rangecheck();
sl@0
   230
        }
sl@0
   231
sl@0
   232
        const_reference front() const
sl@0
   233
        {
sl@0
   234
            return failed_rangecheck();
sl@0
   235
        }
sl@0
   236
sl@0
   237
        reference back()
sl@0
   238
        {
sl@0
   239
            return failed_rangecheck();
sl@0
   240
        }
sl@0
   241
sl@0
   242
        const_reference back() const
sl@0
   243
        {
sl@0
   244
            return failed_rangecheck();
sl@0
   245
        }
sl@0
   246
sl@0
   247
        // size is constant
sl@0
   248
        static size_type size() { return 0; }
sl@0
   249
        static bool empty() { return true; }
sl@0
   250
        static size_type max_size() { return 0; }
sl@0
   251
        enum { static_size = 0 };
sl@0
   252
sl@0
   253
        void swap (array<T,0>& y) {
sl@0
   254
        }
sl@0
   255
sl@0
   256
        // direct access to data (read-only)
sl@0
   257
        const T* data() const { return 0; }
sl@0
   258
        T* data() { return 0; }
sl@0
   259
sl@0
   260
        // use array as C array (direct read/write access to data)
sl@0
   261
        T* c_array() { return 0; }
sl@0
   262
sl@0
   263
        // assignment with type conversion
sl@0
   264
        template <typename T2>
sl@0
   265
        array<T,0>& operator= (const array<T2,0>& ) {
sl@0
   266
            return *this;
sl@0
   267
        }
sl@0
   268
sl@0
   269
        // assign one value to all elements
sl@0
   270
        void assign (const T& ) {   }
sl@0
   271
sl@0
   272
        // check range (may be private because it is static)
sl@0
   273
        static reference failed_rangecheck () {
sl@0
   274
                std::range_error e("attempt to access element of an empty array");
sl@0
   275
                boost::throw_exception(e);
sl@0
   276
                //
sl@0
   277
                // We need to return something here to keep
sl@0
   278
                // some compilers happy: however we will never
sl@0
   279
                // actually get here....
sl@0
   280
                //
sl@0
   281
                static T placeholder;
sl@0
   282
                return placeholder;
sl@0
   283
            }
sl@0
   284
    };
sl@0
   285
#endif
sl@0
   286
sl@0
   287
    // comparisons
sl@0
   288
    template<class T, std::size_t N>
sl@0
   289
    bool operator== (const array<T,N>& x, const array<T,N>& y) {
sl@0
   290
        return std::equal(x.begin(), x.end(), y.begin());
sl@0
   291
    }
sl@0
   292
    template<class T, std::size_t N>
sl@0
   293
    bool operator< (const array<T,N>& x, const array<T,N>& y) {
sl@0
   294
        return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
sl@0
   295
    }
sl@0
   296
    template<class T, std::size_t N>
sl@0
   297
    bool operator!= (const array<T,N>& x, const array<T,N>& y) {
sl@0
   298
        return !(x==y);
sl@0
   299
    }
sl@0
   300
    template<class T, std::size_t N>
sl@0
   301
    bool operator> (const array<T,N>& x, const array<T,N>& y) {
sl@0
   302
        return y<x;
sl@0
   303
    }
sl@0
   304
    template<class T, std::size_t N>
sl@0
   305
    bool operator<= (const array<T,N>& x, const array<T,N>& y) {
sl@0
   306
        return !(y<x);
sl@0
   307
    }
sl@0
   308
    template<class T, std::size_t N>
sl@0
   309
    bool operator>= (const array<T,N>& x, const array<T,N>& y) {
sl@0
   310
        return !(x<y);
sl@0
   311
    }
sl@0
   312
sl@0
   313
    // global swap()
sl@0
   314
    template<class T, std::size_t N>
sl@0
   315
    inline void swap (array<T,N>& x, array<T,N>& y) {
sl@0
   316
        x.swap(y);
sl@0
   317
    }
sl@0
   318
sl@0
   319
} /* namespace boost */
sl@0
   320
sl@0
   321
#endif /*BOOST_ARRAY_HPP*/