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;
74 "Attempting to dereference out of boundary");
101 NEFORCE_DEBUG_VERIFY((current_ && container_) || off == 0,
"Attempting to advance a null pointer");
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(
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_);
286 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
size() const noexcept {
294 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
max_size() const noexcept {
302 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr bool empty() const noexcept {
311 NEFORCE_NODISCARD
constexpr reference
at(size_type position)
noexcept {
313 return array_[position];
320 NEFORCE_NODISCARD
constexpr const_reference
at(size_type position)
const noexcept {
322 return array_[position];
329 NEFORCE_NODISCARD
constexpr reference
operator[](size_type position)
noexcept {
331 return array_[position];
338 NEFORCE_NODISCARD
constexpr const_reference
operator[](size_type position)
const noexcept {
340 return array_[position];
347 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr reference
front() noexcept {
return array_[0]; }
352 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reference
front() const noexcept {
return array_[0]; }
357 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr reference
back() noexcept {
return array_[Size - 1]; }
362 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reference
back() const noexcept {
return array_[Size - 1]; }
367 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr T*
data() noexcept {
return array_; }
372 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const T*
data() const noexcept {
380 constexpr void fill(
const T& value) { _NEFORCE
fill_n(array_, Size, value); }
393 NEFORCE_NODISCARD
constexpr bool operator==(
const array& rhs)
const noexcept {
401 NEFORCE_NODISCARD
constexpr bool operator<(
const array& rhs)
const noexcept {
406struct empty_array_element_tag {
407 constexpr explicit empty_array_element_tag() noexcept = default;
418 static_assert(
is_object_v<T>,
"array only containers of object types.");
421 using value_type = T;
423 using reference = T&;
424 using const_pointer =
const T*;
425 using const_reference =
const T&;
431 using reverse_iterator = _NEFORCE reverse_iterator<iterator>;
432 using const_reverse_iterator = _NEFORCE reverse_iterator<const_iterator>;
436 empty_array_element_tag>
440 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr iterator
begin()
noexcept {
443 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr iterator
end()
noexcept {
446 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_iterator
begin()
const noexcept {
447 return const_iterator{};
449 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_iterator
end()
const noexcept {
450 return const_iterator{};
452 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr reverse_iterator
rbegin()
noexcept {
453 return reverse_iterator(
end());
455 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr reverse_iterator
rend()
noexcept {
456 return reverse_iterator(
begin());
458 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
460 return const_reverse_iterator(
end());
462 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
463 rend()
const noexcept {
464 return const_reverse_iterator(
begin());
466 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_iterator
cbegin()
const noexcept {
return begin(); }
467 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_iterator
cend()
const noexcept {
return end(); }
468 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
crbegin()
const noexcept {
471 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr const_reverse_iterator
crend()
const noexcept {
return rend(); }
473 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type
size()
const noexcept {
476 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr size_type max_size()
const noexcept {
479 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr bool empty()
const noexcept {
483 NEFORCE_NODISCARD reference at(size_type) {
488 NEFORCE_NODISCARD const_reference at(size_type)
const {
493 NEFORCE_NODISCARD reference operator[](size_type)
noexcept {
497 NEFORCE_NODISCARD const_reference operator[](size_type)
const noexcept {
502 NEFORCE_NODISCARD reference front()
noexcept {
506 NEFORCE_NODISCARD const_reference front()
const noexcept {
511 NEFORCE_NODISCARD reference back()
noexcept {
516 NEFORCE_NODISCARD const_reference back()
const noexcept {
521 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr T*
data()
noexcept {
return nullptr; }
522 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE
constexpr const T*
data()
const noexcept {
526 NEFORCE_ALWAYS_INLINE
constexpr void fill(
const T&) {}
527 NEFORCE_ALWAYS_INLINE
constexpr void swap(array&)
noexcept {}
529 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr bool operator==(
const array&)
const noexcept {
return true; }
531 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE
constexpr bool operator<(
const array&)
const noexcept {
return false; }
534#ifdef NEFORCE_STANDARD_17
536template <
typename First,
typename... Rest>
543template <
typename First,
typename... Rest>
544array(First, Rest...) -> array<
typename inner::__array_same<First, Rest...>::type, 1 +
sizeof...(Rest)>;
556template <
size_t Idx,
typename T,
size_t Size>
558 static_assert(Idx < Size,
"array index out of bounds");
570template <
size_t Idx,
typename T,
size_t Size>
572 static_assert(Idx < Size,
"array index out of bounds");
584template <
size_t Idx,
typename T,
size_t Size>
586 static_assert(Idx < Size,
"array index out of bounds");
587 return _NEFORCE
move(arr[Idx]);
598template <
size_t Idx,
typename T,
size_t Size>
600 static_assert(Idx < Size,
"array index out of bounds");
601 return _NEFORCE
move(arr[Idx]);
618template <
typename T,
size_t Size>
627template <
size_t Idx,
typename T,
size_t Size>
629 static_assert(Idx < Size,
"array index is in range");
633template <
typename T,
size_t Size>
636template <
typename T,
size_t Size>
641NEFORCE_END_NAMESPACE__
NEFORCE_NODISCARD constexpr const_reverse_iterator rend() const noexcept
获取常量反向结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr const_reference front() const noexcept
访问第一个常量元素
NEFORCE_NODISCARD constexpr const_reference operator[](size_type position) const noexcept
常量下标访问操作符
_NEFORCE reverse_iterator< iterator > reverse_iterator
反向迭代器类型
array_iterator< false, Size, array > iterator
迭代器类型
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr const_reference back() const noexcept
访问最后一个常量元素
NEFORCE_NODISCARD constexpr iterator end() noexcept
获取结束迭代器
NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type max_size() const noexcept
获取最大大小
NEFORCE_NODISCARD constexpr const_reference at(size_type position) const noexcept
索引位置元素常量访问
constexpr void fill(const T &value)
填充数组
NEFORCE_NODISCARD constexpr const_iterator cend() const noexcept
获取常量结束迭代器
NEFORCE_NODISCARD constexpr const_iterator begin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr reference front() noexcept
访问第一个元素
NEFORCE_NODISCARD constexpr const_reverse_iterator crend() const noexcept
获取常量反向结束迭代器
NEFORCE_NODISCARD constexpr reverse_iterator rbegin() noexcept
获取反向起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr reference back() noexcept
访问最后一个元素
NEFORCE_NODISCARD constexpr iterator begin() noexcept
获取起始迭代器
NEFORCE_NODISCARD constexpr const_reverse_iterator rbegin() const noexcept
获取常量反向起始迭代器
NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type size() const noexcept
NEFORCE_NODISCARD constexpr reverse_iterator rend() noexcept
获取反向结束迭代器
NEFORCE_NODISCARD constexpr const_reverse_iterator crbegin() const noexcept
获取常量反向起始迭代器
NEFORCE_NODISCARD constexpr bool operator==(const array &rhs) const noexcept
相等比较操作符
NEFORCE_NODISCARD constexpr const_iterator end() const noexcept
获取常量结束迭代器
array_iterator< true, Size, array > const_iterator
常量迭代器类型
_NEFORCE reverse_iterator< const_iterator > const_reverse_iterator
常量反向迭代器类型
constexpr void swap(array &other) noexcept(is_nothrow_swappable_v< T >)
交换两个数组
NEFORCE_NODISCARD constexpr reference at(size_type position) noexcept
索引位置元素访问
NEFORCE_NODISCARD constexpr const_iterator cbegin() const noexcept
获取常量起始迭代器
NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr const T * data() const noexcept
获取常量底层数据指针
NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr bool empty() const noexcept
检查数组是否为空
NEFORCE_NODISCARD constexpr reference operator[](size_type position) noexcept
下标访问操作符
NEFORCE_NODISCARD constexpr bool operator<(const array &rhs) const noexcept
小于比较操作符
NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr T * data() noexcept
获取底层数据指针
NEFORCE_NODISCARD constexpr T & get(array< T, Size > &arr) noexcept
获取左值数组指定位置的元素
NEFORCE_INLINE17 constexpr bool is_object_v
is_object的便捷变量模板
NEFORCE_NODISCARD constexpr bool equal(Iterator1 first1, Iterator1 last1, Iterator2 first2, BinaryPredicate binary_pred) noexcept(noexcept(++first1) &&noexcept(++first2) &&noexcept(binary_pred(*first1, *first2)))
比较两个范围是否相等
NEFORCE_NODISCARD 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))
字典序比较两个范围
#define NEFORCE_DEBUG_VERIFY(CON, MESG)
调试模式断言
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
NEFORCE_NODISCARD constexpr bool operator<(const normal_iterator< LeftIter > &lhs, const normal_iterator< RightIter > &rhs) noexcept
小于比较运算符
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重载
NEFORCE_INLINE17 constexpr bool is_nothrow_swappable_v
is_nothrow_swappable的便捷变量模板
constexpr size_t tuple_size_v
tuple_size的类型别名
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) rbegin(Container &cont) noexcept(noexcept(cont.rbegin()))
获取容器的反向起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) crend(const Container &cont) noexcept(noexcept(cont.crend()))
获取const容器的const反向结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) rend(Container &cont) noexcept(noexcept(cont.rend()))
获取const容器的反向起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) begin(Container &cont) noexcept(noexcept(cont.begin()))
获取容器的起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) cbegin(const Container &cont) noexcept(noexcept(cont.cbegin()))
获取const容器的const起始迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) cend(const Container &cont) noexcept(noexcept(cont.cend()))
获取const容器的const结束迭代器
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) crbegin(const Container &cont) noexcept(noexcept(cont.crbegin()))
获取const容器的const反向起始迭代器
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
NEFORCE_INLINE17 constexpr bool conjunction_v
conjunction的便捷变量模板
conditional_t< IsConst, typename container_type::const_pointer, typename container_type::pointer > pointer
指针类型
NEFORCE_NODISCARD constexpr bool equal(const array_iterator &rhs) const noexcept
相等比较
NEFORCE_NODISCARD constexpr const container_type * container() const noexcept
获取关联容器
typename container_type::value_type value_type
值类型
typename container_type::difference_type difference_type
差值类型
NEFORCE_NODISCARD constexpr difference_type distance_to(const array_iterator &other) const noexcept
计算距离操作
constexpr void decrement() noexcept
递减操作
typename container_type::size_type size_type
大小类型
constexpr void advance(difference_type off) noexcept
前进操作
NEFORCE_NODISCARD constexpr reference operator[](const difference_type off) const noexcept
下标访问操作符
contiguous_iterator_tag iterator_category
迭代器类别
constexpr void increment() noexcept
递增操作
NEFORCE_NODISCARD constexpr bool less_than(const array_iterator &rhs) const noexcept
小于比较
NEFORCE_NODISCARD constexpr reference dereference() const noexcept
解引用操作
conditional_t< IsConst, typename container_type::const_reference, typename container_type::reference > reference
引用类型
NEFORCE_NODISCARD constexpr pointer base() const noexcept
获取底层指针