forked from boostorg/array
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd0532b8fa | |||
| 6a9e8c78da | |||
| 55bc631d40 | |||
| 435b293467 | |||
| 6447b408b2 | |||
| 17b49d86ad | |||
| fe60e163c7 | |||
| 16280f660b | |||
| 16b6ba8d84 | |||
| f5a3f1b34a | |||
| 9e2868f8e2 | |||
| 4f2ed73766 | |||
| b32a6cfcfd | |||
| 50cf6ebba7 | |||
| ec05d6ca34 | |||
| 18ec6239b2 | |||
| b44be8da89 | |||
| ea9dbd5674 | |||
| 5c05254afb | |||
| a211468866 | |||
| c06cadc04f | |||
| f155831795 | |||
| 7ca2f112a2 | |||
| 19f02c7615 | |||
| 66386e8eda | |||
| 54d839c8bc | |||
| e7663434ee | |||
| 52406dfcc0 | |||
| 9b8a342f44 |
+2
-2
@@ -6,7 +6,7 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
https://www.boost.org/LICENSE_1_0.txt
|
https://www.boost.org/LICENSE_1_0.txt
|
||||||
////
|
////
|
||||||
|
|
||||||
# Array
|
# Boost.Array
|
||||||
Nicolai M. Josuttis
|
Nicolai M. Josuttis
|
||||||
:toc: left
|
:toc: left
|
||||||
:toclevels: 4
|
:toclevels: 4
|
||||||
@@ -18,8 +18,8 @@ Nicolai M. Josuttis
|
|||||||
|
|
||||||
:leveloffset: +1
|
:leveloffset: +1
|
||||||
|
|
||||||
|
|
||||||
include::array/introduction.adoc[]
|
include::array/introduction.adoc[]
|
||||||
|
include::array/changes.adoc[]
|
||||||
include::array/reference.adoc[]
|
include::array/reference.adoc[]
|
||||||
include::array/design_rationale.adoc[]
|
include::array/design_rationale.adoc[]
|
||||||
include::array/information.adoc[]
|
include::array/information.adoc[]
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
////
|
||||||
|
Copyright 2025 Peter Dimov
|
||||||
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
|
http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
////
|
||||||
|
|
||||||
|
[#changes]
|
||||||
|
# Revision History
|
||||||
|
:toc:
|
||||||
|
:toc-title:
|
||||||
|
:idprefix:
|
||||||
|
|
||||||
|
## Changes in 1.88.0
|
||||||
|
|
||||||
|
* Converted documentation to AsciiDoc (Christian Mazakas).
|
||||||
|
* Added `noexcept` and `constexpr` as appropriate.
|
||||||
@@ -12,4 +12,4 @@ Copyright (C) 2001-2004 Nicolai M. Josuttis
|
|||||||
|
|
||||||
Copyright (C) 2012 Marshall Clow
|
Copyright (C) 2012 Marshall Clow
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Distributed under the https://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
|
||||||
|
|||||||
@@ -37,7 +37,3 @@ Note that for standard conforming compilers it is possible to use fewer braces (
|
|||||||
```cpp
|
```cpp
|
||||||
boost::array<int,4> a = { 1, 2, 3 };
|
boost::array<int,4> a = { 1, 2, 3 };
|
||||||
```
|
```
|
||||||
|
|
||||||
I'd appreciate any constructive feedback. **Please note: I don't have time to read all boost mails. Thus, to make sure that feedback arrives to me, please send me a copy of each mail regarding this class.**
|
|
||||||
|
|
||||||
The code is provided "as is" without expressed or implied warranty.
|
|
||||||
|
|||||||
@@ -11,11 +11,18 @@ https://www.boost.org/LICENSE_1_0.txt
|
|||||||
:idprefix: introduction_
|
:idprefix: introduction_
|
||||||
:cpp: C++
|
:cpp: C++
|
||||||
|
|
||||||
The {cpp} Standard Template Library STL as part of the {cpp} Standard Library provides a framework for processing algorithms on different kind of containers. However, ordinary arrays don't provide the interface of STL containers (although, they provide the iterator interface of STL containers).
|
The {cpp} Standard Template Library STL as part of the {cpp} Standard Library provides a framework for processing algorithms on different kind of containers.
|
||||||
|
However, ordinary arrays don't provide the interface of STL containers (although, they provide the iterator interface of STL containers).
|
||||||
|
|
||||||
As replacement for ordinary arrays, the STL provides class `std::vector`. However, `std::vector<>` provides the semantics of dynamic arrays. Thus, it manages data to be able to change the number of elements. This results in some overhead in case only arrays with static size are needed.
|
As replacement for ordinary arrays, the STL provides class `std::vector`.
|
||||||
|
However, `std::vector<>` provides the semantics of dynamic arrays.
|
||||||
|
Thus, it manages data to be able to change the number of elements.
|
||||||
|
This results in some overhead in case only arrays with static size are needed.
|
||||||
|
|
||||||
In his book, _Generic Programming and the STL_, Matthew H. Austern introduces a useful wrapper class for ordinary arrays with static size, called `block`. It is safer and has no worse performance than ordinary arrays. In _The {cpp} Programming Language_, 3rd edition, Bjarne Stroustrup introduces a similar class, called c_array, which I (http://www.josuttis.com/[Nicolai Josuttis]) present slightly modified in my book _The {cpp} Standard Library - A Tutorial and Reference_, called `carray`. This is the essence of these approaches spiced with many feedback from https://www.boost.org/[boost].
|
In his book, _Generic Programming and the STL_, Matthew H. Austern introduces a useful wrapper class for ordinary arrays with static size, called `block`.
|
||||||
|
It is safer and has no worse performance than ordinary arrays.
|
||||||
|
In _The {cpp} Programming Language_, 3rd edition, Bjarne Stroustrup introduces a similar class, called c_array, which I (http://www.josuttis.com/[Nicolai Josuttis]) present slightly modified in my book _The {cpp} Standard Library - A Tutorial and Reference_, called `carray`.
|
||||||
|
This is the essence of these approaches spiced with many feedback from https://www.boost.org/[Boost].
|
||||||
|
|
||||||
After considering different names, we decided to name this class simply `array`.
|
After considering different names, we decided to name this class simply `array`.
|
||||||
|
|
||||||
|
|||||||
+163
-176
@@ -15,24 +15,30 @@ https://www.boost.org/LICENSE_1_0.txt
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<typename T, std::size_t N> class array;
|
template<typename T, std::size_t N> class array;
|
||||||
template<typename T, std::size_t N> void swap(array<T, N>&, array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator==(const array<T, N>&, const array<T, N>&);
|
void swap(array<T, N>&, array<T, N>&);
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator!=(const array<T, N>&, const array<T, N>&);
|
constexpr bool operator==(const array<T, N>&, const array<T, N>&);
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator<(const array<T, N>&, const array<T, N>&);
|
constexpr bool operator!=(const array<T, N>&, const array<T, N>&);
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator>(const array<T, N>&, const array<T, N>&);
|
constexpr bool operator<(const array<T, N>&, const array<T, N>&);
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator<=(const array<T, N>&, const array<T, N>&);
|
constexpr bool operator>(const array<T, N>&, const array<T, N>&);
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator>=(const array<T, N>&, const array<T, N>&);
|
constexpr bool operator<=(const array<T, N>&, const array<T, N>&);
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
template<typename T, std::size_t N>
|
||||||
T boost::get(array<T, N>&);
|
constexpr bool operator>=(const array<T, N>&, const array<T, N>&);
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
|
||||||
T boost::get(const array<T, N>&);
|
template<std::size_t Idx, typename T, std::size_t N>
|
||||||
|
constexpr T& get(array<T, N>&) noexcept;
|
||||||
|
template<std::size_t Idx, typename T, std::size_t N>
|
||||||
|
constexpr const T& get(const array<T, N>&) noexcept;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -46,7 +52,9 @@ namespace boost {
|
|||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
class array {
|
class array {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// types
|
// types
|
||||||
|
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef T* iterator;
|
typedef T* iterator;
|
||||||
typedef const T* const_iterator;
|
typedef const T* const_iterator;
|
||||||
@@ -58,361 +66,340 @@ public:
|
|||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
// static constants
|
// static constants
|
||||||
|
|
||||||
static const size_type static_size = N;
|
static const size_type static_size = N;
|
||||||
|
|
||||||
// construct/copy/destruct
|
// construct/copy/destroy
|
||||||
|
|
||||||
template<typename U> array& operator=(const array<U, N>&);
|
template<typename U> array& operator=(const array<U, N>&);
|
||||||
|
|
||||||
// iterator support
|
// iterator support
|
||||||
iterator begin();
|
|
||||||
const_iterator begin() const;
|
constexpr iterator begin() noexcept;
|
||||||
iterator end();
|
constexpr const_iterator begin() const noexcept;
|
||||||
const_iterator end() const;
|
constexpr const_iterator cbegin() const noexcept;
|
||||||
const_iterator cbegin();
|
|
||||||
const_iterator cend();
|
constexpr iterator end() noexcept;
|
||||||
|
constexpr const_iterator end() const noexcept;
|
||||||
|
constexpr const_iterator cend() const noexcept;
|
||||||
|
|
||||||
// reverse iterator support
|
// reverse iterator support
|
||||||
reverse_iterator rbegin();
|
|
||||||
const_reverse_iterator rbegin() const;
|
reverse_iterator rbegin() noexcept;
|
||||||
reverse_iterator rend();
|
const_reverse_iterator rbegin() const noexcept;
|
||||||
const_reverse_iterator rend() const;
|
const_reverse_iterator crbegin() const noexcept;
|
||||||
const_reverse_iterator crbegin();
|
|
||||||
const_reverse_iterator crend();
|
reverse_iterator rend() noexcept;
|
||||||
|
const_reverse_iterator rend() const noexcept;
|
||||||
|
const_reverse_iterator crend() const noexcept;
|
||||||
|
|
||||||
// capacity
|
// capacity
|
||||||
size_type size();
|
|
||||||
bool empty();
|
static constexpr size_type size() noexcept;
|
||||||
size_type max_size();
|
static constexpr bool empty() noexcept;
|
||||||
|
static constexpr size_type max_size() noexcept;
|
||||||
|
|
||||||
// element access
|
// element access
|
||||||
reference operator[](size_type);
|
|
||||||
const_reference operator[](size_type) const;
|
constexpr reference operator[](size_type);
|
||||||
reference at(size_type);
|
constexpr const_reference operator[](size_type) const;
|
||||||
const_reference at(size_type) const;
|
|
||||||
reference front();
|
constexpr reference at(size_type);
|
||||||
const_reference front() const;
|
constexpr const_reference at(size_type) const;
|
||||||
reference back();
|
|
||||||
const_reference back() const;
|
constexpr reference front();
|
||||||
const T* data() const;
|
constexpr const_reference front() const;
|
||||||
T* c_array();
|
|
||||||
|
constexpr reference back();
|
||||||
|
constexpr const_reference back() const;
|
||||||
|
|
||||||
|
constexpr T* data() noexcept;
|
||||||
|
constexpr const T* data() const noexcept;
|
||||||
|
|
||||||
|
T* c_array() noexcept; // deprecated
|
||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
void swap(array<T, N>&);
|
|
||||||
void assign(const T&);
|
swap(array<T, N>&);
|
||||||
|
|
||||||
|
constexpr void fill(const T&);
|
||||||
|
void assign(const T&); // deprecated
|
||||||
|
|
||||||
// public data members
|
// public data members
|
||||||
T elems[N];
|
T elems[N];
|
||||||
};
|
};
|
||||||
|
|
||||||
// specialized algorithms
|
|
||||||
template<typename T, std::size_t N> void swap(array<T, N>&, array<T, N>&);
|
|
||||||
|
|
||||||
// comparisons
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator==(const array<T, N>&, const array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator!=(const array<T, N>&, const array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator<(const array<T, N>&, const array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator>(const array<T, N>&, const array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator<=(const array<T, N>&, const array<T, N>&);
|
|
||||||
template<typename T, std::size_t N>
|
|
||||||
bool operator>=(const array<T, N>&, const array<T, N>&);
|
|
||||||
|
|
||||||
// specializations
|
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
|
||||||
T boost::get(array<T, N>&);
|
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
|
||||||
T boost::get(const array<T, N>&);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Description
|
### Construct/Copy/Destroy
|
||||||
|
|
||||||
#### array public construct/copy/destruct
|
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename U> array& operator=(const array<U, N>& other);
|
template<typename U> array& operator=(const array<U, N>& other);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Effects: :: `std::copy(rhs.begin(), rhs.end(), begin())`
|
Effects: :: `std::copy(rhs.begin(), rhs.end(), begin())`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array iterator support
|
### Iterator Support
|
||||||
|
|
||||||
```
|
```
|
||||||
iterator begin();
|
constexpr iterator begin() noexcept;
|
||||||
const_iterator begin() const;
|
constexpr const_iterator begin() const noexcept;
|
||||||
|
constexpr const_iterator cbegin() const noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: iterator for the first element
|
Returns: :: `data()`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
iterator end();
|
constexpr iterator end() noexcept;
|
||||||
const_iterator end() const;
|
constexpr const_iterator end() const noexcept;
|
||||||
|
constexpr const_iterator cend() const noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: iterator for position after the last element
|
Returns: :: `data() + size()`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Reverse Iterator Support
|
||||||
|
|
||||||
```
|
```
|
||||||
const_iterator cbegin();
|
reverse_iterator rbegin() noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: constant iterator for the first element
|
Returns: :: `reverse_iterator(end())`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
const_iterator cend();
|
const_reverse_iterator rbegin() const noexcept;
|
||||||
|
const_reverse_iterator crbegin() const noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: constant iterator for position after the last element
|
Returns: :: `const_reverse_iterator(end())`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array reverse iterator support
|
|
||||||
|
|
||||||
```
|
```
|
||||||
reverse_iterator rbegin();
|
reverse_iterator rend() noexcept;
|
||||||
const_reverse_iterator rbegin() const;
|
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: reverse iterator for the first element of reverse iteration
|
Returns: :: `reverse_iterator(begin())`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
reverse_iterator rend();
|
const_reverse_iterator rend() const noexcept;
|
||||||
const_reverse_iterator rend() const;
|
const_reverse_iterator crend() const noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: reverse iterator for position after the last element in reverse iteration
|
Returns: :: `const_reverse_iterator(begin())`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Capacity
|
||||||
|
|
||||||
```
|
```
|
||||||
const_reverse_iterator crbegin();
|
static constexpr size_type size() noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: constant reverse iterator for the first element of reverse iteration
|
Returns: :: `N`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
const_reverse_iterator crend();
|
static constexpr bool empty() noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: constant reverse iterator for position after the last element in reverse iteration
|
Returns: :: `N == 0`.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array capacity
|
|
||||||
|
|
||||||
```
|
```
|
||||||
size_type size();
|
static constexpr size_type max_size() noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `N`
|
Returns: :: `N`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Element Access
|
||||||
|
|
||||||
```
|
```
|
||||||
bool empty();
|
constexpr reference operator[](size_type i);
|
||||||
|
constexpr const_reference operator[](size_type i) const;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `N==0`
|
Requires: :: `i < N`.
|
||||||
Throws: :: will not throw
|
Returns: :: `elems[i]`.
|
||||||
|
Throws: :: nothing.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
size_type max_size();
|
constexpr reference at(size_type i);
|
||||||
|
constexpr const_reference at(size_type i) const;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `N`
|
Returns: :: `elems[i]`.
|
||||||
Throws: :: will not throw
|
Throws: :: `std::out_of_range` if `i >= N`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array element access
|
|
||||||
|
|
||||||
```
|
```
|
||||||
reference operator[](size_type i);
|
constexpr reference front();
|
||||||
const_reference operator[](size_type i) const;
|
constexpr const_reference front() const;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Requires: :: `i < N`
|
Requires: :: `N > 0`.
|
||||||
Returns: :: element with index `i`
|
Returns: :: `elems[0]`.
|
||||||
Throws: :: will not throw.
|
Throws: :: nothing.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
reference at(size_type i);
|
constexpr reference back();
|
||||||
const_reference at(size_type i) const;
|
constexpr const_reference back() const;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: element with index `i`
|
Requires: :: `N > 0`.
|
||||||
Throws: :: `std::range_error` if `i >= N`
|
Returns: :: `elems[N-1]`.
|
||||||
|
Throws: :: nothing.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
reference front();
|
constexpr T* data() noexcept;
|
||||||
const_reference front() const;
|
constexpr const T* data() const noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Requires: :: `N > 0`
|
Returns: :: `elems`.
|
||||||
Returns: :: the first element
|
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
reference back();
|
T* c_array() noexcept; // deprecated
|
||||||
const_reference back() const;
|
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Requires: :: `N > 0`
|
Returns: :: `data()`.
|
||||||
Returns: :: the last element
|
Remarks: :: This function is deprecated. Use `data()` instead.
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
### Modifiers
|
||||||
const T* data() const;
|
|
||||||
```
|
|
||||||
[horizontal]
|
|
||||||
Returns: :: `elems`
|
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
```
|
|
||||||
T* c_array();
|
|
||||||
```
|
|
||||||
[horizontal]
|
|
||||||
Returns: :: `elems`
|
|
||||||
Throws: :: will not throw
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
#### array modifiers
|
|
||||||
|
|
||||||
```
|
```
|
||||||
void swap(array<T, N>& other);
|
void swap(array<T, N>& other);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Effects: :: `std::swap_ranges(begin(), end(), other.begin())`
|
Effects: :: `std::swap(elems, other.elems)`.
|
||||||
Complexity: :: linear in `N`
|
Complexity: :: linear in `N`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
void assign(const T& value);
|
void fill(const T& value);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Effects: :: `std::fill_n(begin(), N, value)`
|
Effects: :: for each `i` in `[0..N)`, performs `elems[i] = value;`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array specialized algorithms
|
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N> void swap(array<T, N>& x, array<T, N>& y);
|
void assign(const T& value); // deprecated
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Effects: :: `x.swap(y)`
|
Effects: :: `fill(value)`.
|
||||||
Throws: :: will not throw.
|
Remarks: :: An obsolete and deprecated spelling of `fill`. Use `fill` instead.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array comparisons
|
### Specialized Algorithms
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator==(const array<T, N>& x, const array<T, N>& y);
|
void swap(array<T, N>& x, array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `std::equal(x.begin(), x.end(), y.begin())`
|
Effects: :: `x.swap(y)`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Comparisons
|
||||||
|
|
||||||
|
```
|
||||||
|
template<typename T, std::size_t N>
|
||||||
|
constexpr bool operator==(const array<T, N>& x, const array<T, N>& y);
|
||||||
|
```
|
||||||
|
[horizontal]
|
||||||
|
Returns: :: `std::equal(x.begin(), x.end(), y.begin())`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator!=(const array<T, N>& x, const array<T, N>& y);
|
constexpr bool operator!=(const array<T, N>& x, const array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `!(x == y)`
|
Returns: :: `!(x == y)`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator<(const array<T, N>& x, const array<T, N>& y);
|
constexpr bool operator<(const array<T, N>& x, const array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end())`
|
Returns: :: `std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end())`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator>(const array<T, N>& x, const array<T, N>& y);
|
constexpr bool operator>(const array<T, N>& x, const array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `y < x`
|
Returns: :: `y < x`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator<=(const array<T, N>& x, const array<T, N>& y);
|
constexpr bool operator<=(const array<T, N>& x, const array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `!(y < x)`
|
Returns: :: `!(y < x)`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
bool operator>=(const array<T, N>& x, const array<T, N>& y);
|
constexpr bool operator>=(const array<T, N>& x, const array<T, N>& y);
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: `!(x < y)`
|
Returns: :: `!(x < y)`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
#### array specializations
|
### Specializations
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
template<std::size_t Idx, typename T, std::size_t N>
|
||||||
T boost::get(array<T, N>& arr);
|
constexpr T& get(array<T, N>& arr) noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: element of array with index `Idx`
|
Mandates: :: `Idx < N`.
|
||||||
Effects: :: Will `static_assert` if `Idx >= N`
|
Returns: :: `arr[Idx]`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```
|
```
|
||||||
template<typename T, std::size_t N, std::size_t Idx>
|
template<std::size_t Idx, typename T, std::size_t N>
|
||||||
T boost::get(const array<T, N>& arr);
|
constexpr const T& get(const array<T, N>& arr) noexcept;
|
||||||
```
|
```
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Returns: :: const element of array with index `Idx`
|
Mandates: :: `Idx < N`.
|
||||||
Effects: :: Will `static_assert` if `Idx >= N`
|
Returns: :: `arr[Idx]`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+99
-104
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef BOOST_ARRAY_HPP_INCLUDED
|
||||||
|
#define BOOST_ARRAY_HPP_INCLUDED
|
||||||
|
|
||||||
/* The following code declares class array,
|
/* The following code declares class array,
|
||||||
* an STL container (as wrapper) for arrays of constant size.
|
* an STL container (as wrapper) for arrays of constant size.
|
||||||
*
|
*
|
||||||
@@ -28,29 +31,24 @@
|
|||||||
*
|
*
|
||||||
* Jan 29, 2004
|
* Jan 29, 2004
|
||||||
*/
|
*/
|
||||||
#ifndef BOOST_ARRAY_HPP
|
|
||||||
#define BOOST_ARRAY_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/config/workaround.hpp>
|
#include <boost/config/workaround.hpp>
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||||
# pragma warning(push)
|
# pragma warning(push)
|
||||||
# pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe
|
|
||||||
# pragma warning(disable:4510) // boost::array<T,N>' : default constructor could not be generated
|
# pragma warning(disable:4510) // boost::array<T,N>' : default constructor could not be generated
|
||||||
# pragma warning(disable:4610) // warning C4610: class 'boost::array<T,N>' can never be instantiated - user defined constructor required
|
# pragma warning(disable:4512) // boost::array<T,N>' : assignment operator could not be generated
|
||||||
|
# pragma warning(disable:4610) // class 'boost::array<T,N>' can never be instantiated - user defined constructor required
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstddef>
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <boost/assert.hpp>
|
#include <utility>
|
||||||
#include <boost/core/invoke_swap.hpp>
|
#include <cstddef>
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
#include <boost/throw_exception.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
@@ -79,19 +77,8 @@ namespace boost {
|
|||||||
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return elems+N; }
|
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return elems+N; }
|
||||||
|
|
||||||
// reverse iterator support
|
// reverse iterator support
|
||||||
#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
|
||||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
|
||||||
typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
|
|
||||||
value_type, reference, iterator, difference_type> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
|
|
||||||
value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
|
|
||||||
#else
|
|
||||||
// workaround for broken reverse_iterator implementations
|
|
||||||
typedef std::reverse_iterator<iterator,T> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
|
reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
|
||||||
const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
|
const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
|
||||||
@@ -155,31 +142,49 @@ namespace boost {
|
|||||||
enum { static_size = N };
|
enum { static_size = N };
|
||||||
|
|
||||||
// swap (note: linear complexity)
|
// swap (note: linear complexity)
|
||||||
BOOST_CXX14_CONSTEXPR void swap (array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR void swap (array<T,N>& y)
|
||||||
for (size_type i = 0; i < N; ++i)
|
{
|
||||||
boost::core::invoke_swap(elems[i],y.elems[i]);
|
std::swap( elems, y.elems );
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct access to data (read-only)
|
// direct access to data
|
||||||
BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return elems; }
|
BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return elems; }
|
||||||
BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return elems; }
|
BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return elems; }
|
||||||
|
|
||||||
// use array as C array (direct read/write access to data)
|
// obsolete
|
||||||
|
BOOST_DEPRECATED( "please use `data()` instead" )
|
||||||
T* c_array() BOOST_NOEXCEPT { return elems; }
|
T* c_array() BOOST_NOEXCEPT { return elems; }
|
||||||
|
|
||||||
// assignment with type conversion
|
// assignment with type conversion
|
||||||
template <typename T2>
|
template <typename T2>
|
||||||
array<T,N>& operator= (const array<T2,N>& rhs) {
|
array<T,N>& operator= (const array<T2,N>& rhs)
|
||||||
std::copy(rhs.begin(),rhs.end(), begin());
|
{
|
||||||
|
for( std::size_t i = 0; i < N; ++i )
|
||||||
|
{
|
||||||
|
elems[ i ] = rhs.elems[ i ];
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign one value to all elements
|
// fill with one value
|
||||||
void assign (const T& value) { fill ( value ); } // A synonym for fill
|
|
||||||
BOOST_CXX14_CONSTEXPR void fill (const T& value)
|
BOOST_CXX14_CONSTEXPR void fill (const T& value)
|
||||||
{
|
{
|
||||||
std::fill_n(begin(),size(),value);
|
// using elems[ 0 ] as a temporary copy
|
||||||
|
// avoids the aliasing opportunity betw.
|
||||||
|
// `value` and `elems`
|
||||||
|
|
||||||
|
elems[ 0 ] = value;
|
||||||
|
|
||||||
|
for( std::size_t i = 1; i < N; ++i )
|
||||||
|
{
|
||||||
|
elems[ i ] = elems[ 0 ];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// an obsolete synonym for fill
|
||||||
|
BOOST_DEPRECATED( "please use `fill` instead" )
|
||||||
|
void assign (const T& value) { fill ( value ); }
|
||||||
|
|
||||||
// check range (may be private because it is static)
|
// check range (may be private because it is static)
|
||||||
static BOOST_CONSTEXPR bool rangecheck (size_type i) {
|
static BOOST_CONSTEXPR bool rangecheck (size_type i) {
|
||||||
@@ -211,19 +216,8 @@ namespace boost {
|
|||||||
const_iterator cend() const BOOST_NOEXCEPT { return cbegin(); }
|
const_iterator cend() const BOOST_NOEXCEPT { return cbegin(); }
|
||||||
|
|
||||||
// reverse iterator support
|
// reverse iterator support
|
||||||
#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
|
|
||||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
|
|
||||||
typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
|
|
||||||
value_type, reference, iterator, difference_type> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
|
|
||||||
value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
|
|
||||||
#else
|
|
||||||
// workaround for broken reverse_iterator implementations
|
|
||||||
typedef std::reverse_iterator<iterator,T> reverse_iterator;
|
|
||||||
typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
|
reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
|
||||||
const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
|
const_reverse_iterator rbegin() const BOOST_NOEXCEPT {
|
||||||
@@ -283,14 +277,16 @@ namespace boost {
|
|||||||
static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return 0; }
|
static BOOST_CONSTEXPR size_type max_size() BOOST_NOEXCEPT { return 0; }
|
||||||
enum { static_size = 0 };
|
enum { static_size = 0 };
|
||||||
|
|
||||||
void swap (array<T,0>& /*y*/) {
|
BOOST_CXX14_CONSTEXPR void swap (array<T,0>& /*y*/)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct access to data (read-only)
|
// direct access to data
|
||||||
BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return 0; }
|
BOOST_CONSTEXPR const T* data() const BOOST_NOEXCEPT { return 0; }
|
||||||
BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return 0; }
|
BOOST_CXX14_CONSTEXPR T* data() BOOST_NOEXCEPT { return 0; }
|
||||||
|
|
||||||
// use array as C array (direct read/write access to data)
|
// obsolete
|
||||||
|
BOOST_DEPRECATED( "please use `data()` instead" )
|
||||||
T* c_array() BOOST_NOEXCEPT { return 0; }
|
T* c_array() BOOST_NOEXCEPT { return 0; }
|
||||||
|
|
||||||
// assignment with type conversion
|
// assignment with type conversion
|
||||||
@@ -299,8 +295,11 @@ namespace boost {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign one value to all elements
|
// an obsolete synonym for fill
|
||||||
|
BOOST_DEPRECATED( "please use `fill` instead" )
|
||||||
void assign (const T& value) { fill ( value ); }
|
void assign (const T& value) { fill ( value ); }
|
||||||
|
|
||||||
|
// fill with one value
|
||||||
BOOST_CXX14_CONSTEXPR void fill (const T& ) {}
|
BOOST_CXX14_CONSTEXPR void fill (const T& ) {}
|
||||||
|
|
||||||
// check range (may be private because it is static)
|
// check range (may be private because it is static)
|
||||||
@@ -321,25 +320,63 @@ namespace boost {
|
|||||||
|
|
||||||
// comparisons
|
// comparisons
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
BOOST_CXX14_CONSTEXPR bool operator== (const array<T,N>& x, const array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR bool operator== (const array<T,N>& x, const array<T,N>& y)
|
||||||
return std::equal(x.begin(), x.end(), y.begin());
|
{
|
||||||
|
for( std::size_t i = 0; i < N; ++i )
|
||||||
|
{
|
||||||
|
if( !( x[ i ] == y[ i ] ) ) return false;
|
||||||
}
|
}
|
||||||
template<class T, std::size_t N>
|
|
||||||
BOOST_CXX14_CONSTEXPR bool operator< (const array<T,N>& x, const array<T,N>& y) {
|
return true;
|
||||||
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_GCC, < 90000)
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
BOOST_CXX14_CONSTEXPR bool operator== (const array<T, 0>& x, const array<T, 0>& y)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
BOOST_CXX14_CONSTEXPR bool operator!= (const array<T,N>& x, const array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR bool operator!= (const array<T,N>& x, const array<T,N>& y) {
|
||||||
return !(x==y);
|
return !(x==y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, std::size_t N>
|
||||||
|
BOOST_CXX14_CONSTEXPR bool operator< (const array<T,N>& x, const array<T,N>& y)
|
||||||
|
{
|
||||||
|
for( std::size_t i = 0; i < N; ++i )
|
||||||
|
{
|
||||||
|
if( x[ i ] < y[ i ] ) return true;
|
||||||
|
if( y[ i ] < x[ i ] ) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_GCC, < 90000)
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
BOOST_CXX14_CONSTEXPR bool operator< (const array<T, 0>& x, const array<T, 0>& y)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
BOOST_CXX14_CONSTEXPR bool operator> (const array<T,N>& x, const array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR bool operator> (const array<T,N>& x, const array<T,N>& y) {
|
||||||
return y<x;
|
return y<x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
BOOST_CXX14_CONSTEXPR bool operator<= (const array<T,N>& x, const array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR bool operator<= (const array<T,N>& x, const array<T,N>& y) {
|
||||||
return !(y<x);
|
return !(y<x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
BOOST_CXX14_CONSTEXPR bool operator>= (const array<T,N>& x, const array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR bool operator>= (const array<T,N>& x, const array<T,N>& y) {
|
||||||
return !(x<y);
|
return !(x<y);
|
||||||
@@ -347,39 +384,13 @@ namespace boost {
|
|||||||
|
|
||||||
// global swap()
|
// global swap()
|
||||||
template<class T, std::size_t N>
|
template<class T, std::size_t N>
|
||||||
inline void swap (array<T,N>& x, array<T,N>& y) {
|
BOOST_CXX14_CONSTEXPR inline void swap (array<T,N>& x, array<T,N>& y) {
|
||||||
x.swap(y);
|
x.swap(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__SUNPRO_CC)
|
// undocumented and obsolete
|
||||||
// Trac ticket #4757; the Sun Solaris compiler can't handle
|
|
||||||
// syntax like 'T(&get_c_array(boost::array<T,N>& arg))[N]'
|
|
||||||
//
|
|
||||||
// We can't just use this for all compilers, because the
|
|
||||||
// borland compilers can't handle this form.
|
|
||||||
namespace detail {
|
|
||||||
template <typename T, std::size_t N> struct c_array
|
|
||||||
{
|
|
||||||
typedef T type[N];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific for boost::array: simply returns its elems data member.
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
typename detail::c_array<T,N>::type& get_c_array(boost::array<T,N>& arg)
|
|
||||||
{
|
|
||||||
return arg.elems;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific for boost::array: simply returns its elems data member.
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
typename detail::c_array<T,N>::type const& get_c_array(const boost::array<T,N>& arg)
|
|
||||||
{
|
|
||||||
return arg.elems;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Specific for boost::array: simply returns its elems data member.
|
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
|
BOOST_DEPRECATED( "please use `elems` instead" )
|
||||||
T(&get_c_array(boost::array<T,N>& arg))[N]
|
T(&get_c_array(boost::array<T,N>& arg))[N]
|
||||||
{
|
{
|
||||||
return arg.elems;
|
return arg.elems;
|
||||||
@@ -387,29 +398,11 @@ namespace boost {
|
|||||||
|
|
||||||
// Const version.
|
// Const version.
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
|
BOOST_DEPRECATED( "please use `elems` instead" )
|
||||||
const T(&get_c_array(const boost::array<T,N>& arg))[N]
|
const T(&get_c_array(const boost::array<T,N>& arg))[N]
|
||||||
{
|
{
|
||||||
return arg.elems;
|
return arg.elems;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Overload for std::array, assuming that std::array will have
|
|
||||||
// explicit conversion functions as discussed at the WG21 meeting
|
|
||||||
// in Summit, March 2009.
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
T(&get_c_array(std::array<T,N>& arg))[N]
|
|
||||||
{
|
|
||||||
return static_cast<T(&)[N]>(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Const version.
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
const T(&get_c_array(const std::array<T,N>& arg))[N]
|
|
||||||
{
|
|
||||||
return static_cast<T(&)[N]>(arg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class It> std::size_t hash_range(It, It);
|
template <class It> std::size_t hash_range(It, It);
|
||||||
|
|
||||||
@@ -420,13 +413,13 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <size_t Idx, typename T, size_t N>
|
template <size_t Idx, typename T, size_t N>
|
||||||
T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
BOOST_CXX14_CONSTEXPR T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
||||||
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
|
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
|
||||||
return arr[Idx];
|
return arr[Idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t Idx, typename T, size_t N>
|
template <size_t Idx, typename T, size_t N>
|
||||||
const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
BOOST_CONSTEXPR const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
||||||
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" );
|
BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" );
|
||||||
return arr[Idx];
|
return arr[Idx];
|
||||||
}
|
}
|
||||||
@@ -437,12 +430,14 @@ namespace boost {
|
|||||||
// If we don't have std::array, I'm assuming that we don't have std::get
|
// If we don't have std::array, I'm assuming that we don't have std::get
|
||||||
namespace std {
|
namespace std {
|
||||||
template <size_t Idx, typename T, size_t N>
|
template <size_t Idx, typename T, size_t N>
|
||||||
|
BOOST_DEPRECATED( "please use `boost::get` instead" )
|
||||||
T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
||||||
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
|
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
|
||||||
return arr[Idx];
|
return arr[Idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t Idx, typename T, size_t N>
|
template <size_t Idx, typename T, size_t N>
|
||||||
|
BOOST_DEPRECATED( "please use `boost::get` instead" )
|
||||||
const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT {
|
||||||
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" );
|
BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" );
|
||||||
return arr[Idx];
|
return arr[Idx];
|
||||||
@@ -454,4 +449,4 @@ namespace std {
|
|||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*BOOST_ARRAY_HPP*/
|
#endif // #ifndef BOOST_ARRAY_HPP_INCLUDED
|
||||||
|
|||||||
@@ -47,6 +47,21 @@ run array_eq_test.cpp ;
|
|||||||
run array_lt_test.cpp ;
|
run array_lt_test.cpp ;
|
||||||
run array_get_test.cpp ;
|
run array_get_test.cpp ;
|
||||||
|
|
||||||
|
# C++11 constexpr
|
||||||
|
|
||||||
|
compile array_init_test_cx.cpp ;
|
||||||
|
compile array_copy_test_cx.cpp ;
|
||||||
|
compile array_data_test_cx.cpp ;
|
||||||
|
compile array_iterator_test_cx.cpp ;
|
||||||
|
compile array_size_test_cx.cpp ;
|
||||||
|
compile array_access_test_cx.cpp ;
|
||||||
|
compile array_get_test_cx.cpp ;
|
||||||
|
|
||||||
|
# C++14 constexpr
|
||||||
|
|
||||||
|
compile array_eq_test_cx.cpp ;
|
||||||
|
compile array_lt_test_cx.cpp ;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
||||||
run quick.cpp ;
|
run quick.cpp ;
|
||||||
|
|||||||
+3
-3
@@ -5,11 +5,11 @@
|
|||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/array.hpp>
|
|
||||||
|
|
||||||
#include <boost/core/lightweight_test_trait.hpp>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T> void test()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a = {{}};
|
||||||
|
|
||||||
|
STATIC_ASSERT( &a[ 0 ] == a.data() + 0 );
|
||||||
|
STATIC_ASSERT( &a[ 1 ] == a.data() + 1 );
|
||||||
|
STATIC_ASSERT( &a[ 2 ] == a.data() + 2 );
|
||||||
|
STATIC_ASSERT( &a[ 3 ] == a.data() + 3 );
|
||||||
|
|
||||||
|
STATIC_ASSERT( &a.at( 0 ) == a.data() + 0 );
|
||||||
|
STATIC_ASSERT( &a.at( 1 ) == a.data() + 1 );
|
||||||
|
STATIC_ASSERT( &a.at( 2 ) == a.data() + 2 );
|
||||||
|
STATIC_ASSERT( &a.at( 3 ) == a.data() + 3 );
|
||||||
|
|
||||||
|
STATIC_ASSERT( &a.front() == a.data() );
|
||||||
|
STATIC_ASSERT( &a.back() == a.data() + 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 2> a1 = {};
|
||||||
|
constexpr boost::array<T, 2> a2 = a1;
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1[0] == a2[0] );
|
||||||
|
STATIC_ASSERT( a1[1] == a2[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 3> a1 = {{ 1, 2, 3 }};
|
||||||
|
constexpr boost::array<T, 3> a2 = a1;
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1[0] == a2[0] );
|
||||||
|
STATIC_ASSERT( a1[1] == a2[1] );
|
||||||
|
STATIC_ASSERT( a1[2] == a2[2] );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test3()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 0> a1 = {};
|
||||||
|
constexpr boost::array<T, 0> a2 = a1;
|
||||||
|
|
||||||
|
(void)a1;
|
||||||
|
(void)a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int>();
|
||||||
|
test2<int>();
|
||||||
|
test3<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, N> a = {};
|
||||||
|
STATIC_ASSERT( a.data() == a.elems );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 0> a = {};
|
||||||
|
STATIC_ASSERT( a.data() == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int, 1>();
|
||||||
|
test1<int, 7>();
|
||||||
|
|
||||||
|
test2<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, N> a1 = {};
|
||||||
|
constexpr boost::array<T, N> a2 = {};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 == a2 );
|
||||||
|
STATIC_ASSERT( !( a1 != a2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a1 = {{ 1, 2, 3, 4 }};
|
||||||
|
constexpr boost::array<T, 4> a2 = {{ 1, 2, 3, 4 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 == a2 );
|
||||||
|
STATIC_ASSERT( !( a1 != a2 ) );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a1 = {{ 1, 2, 3, 4 }};
|
||||||
|
constexpr boost::array<T, 4> a2 = {{ 1, 2, 3, 5 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( !( a1 == a2 ) );
|
||||||
|
STATIC_ASSERT( a1 != a2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int, 0>();
|
||||||
|
test1<int, 1>();
|
||||||
|
test1<int, 7>();
|
||||||
|
|
||||||
|
test2<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T> void test()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a = {{ 1, 2, 3, 4 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( boost::get<0>( a ) == 1 );
|
||||||
|
STATIC_ASSERT( boost::get<1>( a ) == 2 );
|
||||||
|
STATIC_ASSERT( boost::get<2>( a ) == 3 );
|
||||||
|
STATIC_ASSERT( boost::get<3>( a ) == 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 1> a = {{}};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a[0] == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 2> a = {};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a[0] == 0 );
|
||||||
|
STATIC_ASSERT( a[1] == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test3()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 3> a = {{ 1, 2, 3 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a[0] == 1 );
|
||||||
|
STATIC_ASSERT( a[1] == 2 );
|
||||||
|
STATIC_ASSERT( a[2] == 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test4()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a = { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
STATIC_ASSERT( a[0] == 1 );
|
||||||
|
STATIC_ASSERT( a[1] == 2 );
|
||||||
|
STATIC_ASSERT( a[2] == 3 );
|
||||||
|
STATIC_ASSERT( a[3] == 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test5()
|
||||||
|
{
|
||||||
|
// constexpr boost::array<T, 0> a = {{}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test6()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 0> a = {};
|
||||||
|
(void)a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int>();
|
||||||
|
test2<int>();
|
||||||
|
test3<int>();
|
||||||
|
test4<int>();
|
||||||
|
test5<int>();
|
||||||
|
test6<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_MSVC < 1910")
|
||||||
|
|
||||||
|
#elif BOOST_WORKAROUND(BOOST_GCC, < 50000)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_GCC < 50000")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, N> a = {};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a.begin() == a.data() );
|
||||||
|
STATIC_ASSERT( a.end() == a.data() + N );
|
||||||
|
|
||||||
|
STATIC_ASSERT( a.cbegin() == a.data() );
|
||||||
|
STATIC_ASSERT( a.cend() == a.data() + N );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 0> a = {};
|
||||||
|
|
||||||
|
// iterator access is not constexpr for boost::array<T, 0>
|
||||||
|
// it is for std::array<T, 0>, though, so we should change it
|
||||||
|
|
||||||
|
STATIC_ASSERT( a.begin() == a.end() );
|
||||||
|
STATIC_ASSERT( a.cbegin() == a.cend() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// test1<int, 0>();
|
||||||
|
test1<int, 1>();
|
||||||
|
test1<int, 7>();
|
||||||
|
|
||||||
|
// test2<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX14_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, N> a1 = {};
|
||||||
|
constexpr boost::array<T, N> a2 = {};
|
||||||
|
|
||||||
|
STATIC_ASSERT( !( a1 < a2 ) );
|
||||||
|
STATIC_ASSERT( !( a1 > a2 ) );
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 <= a2 );
|
||||||
|
STATIC_ASSERT( a1 >= a2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void test2()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a1 = {{ 1, 2, 3, 4 }};
|
||||||
|
constexpr boost::array<T, 4> a2 = {{ 1, 2, 3, 4 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( !( a1 < a2 ) );
|
||||||
|
STATIC_ASSERT( !( a1 > a2 ) );
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 <= a2 );
|
||||||
|
STATIC_ASSERT( a1 >= a2 );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a1 = {{ 1, 2, 3, 4 }};
|
||||||
|
constexpr boost::array<T, 4> a2 = {{ 1, 2, 3, 5 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 < a2 );
|
||||||
|
STATIC_ASSERT( !( a1 > a2 ) );
|
||||||
|
|
||||||
|
STATIC_ASSERT( a1 <= a2 );
|
||||||
|
STATIC_ASSERT( !( a1 >= a2 ) );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, 4> a1 = {{ 1, 2, 3, 4 }};
|
||||||
|
constexpr boost::array<T, 4> a2 = {{ 1, 2, 3, 2 }};
|
||||||
|
|
||||||
|
STATIC_ASSERT( !( a1 < a2 ) );
|
||||||
|
STATIC_ASSERT( a1 > a2 );
|
||||||
|
|
||||||
|
STATIC_ASSERT( !( a1 <= a2 ) );
|
||||||
|
STATIC_ASSERT( a1 >= a2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int, 0>();
|
||||||
|
test1<int, 1>();
|
||||||
|
test1<int, 7>();
|
||||||
|
|
||||||
|
test2<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2025 Peter Dimov
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// https://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/config/pragma_message.hpp>
|
||||||
|
#include <boost/config/workaround.hpp>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||||
|
|
||||||
|
BOOST_PRAGMA_MESSAGE("Test skipped because BOOST_NO_CXX11_CONSTEXPR is defined")
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test1()
|
||||||
|
{
|
||||||
|
constexpr boost::array<T, N> a = {};
|
||||||
|
|
||||||
|
STATIC_ASSERT( a.size() == N );
|
||||||
|
STATIC_ASSERT( a.empty() == (N == 0) );
|
||||||
|
STATIC_ASSERT( a.max_size() == N );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, std::size_t N> void test2()
|
||||||
|
{
|
||||||
|
typedef boost::array<T, N> A;
|
||||||
|
|
||||||
|
STATIC_ASSERT( A().size() == N );
|
||||||
|
STATIC_ASSERT( A().empty() == (N == 0) );
|
||||||
|
STATIC_ASSERT( A().max_size() == N );
|
||||||
|
}
|
||||||
|
|
||||||
|
// the functions are static, which deviates from the standard
|
||||||
|
template<class T, std::size_t N> void test3()
|
||||||
|
{
|
||||||
|
typedef boost::array<T, N> A;
|
||||||
|
|
||||||
|
STATIC_ASSERT( A::size() == N );
|
||||||
|
STATIC_ASSERT( A::empty() == (N == 0) );
|
||||||
|
STATIC_ASSERT( A::max_size() == N );
|
||||||
|
|
||||||
|
STATIC_ASSERT( A::static_size == N );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1<int, 0>();
|
||||||
|
test1<int, 1>();
|
||||||
|
test1<int, 7>();
|
||||||
|
|
||||||
|
test2<int, 0>();
|
||||||
|
test2<int, 1>();
|
||||||
|
test2<int, 7>();
|
||||||
|
|
||||||
|
test3<int, 0>();
|
||||||
|
test3<int, 1>();
|
||||||
|
test3<int, 7>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user