1#ifndef NEFORCE_CORE_CONTAINER_ARRAY_HPP__
2#define NEFORCE_CORE_CONTAINER_ARRAY_HPP__
15NEFORCE_BEGIN_NAMESPACE__
32template <
bool IsConst,
size_t Size,
typename Array>
33struct array_iterator :
iiterator<array_iterator<IsConst, Size, Array>> {
37 using size_type =
typename container_type::size_type;
41 typename container_type::reference>;
43 typename container_type::pointer>;
50 constexpr array_iterator() noexcept = default;
51 NEFORCE_CONSTEXPR20 ~array_iterator() = default;
53 constexpr array_iterator(const array_iterator&) noexcept = default;
54 constexpr array_iterator& operator=(const array_iterator&) noexcept = default;
55 constexpr array_iterator(array_iterator&&) noexcept = default;
56 constexpr array_iterator& operator=(array_iterator&&) noexcept = default;
72 NEFORCE_DEBUG_VERIFY(current_ && container_,
"Attempting to dereference on a null pointer");
73 NEFORCE_DEBUG_VERIFY(current_ >= container_->data() && current_ < container_->
data() + Size,
74 "Attempting to dereference out of boundary");
82 NEFORCE_DEBUG_VERIFY(current_ && container_,
"Attempting to increment a null pointer");
83 NEFORCE_DEBUG_VERIFY(current_ < container_->
data() + Size,
"Attempting to increment out of boundary");
91 NEFORCE_DEBUG_VERIFY(current_ && container_,
"Attempting to decrement a null pointer");
92 NEFORCE_DEBUG_VERIFY(current_ > container_->data(),
"Attempting to decrement out of boundary");
101 NEFORCE_DEBUG_VERIFY((current_ && container_) || off == 0,
"Attempting to advance a null pointer");
102 NEFORCE_DEBUG_VERIFY(current_ + off >= container_->data() && current_ + off <= container_->
data() + Size,
103 "Attempting to advance out of boundary");
113 NEFORCE_DEBUG_VERIFY(container_ == other.container_,
"Attempting to distance to a different container");
123 return *(*
this + off);
131 NEFORCE_NODISCARD
constexpr bool equal_to(
const array_iterator& rhs)
const noexcept {
132 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_,
"Attempting to equal to a different container");
133 return current_ == rhs.current_;
141 NEFORCE_NODISCARD
constexpr bool less_than(
const array_iterator& rhs)
const noexcept {
142 NEFORCE_DEBUG_VERIFY(container_ == rhs.container_,
"Attempting to less than a different container");
143 return current_ < rhs.current_;
150 NEFORCE_NODISCARD
constexpr pointer base() const noexcept {
return current_; }
171template <
typename T,
size_t Size>
173 static_assert(
is_object_v<T>,
"array only containers of object types.");
176 using value_type = T;
178 using reference = T&;
179 using const_pointer =
const T*;
180 using const_reference =
const T&;
193 constexpr array() noexcept = default;
194 NEFORCE_CONSTEXPR20 ~array() noexcept = default;
196 constexpr array(const array&) noexcept = default;
197 constexpr array& operator=(const array&) noexcept = default;
198 constexpr array(array&&) noexcept = default;
199 constexpr array& operator=(array&&) noexcept = default;
205 constexpr array(std::initializer_list<T> ilist) noexcept {
206 size_t size = ilist.size() < Size ? ilist.size() : Size;
207 _NEFORCE
copy(ilist.begin(), ilist.begin() +
size, array_);
290 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
size() const noexcept {
298 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
max_size() const noexcept {
306 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr bool empty() const noexcept {
315 NEFORCE_NODISCARD
constexpr reference
at(size_type position)
noexcept {
316 NEFORCE_DEBUG_VERIFY(position < Size,
"array subscript out of range");
317 return array_[position];
324 NEFORCE_NODISCARD
constexpr const_reference
at(size_type position)
const noexcept {
325 NEFORCE_DEBUG_VERIFY(position < Size,
"array subscript out of range");
326 return array_[position];
333 NEFORCE_NODISCARD
constexpr reference
operator[](size_type position)
noexcept {
334 NEFORCE_DEBUG_VERIFY(position < Size,
"array subscript out of range");
335 return array_[position];
342 NEFORCE_NODISCARD
constexpr const_reference
operator[](size_type position)
const noexcept {
343 NEFORCE_DEBUG_VERIFY(position < Size,
"array subscript out of range");
344 return array_[position];
351 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr reference
front() noexcept {
return array_[0]; }
356 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reference
front() const noexcept {
return array_[0]; }
361 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr reference
back() noexcept {
return array_[Size - 1]; }
366 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reference
back() const noexcept {
return array_[Size - 1]; }
371 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr T*
data() noexcept {
return array_; }
376 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const T*
data() const noexcept {
384 constexpr void fill(
const T& value) { _NEFORCE
fill_n(array_, Size, value); }
397 NEFORCE_NODISCARD
constexpr bool equal_to(
const array& rhs)
const noexcept {
405 NEFORCE_NODISCARD
constexpr bool less_than(
const array& rhs)
const noexcept {
410struct empty_array_element_tag {
411 constexpr explicit empty_array_element_tag() noexcept = default;
422 static_assert(
is_object_v<T>,
"array only containers of object types.");
425 using value_type = T;
427 using reference = T&;
428 using const_pointer =
const T*;
429 using const_reference =
const T&;
435 using reverse_iterator = _NEFORCE reverse_iterator<iterator>;
436 using const_reverse_iterator = _NEFORCE reverse_iterator<const_iterator>;
441 empty_array_element_tag>;
443 placeholder array_[1]{placeholder{}};
446 constexpr array()
noexcept =
default;
447 NEFORCE_CONSTEXPR20 ~array()
noexcept =
default;
449 constexpr array(
const array& )
noexcept {}
451 constexpr array& operator=(
const array& )
noexcept {
return *
this; }
452 constexpr array(array&& )
noexcept {}
453 constexpr array& operator=(array&& )
noexcept {
return *
this; }
455 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr iterator
begin()
noexcept {
458 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr iterator
end()
noexcept {
461 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_iterator
begin()
const noexcept {
462 return const_iterator{};
464 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_iterator
end()
const noexcept {
465 return const_iterator{};
467 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr reverse_iterator
rbegin()
noexcept {
468 return reverse_iterator(
end());
470 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr reverse_iterator
rend()
noexcept {
471 return reverse_iterator(
begin());
473 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
475 return const_reverse_iterator(
end());
477 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
478 rend()
const noexcept {
479 return const_reverse_iterator(
begin());
481 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_iterator
cbegin()
const noexcept {
return begin(); }
482 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_iterator
cend()
const noexcept {
return end(); }
483 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
crbegin()
const noexcept {
486 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
crend()
const noexcept {
return rend(); }
488 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
size()
const noexcept {
491 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type max_size()
const noexcept {
494 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr bool empty()
const noexcept {
498 NEFORCE_NODISCARD reference at(size_type ) {
503 NEFORCE_NODISCARD const_reference at(size_type )
const {
508 NEFORCE_NODISCARD reference operator[](size_type ) {
512 NEFORCE_NODISCARD const_reference operator[](size_type )
const {
517 NEFORCE_NODISCARD reference front() {
521 NEFORCE_NODISCARD const_reference front()
const {
526 NEFORCE_NODISCARD reference back() {
531 NEFORCE_NODISCARD const_reference back()
const {
536 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr T*
data()
noexcept {
return nullptr; }
537 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const T*
data()
const noexcept {
541 NEFORCE_ALWAYS_INLINE
constexpr void fill(
const T& ) {}
542 NEFORCE_ALWAYS_INLINE
constexpr void swap(array& )
noexcept {}
544 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr bool equal_to(
const array& )
const noexcept {
547 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr bool less_than(
const array& )
const noexcept {
552#ifdef NEFORCE_STANDARD_17
554template <
typename First,
typename... Rest>
561template <
typename First,
typename... Rest>
562array(First, Rest...) -> array<
typename inner::__array_same<First, Rest...>::type, 1 +
sizeof...(Rest)>;
574template <
size_t Idx,
typename T,
size_t Size>
576 static_assert(Idx < Size,
"array index out of bounds");
588template <
size_t Idx,
typename T,
size_t Size>
590 static_assert(Idx < Size,
"array index out of bounds");
602template <
size_t Idx,
typename T,
size_t Size>
604 static_assert(Idx < Size,
"array index out of bounds");
605 return _NEFORCE
move(arr[Idx]);
616template <
size_t Idx,
typename T,
size_t Size>
618 static_assert(Idx < Size,
"array index out of bounds");
619 return _NEFORCE
move(arr[Idx]);
636template <
typename T,
size_t Size>
639#define __NEFORCE_BUILD_ARRAY_TUPLE_SIZE(CV) \
640 template <typename T, size_t Size> \
641 struct tuple_size<array<T, Size> CV> : integral_constant<size_t, Size> {};
643#undef __NEFORCE_BUILD_ARRAY_TUPLE_SIZE
651template <
size_t Idx,
typename T,
size_t Size>
653 static_assert(Idx < Size,
"array index is in range");
657template <
typename T,
size_t Size>
660template <
typename T,
size_t Size>
665NEFORCE_END_NAMESPACE__
667#ifdef NEFORCE_STANDARD_17
670 template <
typename T,
size_t Size>
673 template <
size_t Idx,
typename T,
size_t Size>
constexpr const_reference front() const noexcept
访问第一个常量元素
constexpr bool equal_to(const array &rhs) const noexcept
相等比较操作符
constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
array_iterator< false, Size, array > iterator
迭代器类型
constexpr const_reference back() const noexcept
访问最后一个常量元素
constexpr size_type max_size() const noexcept
获取最大大小
constexpr reference back() noexcept
访问最后一个元素
constexpr const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
constexpr const_iterator cend() const noexcept
获取常量结束迭代器
constexpr const_iterator begin() const noexcept
获取常量起始迭代器
constexpr void fill(const T &value)
填充数组
constexpr const T * data() const noexcept
获取常量底层数据指针
constexpr const_reference at(size_type position) const noexcept
索引位置元素常量访问
constexpr const_iterator end() const noexcept
获取常量结束迭代器
constexpr size_type size() const noexcept
constexpr iterator begin() noexcept
获取起始迭代器
constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
constexpr bool empty() const noexcept
检查数组是否为空
constexpr iterator end() noexcept
获取结束迭代器
array_iterator< true, Size, array > const_iterator
常量迭代器类型
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
constexpr reference operator[](size_type position) noexcept
下标访问操作符
constexpr void swap(array &other) noexcept(is_nothrow_swappable_v< T >)
交换两个数组
constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
constexpr const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
constexpr const_reference operator[](size_type position) const noexcept
常量下标访问操作符
constexpr T * data() noexcept
获取底层数据指针
constexpr bool less_than(const array &rhs) const noexcept
小于比较操作符
constexpr reference front() noexcept
访问第一个元素
constexpr reference at(size_type position) noexcept
索引位置元素访问
constexpr const_iterator cbegin() const noexcept
获取常量起始迭代器
constexpr T & get(array< T, Size > &arr) noexcept
获取左值数组指定位置的元素
constexpr bool is_object_v
is_object的便捷变量模板
constexpr bool lexicographical_compare(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Compare comp) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(comp(*first1, *first2)) &&noexcept(first1==last1 &&first2 !=last2))
字典序比较两个范围
constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
constexpr void fill(Iterator first, Iterator last, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充范围元素
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
constexpr Iterator2 copy(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__copy_aux(first, last, result)))
复制范围元素
constexpr Iterator fill_n(Iterator first, iter_difference_t< Iterator > n, const T &value) noexcept(is_nothrow_assignable_v< iter_value_t< Iterator >, T >)
填充指定数量的元素
void swap()=delete
删除无参数的swap重载
constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr size_t tuple_size_v
tuple_size的类型别名
typename tuple_element< Index, Types... >::type tuple_element_t
tuple_element的类型别名
constexpr decltype(auto) crend(const Container &cont) noexcept(noexcept(cont.crend()))
获取const容器的const反向结束迭代器
constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器
constexpr decltype(auto) rend(Container &cont) noexcept(noexcept(cont.rend()))
获取const容器的反向起始迭代器
constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
constexpr decltype(auto) crbegin(const Container &cont) noexcept(noexcept(cont.crbegin()))
获取const容器的const反向起始迭代器
constexpr decltype(auto) rbegin(Container &cont) noexcept(noexcept(cont.rbegin()))
获取容器的反向起始迭代器
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
#define NEFORCE_MACRO_RANGES_CV(MAC)
cv限定符列表宏
constexpr bool conjunction_v
conjunction的便捷变量模板
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
constexpr bool less_than(const array_iterator &rhs) const noexcept
小于比较
constexpr reference operator[](const difference_type off) const noexcept
下标访问操作符
constexpr reference dereference() const noexcept
解引用操作
constexpr const container_type * container() const noexcept
获取关联容器
constexpr pointer base() const noexcept
获取底层指针
typename container_type::value_type value_type
值类型
typename container_type::difference_type difference_type
差值类型
constexpr void decrement() noexcept
递减操作
typename container_type::size_type size_type
大小类型
constexpr void advance(difference_type off) noexcept
前进操作
constexpr bool equal_to(const array_iterator &rhs) const noexcept
相等比较
contiguous_iterator_tag iterator_category
迭代器类别
constexpr void increment() noexcept
递增操作
constexpr difference_type distance_to(const array_iterator &other) const noexcept
计算距离操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型