Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:10:37

0001 #ifndef BOOST_ARRAY_HPP_INCLUDED
0002 #define BOOST_ARRAY_HPP_INCLUDED
0003 
0004 /* The following code declares class array,
0005  * an STL container (as wrapper) for arrays of constant size.
0006  *
0007  * See
0008  *      http://www.boost.org/libs/array/
0009  * for documentation.
0010  *
0011  * The original author site is at: http://www.josuttis.com/
0012  *
0013  * (C) Copyright Nicolai M. Josuttis 2001.
0014  *
0015  * Distributed under the Boost Software License, Version 1.0. (See
0016  * accompanying file LICENSE_1_0.txt or copy at
0017  * http://www.boost.org/LICENSE_1_0.txt)
0018  *
0019  *  9 Jan 2013 - (mtc) Added constexpr
0020  * 14 Apr 2012 - (mtc) Added support for boost::hash
0021  * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
0022  * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
0023  *      See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168
0024  *      Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow)
0025  * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow)
0026  * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)
0027  * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
0028  * 05 Aug 2001 - minor update (Nico Josuttis)
0029  * 20 Jan 2001 - STLport fix (Beman Dawes)
0030  * 29 Sep 2000 - Initial Revision (Nico Josuttis)
0031  *
0032  * Jan 29, 2004
0033  */
0034 
0035 #include <boost/config.hpp>
0036 #include <boost/config/workaround.hpp>
0037 
0038 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0039 # pragma warning(push)
0040 # pragma warning(disable: 4510) // boost::array<T,N>' : default constructor could not be generated
0041 # pragma warning(disable: 4512) // boost::array<T,N>' : assignment operator could not be generated
0042 # pragma warning(disable: 4610) // class 'boost::array<T,N>' can never be instantiated - user defined constructor required
0043 # pragma warning(disable: 4702) // unreachable code
0044 #endif
0045 
0046 #include <boost/assert.hpp>
0047 #include <boost/static_assert.hpp>
0048 #include <boost/throw_exception.hpp>
0049 #include <iterator>
0050 #include <stdexcept>
0051 #include <utility>
0052 #include <cstddef>
0053 
0054 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L
0055 # if __has_include(<compare>)
0056 #  include <compare>
0057 # endif
0058 #endif
0059 
0060 namespace boost {
0061 
0062     template<class T, std::size_t N>
0063     class array {
0064       public:
0065         T elems[N];    // fixed-size array of elements of type T
0066 
0067       public:
0068         // type definitions
0069         typedef T              value_type;
0070         typedef T*             iterator;
0071         typedef const T*       const_iterator;
0072         typedef T&             reference;
0073         typedef const T&       const_reference;
0074         typedef std::size_t    size_type;
0075         typedef std::ptrdiff_t difference_type;
0076 
0077         // iterator support
0078         BOOST_CXX14_CONSTEXPR iterator  begin()       BOOST_NOEXCEPT { return elems; }
0079         BOOST_CONSTEXPR const_iterator  begin() const BOOST_NOEXCEPT { return elems; }
0080         BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return elems; }
0081 
0082         BOOST_CXX14_CONSTEXPR iterator  end()       BOOST_NOEXCEPT { return elems+N; }
0083         BOOST_CONSTEXPR const_iterator  end() const BOOST_NOEXCEPT { return elems+N; }
0084         BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return elems+N; }
0085 
0086         // reverse iterator support
0087         typedef std::reverse_iterator<iterator> reverse_iterator;
0088         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0089 
0090         reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
0091         const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
0092             return const_reverse_iterator(end());
0093         }
0094         const_reverse_iterator crbegin() const BOOST_NOEXCEPT {
0095             return const_reverse_iterator(end());
0096         }
0097 
0098         reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); }
0099         const_reverse_iterator rend() const BOOST_NOEXCEPT {
0100             return const_reverse_iterator(begin());
0101         }
0102         const_reverse_iterator crend() const BOOST_NOEXCEPT {
0103             return const_reverse_iterator(begin());
0104         }
0105 
0106         // operator[]
0107         BOOST_CXX14_CONSTEXPR reference operator[](size_type i)
0108         {
0109             return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
0110         }
0111 
0112 #if !BOOST_WORKAROUND(BOOST_GCC, < 50000)
0113         BOOST_CONSTEXPR
0114 #endif
0115         const_reference operator[](size_type i) const
0116         {
0117             return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
0118         }
0119 
0120         // at() with range check
0121         BOOST_CXX14_CONSTEXPR reference at(size_type i)       { return rangecheck(i), elems[i]; }
0122         BOOST_CONSTEXPR const_reference at(size_type i) const { return rangecheck(i), elems[i]; }
0123 
0124         // front() and back()
0125         BOOST_CXX14_CONSTEXPR reference front()
0126         {
0127             return elems[0];
0128         }
0129 
0130         BOOST_CONSTEXPR const_reference front() const
0131         {
0132             return elems[0];
0133         }
0134 
0135         BOOST_CXX14_CONSTEXPR reference back()
0136         {
0137             return elems[N-1];
0138         }
0139 
0140         BOOST_CONSTEXPR const_reference back() const
0141         {
0142             return elems[N-1];
0143         }
0144 
0145         // size is constant
0146         static BOOST_CONSTEXPR size_type size() BOOST_NOEXCEPT { return N; }
0147         static BOOST_CONSTEXPR bool empty() BOOST_NOEXCEPT { return false; }
0148         static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return N; }
0149         enum { static_size = N };
0150 
0151         // swap (note: linear complexity)
0152         BOOST_CXX14_CONSTEXPR void swap (array<T,N>& y)
0153         {
0154             std::swap( elems, y.elems );
0155         }
0156 
0157         // direct access to data
0158         BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return elems; }
0159         BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return elems; }
0160 
0161         // obsolete
0162         BOOST_DEPRECATED( "please use `data()` instead" )
0163         T* c_array() BOOST_NOEXCEPT { return elems; }
0164 
0165         // assignment with type conversion
0166         template <typename T2>
0167         array<T,N>& operator= (const array<T2,N>& rhs)
0168         {
0169             for( std::size_t i = 0; i < N; ++i )
0170             {
0171                 elems[ i ] = rhs.elems[ i ];
0172             }
0173 
0174             return *this;
0175         }
0176 
0177         // fill with one value
0178         BOOST_CXX14_CONSTEXPR void fill (const T& value)
0179         {
0180             // using elems[ 0 ] as a temporary copy
0181             // avoids the aliasing opportunity betw.
0182             // `value` and `elems`
0183 
0184             elems[ 0 ] = value;
0185 
0186             for( std::size_t i = 1; i < N; ++i )
0187             {
0188                 elems[ i ] = elems[ 0 ];
0189             }
0190         }
0191 
0192         // an obsolete synonym for fill
0193         BOOST_DEPRECATED( "please use `fill` instead" )
0194         void assign (const T& value) { fill ( value ); }
0195 
0196         // check range (may be private because it is static)
0197         static BOOST_CONSTEXPR bool rangecheck (size_type i) {
0198             return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true;
0199         }
0200 
0201     };
0202 
0203     template< class T >
0204     class array< T, 0 > {
0205       public:
0206         struct {} elems; // enables initialization with = {{}}
0207 
0208       public:
0209         // type definitions
0210         typedef T              value_type;
0211         typedef T*             iterator;
0212         typedef const T*       const_iterator;
0213         typedef T&             reference;
0214         typedef const T&       const_reference;
0215         typedef std::size_t    size_type;
0216         typedef std::ptrdiff_t difference_type;
0217 
0218         // iterator support
0219         BOOST_CXX14_CONSTEXPR iterator  begin()       BOOST_NOEXCEPT { return data(); }
0220         BOOST_CONSTEXPR const_iterator  begin() const BOOST_NOEXCEPT { return data(); }
0221         BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return data(); }
0222 
0223         BOOST_CXX14_CONSTEXPR iterator  end()       BOOST_NOEXCEPT { return  begin(); }
0224         BOOST_CONSTEXPR const_iterator  end() const BOOST_NOEXCEPT { return  begin(); }
0225         BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return cbegin(); }
0226 
0227         // reverse iterator support
0228         typedef std::reverse_iterator<iterator> reverse_iterator;
0229         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0230 
0231         reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
0232         const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
0233             return const_reverse_iterator(end());
0234         }
0235         const_reverse_iterator crbegin() const BOOST_NOEXCEPT {
0236             return const_reverse_iterator(end());
0237         }
0238 
0239         reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); }
0240         const_reverse_iterator rend() const BOOST_NOEXCEPT {
0241             return const_reverse_iterator(begin());
0242         }
0243         const_reverse_iterator crend() const BOOST_NOEXCEPT {
0244             return const_reverse_iterator(begin());
0245         }
0246 
0247         // operator[]
0248         reference operator[](size_type /*i*/)
0249         {
0250             return failed_rangecheck();
0251         }
0252 
0253         const_reference operator[](size_type /*i*/) const
0254         {
0255             return failed_rangecheck();
0256         }
0257 
0258         // at() with range check
0259         reference at(size_type /*i*/)               { return failed_rangecheck(); }
0260         const_reference at(size_type /*i*/) const   { return failed_rangecheck(); }
0261 
0262         // front() and back()
0263         reference front()
0264         {
0265             return failed_rangecheck();
0266         }
0267 
0268         const_reference front() const
0269         {
0270             return failed_rangecheck();
0271         }
0272 
0273         reference back()
0274         {
0275             return failed_rangecheck();
0276         }
0277 
0278         const_reference back() const
0279         {
0280             return failed_rangecheck();
0281         }
0282 
0283         // size is constant
0284         static BOOST_CONSTEXPR size_type size() BOOST_NOEXCEPT { return 0; }
0285         static BOOST_CONSTEXPR bool empty() BOOST_NOEXCEPT { return true; }
0286         static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return 0; }
0287         enum { static_size = 0 };
0288 
0289         BOOST_CXX14_CONSTEXPR void swap (array<T,0>& /*y*/)
0290         {
0291         }
0292 
0293         // direct access to data
0294         BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return 0; }
0295         BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return 0; }
0296 
0297         // obsolete
0298         BOOST_DEPRECATED( "please use `data()` instead" )
0299         T* c_array() BOOST_NOEXCEPT { return 0; }
0300 
0301         // assignment with type conversion
0302         template <typename T2>
0303         array<T,0>& operator= (const array<T2,0>& ) {
0304             return *this;
0305         }
0306 
0307         // an obsolete synonym for fill
0308         BOOST_DEPRECATED( "please use `fill` instead" )
0309         void assign (const T& value) { fill ( value ); }
0310 
0311         // fill with one value
0312         BOOST_CXX14_CONSTEXPR void fill (const T& ) {}
0313 
0314         // check range (may be private because it is static)
0315         static reference failed_rangecheck ()
0316         {
0317             boost::throw_exception( std::out_of_range( "attempt to access element of an empty array" ) );
0318         }
0319     };
0320 
0321     // comparisons
0322     template<class T, std::size_t N>
0323     BOOST_CXX14_CONSTEXPR bool operator== (const array<T,N>& x, const array<T,N>& y)
0324     {
0325         for( std::size_t i = 0; i < N; ++i )
0326         {
0327             if( !( x[ i ] == y[ i ] ) ) return false;
0328         }
0329 
0330         return true;
0331     }
0332 
0333 #if BOOST_WORKAROUND(BOOST_GCC, < 90000)
0334 
0335     template<class T>
0336     BOOST_CXX14_CONSTEXPR bool operator== (const array<T, 0>& /*x*/, const array<T, 0>& /*y*/)
0337     {
0338         return true;
0339     }
0340 
0341 #endif
0342 
0343     template<class T, std::size_t N>
0344     BOOST_CXX14_CONSTEXPR bool operator!= (const array<T,N>& x, const array<T,N>& y) {
0345         return !(x==y);
0346     }
0347 
0348     template<class T, std::size_t N>
0349     BOOST_CXX14_CONSTEXPR bool operator< (const array<T,N>& x, const array<T,N>& y)
0350     {
0351         for( std::size_t i = 0; i < N; ++i )
0352         {
0353             if( x[ i ] < y[ i ] ) return true;
0354             if( y[ i ] < x[ i ] ) return false;
0355         }
0356 
0357         return false;
0358     }
0359 
0360 #if BOOST_WORKAROUND(BOOST_GCC, < 90000)
0361 
0362     template<class T>
0363     BOOST_CXX14_CONSTEXPR bool operator< (const array<T, 0>& /*x*/, const array<T, 0>& /*y*/)
0364     {
0365         return false;
0366     }
0367 
0368 #endif
0369 
0370     template<class T, std::size_t N>
0371     BOOST_CXX14_CONSTEXPR bool operator> (const array<T,N>& x, const array<T,N>& y) {
0372         return y<x;
0373     }
0374 
0375     template<class T, std::size_t N>
0376     BOOST_CXX14_CONSTEXPR bool operator<= (const array<T,N>& x, const array<T,N>& y) {
0377         return !(y<x);
0378     }
0379 
0380     template<class T, std::size_t N>
0381     BOOST_CXX14_CONSTEXPR bool operator>= (const array<T,N>& x, const array<T,N>& y) {
0382         return !(x<y);
0383     }
0384 
0385     // global swap()
0386     template<class T, std::size_t N>
0387     BOOST_CXX14_CONSTEXPR inline void swap (array<T,N>& x, array<T,N>& y) {
0388         x.swap(y);
0389     }
0390 
0391 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L
0392 # if __has_include(<compare>)
0393 
0394     template<class T, std::size_t N>
0395     constexpr auto operator<=> (const array<T,N>& x, const array<T,N>& y)
0396         -> decltype( x.elems[ 0 ] <=> y.elems[ 0 ] )
0397     {
0398         for( std::size_t i = 0; i < N; ++i )
0399         {
0400             auto r = x.elems[ i ] <=> y.elems[ i ];
0401             if( r != 0 ) return r;
0402         }
0403 
0404         return std::strong_ordering::equal;
0405     }
0406 
0407     template<class T>
0408     constexpr auto operator<=> (const array<T,0>& /*x*/, const array<T,0>& /*y*/)
0409         -> std::strong_ordering
0410     {
0411         return std::strong_ordering::equal;
0412     }
0413 
0414 # endif
0415 #endif
0416 
0417     // undocumented and obsolete
0418     template <typename T, std::size_t N>
0419     BOOST_DEPRECATED( "please use `elems` instead" )
0420     T(&get_c_array(boost::array<T,N>& arg))[N]
0421     {
0422         return arg.elems;
0423     }
0424 
0425     // Const version.
0426     template <typename T, std::size_t N>
0427     BOOST_DEPRECATED( "please use `elems` instead" )
0428     const T(&get_c_array(const boost::array<T,N>& arg))[N]
0429     {
0430         return arg.elems;
0431     }
0432 
0433     template <size_t Idx, typename T, size_t N>
0434     BOOST_CXX14_CONSTEXPR T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT
0435     {
0436         BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
0437         return arr[Idx];
0438     }
0439 
0440     template <size_t Idx, typename T, size_t N>
0441     BOOST_CONSTEXPR const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT
0442     {
0443         BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" );
0444         return arr[Idx];
0445     }
0446 
0447     template<class T, std::size_t N>
0448     BOOST_CXX14_CONSTEXPR array<T, N> to_array( T const (&a)[ N ] )
0449     {
0450         array<T, N> r = {};
0451 
0452         for( std::size_t i = 0; i < N; ++i )
0453         {
0454             r[ i ] = a[ i ];
0455         }
0456 
0457         return r;
0458     }
0459 
0460 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0461 
0462     template<class T, std::size_t N>
0463     BOOST_CXX14_CONSTEXPR array<T, N> to_array( T (&&a)[ N ] )
0464     {
0465         array<T, N> r = {};
0466 
0467         for( std::size_t i = 0; i < N; ++i )
0468         {
0469             r[ i ] = std::move( a[ i ] );
0470         }
0471 
0472         return r;
0473     }
0474 
0475     template<class T, std::size_t N>
0476     BOOST_CXX14_CONSTEXPR array<T, N> to_array( T const (&&a)[ N ] )
0477     {
0478         array<T, N> r = {};
0479 
0480         for( std::size_t i = 0; i < N; ++i )
0481         {
0482             r[ i ] = a[ i ];
0483         }
0484 
0485         return r;
0486     }
0487 
0488 #endif
0489 
0490 } /* namespace boost */
0491 
0492 #ifndef BOOST_NO_CXX11_HDR_ARRAY
0493 //  If we don't have std::array, I'm assuming that we don't have std::get
0494 namespace std {
0495    template <size_t Idx, typename T, size_t N>
0496    BOOST_DEPRECATED( "please use `boost::get` instead" )
0497    T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
0498        BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
0499        return arr[Idx];
0500        }
0501 
0502    template <size_t Idx, typename T, size_t N>
0503    BOOST_DEPRECATED( "please use `boost::get` instead" )
0504    const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
0505        BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" );
0506        return arr[Idx];
0507        }
0508 }
0509 #endif
0510 
0511 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0512 # pragma warning(pop)
0513 #endif
0514 
0515 #endif // #ifndef BOOST_ARRAY_HPP_INCLUDED