Array
Boost.Array Library
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 * 9 Jan 2013 - (mtc) Added constexpr
17 * 14 Apr 2012 - (mtc) Added support for boost::hash
18 * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
19 * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
20 * See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168
21 * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow)
22 * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow)
23 * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)
24 * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
25 * 05 Aug 2001 - minor update (Nico Josuttis)
26 * 20 Jan 2001 - STLport fix (Beman Dawes)
27 * 29 Sep 2000 - Initial Revision (Nico Josuttis)
28 * 18 Nov 2021 - Added Javadocs (Alan de Freitas)
29 *
30 * Jan 29, 2004
31 */
32#ifndef BOOST_ARRAY_HPP
33#define BOOST_ARRAY_HPP
34
35#include <boost/detail/workaround.hpp>
36
37#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
38# pragma warning(push)
39# pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe
40# pragma warning(disable:4510) // boost::array<T,N>' : default constructor could not be generated
41# pragma warning(disable:4610) // warning C4610: class 'boost::array<T,N>' can never be instantiated - user defined constructor required
42#endif
43
44#include <cstddef>
45#include <iterator>
46#include <stdexcept>
47#include <boost/assert.hpp>
48#include <boost/static_assert.hpp>
49#include <boost/swap.hpp>
50
51#include <boost/throw_exception.hpp>
52#include <algorithm>
53
54// FIXES for broken compilers
55#include <boost/config.hpp>
56
57
58namespace boost {
59
86 template<class T, std::size_t N>
87 class array {
88 public:
90 T elems[N];
91
92 public:
95
97 typedef T value_type;
98
100 typedef T* iterator;
101
103 typedef const T* const_iterator;
104
106 typedef T& reference;
107
109 typedef const T& const_reference;
110
112 typedef std::size_t size_type;
113
115 typedef std::ptrdiff_t difference_type;
117
120
140 iterator begin() { return elems; }
141
163 const_iterator begin() const { return elems; }
164
188 const_iterator cbegin() const { return elems; }
189
190
211 iterator end() { return elems+N; }
212
235 const_iterator end() const { return elems+N; }
236
260 const_iterator cend() const { return elems+N; }
262
265
266 // reverse iterator support
267#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
269 typedef std::reverse_iterator<iterator> reverse_iterator;
270
272 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
273#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
274 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
276 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
278#else
279 // workaround for broken reverse_iterator implementations
280 typedef std::reverse_iterator<iterator,T> reverse_iterator;
281 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
282#endif
284
287
312
339 return const_reverse_iterator(end());
340 }
341
369 return const_reverse_iterator(end());
370 }
371
399
430 }
431
464 }
466
469
503 {
504 return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
505 }
506
541 /*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const
542 {
543 return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i];
544 }
545
575 reference at(size_type i) { return rangecheck(i), elems[i]; }
576
608 /*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; }
609
637 {
638 return elems[0];
639 }
640
669 BOOST_CONSTEXPR const_reference front() const
670 {
671 return elems[0];
672 }
673
701 {
702 return elems[N-1];
703 }
704
733 BOOST_CONSTEXPR const_reference back() const
734 {
735 return elems[N-1];
736 }
738
741
761 static BOOST_CONSTEXPR size_type size() { return N; }
762
782 static BOOST_CONSTEXPR bool empty() { return false; }
783
805 static BOOST_CONSTEXPR size_type max_size() { return N; }
806
808
809#ifndef BOOST_ARRAY_DOCS
811 enum { static_size = N };
812#endif // BOOST_ARRAY_DOCS
813
816
842 void swap (array<T,N>& y) {
843 for (size_type i = 0; i < N; ++i)
844 boost::swap(elems[i],y.elems[i]);
845 }
847
850
880 const T* data() const { return elems; }
881
909 T* data() { return elems; }
910
940 T* c_array() { return elems; }
942
945
962 template <typename T2>
964 std::copy(rhs.begin(),rhs.end(), begin());
965 return *this;
966 }
967
989 void assign (const T& value) { fill ( value ); }
990
1010 void fill (const T& value)
1011 {
1012 std::fill_n(begin(),size(),value);
1013 }
1015
1018
1044 static BOOST_CONSTEXPR bool rangecheck (size_type i) {
1045 return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true;
1046 }
1048 };
1049
1050#ifndef BOOST_ARRAY_DOCS
1051
1052 template< class T >
1053 class array< T, 0 > {
1054
1055 public:
1056 // type definitions
1057 typedef T value_type;
1058 typedef T* iterator;
1059 typedef const T* const_iterator;
1060 typedef T& reference;
1061 typedef const T& const_reference;
1062 typedef std::size_t size_type;
1063 typedef std::ptrdiff_t difference_type;
1064
1065 // iterator support
1066 iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
1067 const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
1068 const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
1069
1070 iterator end() { return begin(); }
1071 const_iterator end() const { return begin(); }
1072 const_iterator cend() const { return cbegin(); }
1073
1074 // reverse iterator support
1075#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
1076 typedef std::reverse_iterator<iterator> reverse_iterator;
1077 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1078#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
1079 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
1081 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
1083#else
1084 // workaround for broken reverse_iterator implementations
1085 typedef std::reverse_iterator<iterator,T> reverse_iterator;
1086 typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
1087#endif
1088
1091 return const_reverse_iterator(end());
1092 }
1094 return const_reverse_iterator(end());
1095 }
1096
1099 return const_reverse_iterator(begin());
1100 }
1102 return const_reverse_iterator(begin());
1103 }
1104
1105 // operator[]
1107 {
1108 return failed_rangecheck();
1109 }
1110
1111 /*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const
1112 {
1113 return failed_rangecheck();
1114 }
1115
1116 // at() with range check
1117 reference at(size_type /*i*/) { return failed_rangecheck(); }
1118 /*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); }
1119
1120 // front() and back()
1122 {
1123 return failed_rangecheck();
1124 }
1125
1126 BOOST_CONSTEXPR const_reference front() const
1127 {
1128 return failed_rangecheck();
1129 }
1130
1131 reference back()
1132 {
1133 return failed_rangecheck();
1134 }
1135
1136 BOOST_CONSTEXPR const_reference back() const
1137 {
1138 return failed_rangecheck();
1139 }
1140
1141 // size is constant
1142 static BOOST_CONSTEXPR size_type size() { return 0; }
1143 static BOOST_CONSTEXPR bool empty() { return true; }
1144 static BOOST_CONSTEXPR size_type max_size() { return 0; }
1145 enum { static_size = 0 };
1146
1147 void swap (array<T,0>& /*y*/) {
1148 }
1149
1150 // direct access to data (read-only)
1151 const T* data() const { return 0; }
1152 T* data() { return 0; }
1153
1154 // use array as C array (direct read/write access to data)
1155 T* c_array() { return 0; }
1156
1157 // assignment with type conversion
1158 template <typename T2>
1159 array<T,0>& operator= (const array<T2,0>& ) {
1160 return *this;
1161 }
1162
1163 // assign one value to all elements
1164 void assign (const T& value) { fill ( value ); }
1165 void fill (const T& ) {}
1166
1167 // check range (may be private because it is static)
1168 static reference failed_rangecheck () {
1169 std::out_of_range e("attempt to access element of an empty array");
1170 boost::throw_exception(e);
1171#if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__))
1172 //
1173 // We need to return something here to keep
1174 // some compilers happy: however we will never
1175 // actually get here....
1176 //
1177 static T placeholder;
1178 return placeholder;
1179#endif
1180 }
1181 };
1182#endif // BOOST_ARRAY_DOCS
1183
1186
1205 template<class T, std::size_t N>
1206 bool operator== (const array<T,N>& x, const array<T,N>& y) {
1207 return std::equal(x.begin(), x.end(), y.begin());
1208 }
1209
1229 template<class T, std::size_t N>
1230 bool operator< (const array<T,N>& x, const array<T,N>& y) {
1231 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
1232 }
1233
1253 template<class T, std::size_t N>
1254 bool operator!= (const array<T,N>& x, const array<T,N>& y) {
1255 return !(x==y);
1256 }
1257
1277 template<class T, std::size_t N>
1278 bool operator> (const array<T,N>& x, const array<T,N>& y) {
1279 return y<x;
1280 }
1281
1301 template<class T, std::size_t N>
1302 bool operator<= (const array<T,N>& x, const array<T,N>& y) {
1303 return !(y<x);
1304 }
1305
1325 template<class T, std::size_t N>
1326 bool operator>= (const array<T,N>& x, const array<T,N>& y) {
1327 return !(x<y);
1328 }
1330
1333
1353 template<class T, std::size_t N>
1354 inline void swap (array<T,N>& x, array<T,N>& y) {
1355 x.swap(y);
1356 }
1357
1358#if defined(__SUNPRO_CC)
1359// Trac ticket #4757; the Sun Solaris compiler can't handle
1360// syntax like 'T(&get_c_array(boost::array<T,N>& arg))[N]'
1361//
1362// We can't just use this for all compilers, because the
1363// borland compilers can't handle this form.
1364 namespace detail {
1365 template <typename T, std::size_t N> struct c_array
1366 {
1367 typedef T type[N];
1368 };
1369 }
1370
1371 // Specific for boost::array: simply returns its elems data member.
1372 template <typename T, std::size_t N>
1373 typename detail::c_array<T,N>::type& get_c_array(boost::array<T,N>& arg)
1374 {
1375 return arg.elems;
1376 }
1377
1378 // Specific for boost::array: simply returns its elems data member.
1379 template <typename T, std::size_t N>
1380 typename detail::c_array<T,N>::type const& get_c_array(const boost::array<T,N>& arg)
1381 {
1382 return arg.elems;
1383 }
1384#else
1385 // Specific for boost::array: simply returns its elems data member.
1386 template <typename T, std::size_t N>
1388 {
1389 return arg.elems;
1390 }
1391
1392 // Const version.
1393 template <typename T, std::size_t N>
1394 const T(&get_c_array(const boost::array<T,N>& arg))[N]
1395 {
1396 return arg.elems;
1397 }
1398#endif
1399
1400#if 0
1401 // Overload for std::array, assuming that std::array will have
1402 // explicit conversion functions as discussed at the WG21 meeting
1403 // in Summit, March 2009.
1404 template <typename T, std::size_t N>
1405 T(&get_c_array(std::array<T,N>& arg))[N]
1406 {
1407 return static_cast<T(&)[N]>(arg);
1408 }
1409
1410 // Const version.
1411 template <typename T, std::size_t N>
1412 const T(&get_c_array(const std::array<T,N>& arg))[N]
1413 {
1414 return static_cast<T(&)[N]>(arg);
1415 }
1416#endif
1417
1440 template <class It> std::size_t hash_range(It, It);
1441
1464 template<class T, std::size_t N>
1465 std::size_t hash_value(const array<T,N>& arr)
1466 {
1467 return boost::hash_range(arr.begin(), arr.end());
1468 }
1469
1500 template <size_t Idx, typename T, size_t N>
1501 T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
1502 BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
1503 return arr[Idx];
1504 }
1505
1537 template <size_t Idx, typename T, size_t N>
1538 const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
1539 BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" );
1540 return arr[Idx];
1541 }
1543} /* namespace boost */
1544
1545#ifndef BOOST_NO_CXX11_HDR_ARRAY
1546// If we don't have std::array, I'm assuming that we don't have std::get
1547namespace std {
1548 template <size_t Idx, typename T, size_t N>
1549 T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
1550 BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
1551 return arr[Idx];
1552 }
1553
1554 template <size_t Idx, typename T, size_t N>
1555 const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
1556 BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" );
1557 return arr[Idx];
1558 }
1559}
1560#endif
1561
1562#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
1563# pragma warning(pop)
1564#endif
1565
1566#endif /*BOOST_ARRAY_HPP*/
A container that encapsulates fixed size arrays.
Definition: array.hpp:87
T value_type
The array value type.
Definition: array.hpp:97
T elems[N]
Underlying fixed-size array of elements of type T.
Definition: array.hpp:90
static constexpr size_type size()
Returns the number of elements.
Definition: array.hpp:761
const_reverse_iterator rend() const
Returns a constant reverse iterator to the end.
Definition: array.hpp:428
constexpr const_reference back() const
Access the last array element.
Definition: array.hpp:733
reference back()
Access the last array element.
Definition: array.hpp:700
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: array.hpp:311
const_reverse_iterator rbegin() const
Returns a constant reverse iterator to the beginning.
Definition: array.hpp:338
std::size_t size_type
Type used to represent array size.
Definition: array.hpp:112
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition: array.hpp:398
void swap(array< T, N > &y)
Swaps the container contents.
Definition: array.hpp:842
const_reference operator[](size_type i) const
Access specified element.
Definition: array.hpp:541
void assign(const T &value)
Assign one value to all elements.
Definition: array.hpp:989
static constexpr bool rangecheck(size_type i)
Check range.
Definition: array.hpp:1044
void fill(const T &value)
Assign one value to all elements.
Definition: array.hpp:1010
static constexpr bool empty()
Checks whether the container is empty.
Definition: array.hpp:782
reference front()
Access the first array element.
Definition: array.hpp:636
T * data()
Direct access to the underlying array.
Definition: array.hpp:909
iterator begin()
Returns an iterator to the beginning.
Definition: array.hpp:140
const T * data() const
Direct access to the underlying array.
Definition: array.hpp:880
reference operator[](size_type i)
Access specified element.
Definition: array.hpp:502
const T & const_reference
Constant reference to value type.
Definition: array.hpp:109
const_reverse_iterator crend() const
Returns a constant reverse iterator to the end.
Definition: array.hpp:462
iterator end()
Returns an iterator to the end.
Definition: array.hpp:211
const_reference at(size_type i) const
Access specified element with bounds checking.
Definition: array.hpp:608
T * iterator
Iterator to C-style array, i.e. a pointer.
Definition: array.hpp:100
const T * const_iterator
Constant iterator to array, i.e. a pointer.
Definition: array.hpp:103
const_reverse_iterator crbegin() const
Returns a reverse iterator to the beginning.
Definition: array.hpp:368
array< T, N > & operator=(const array< T2, N > &rhs)
Overwrites element of the array with elements of another array.
Definition: array.hpp:963
std::reverse_iterator< iterator > reverse_iterator
Reverse array iterator - std::reverse_iterator<iterator>
Definition: array.hpp:269
const_iterator end() const
Returns a constant iterator to the end.
Definition: array.hpp:235
reference at(size_type i)
Access specified element with bounds checking.
Definition: array.hpp:575
std::reverse_iterator< const_iterator > const_reverse_iterator
Constant reverse array iterator - std::reverse_iterator<const_iterator>
Definition: array.hpp:272
static constexpr size_type max_size()
Returns the maximum possible number of elements.
Definition: array.hpp:805
const_iterator begin() const
Returns a constant iterator to the beginning.
Definition: array.hpp:163
std::ptrdiff_t difference_type
Type used to represent distance between iterators.
Definition: array.hpp:115
const_iterator cend() const
Returns a constant iterator to the end.
Definition: array.hpp:260
const_iterator cbegin() const
Returns a constant iterator to the beginning.
Definition: array.hpp:188
T & reference
Reference to value type.
Definition: array.hpp:106
constexpr const_reference front() const
Access the first array element.
Definition: array.hpp:669
T * c_array()
Direct access to the underlying array.
Definition: array.hpp:940
Definition: array.hpp:58
bool operator<=(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (operator<=)
Definition: array.hpp:1302
std::size_t hash_range(It, It)
Calculate combined hash value of the elements of an iterator range.
std::size_t hash_value(const array< T, N > &arr)
Calculate hash value for an array.
Definition: array.hpp:1465
bool operator==(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (.
Definition: array.hpp:1206
void swap(array< T, N > &x, array< T, N > &y)
Global swap function.
Definition: array.hpp:1354
T & get(boost::array< T, N > &arr) noexcept
Extracts the Ith element from the array.
Definition: array.hpp:1501
T(& get_c_array(boost::array< T, N > &arg))[N]
Definition: array.hpp:1387
bool operator>(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (operator>)
Definition: array.hpp:1278
bool operator!=(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (operator!=)
Definition: array.hpp:1254
bool operator<(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (operator<)
Definition: array.hpp:1230
bool operator>=(const array< T, N > &x, const array< T, N > &y)
Lexicographically compares the values in the array (operator>=)
Definition: array.hpp:1326
Definition: array.hpp:1547
T & get(boost::array< T, N > &arr) noexcept
Definition: array.hpp:1549