NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
array.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_CONTAINER_ARRAY_HPP__
2#define NEFORCE_CORE_CONTAINER_ARRAY_HPP__
3
10
15NEFORCE_BEGIN_NAMESPACE__
16
22
32template <bool IsConst, size_t Size, typename Array>
33struct array_iterator : iiterator<array_iterator<IsConst, Size, Array>> {
34public:
35 using container_type = Array;
36 using value_type = typename container_type::value_type;
37 using size_type = typename container_type::size_type;
38 using difference_type = typename container_type::difference_type;
40 using reference = conditional_t<IsConst, typename container_type::const_reference,
41 typename container_type::reference>;
42 using pointer = conditional_t<IsConst, typename container_type::const_pointer,
43 typename container_type::pointer>;
44
45private:
46 pointer current_ = nullptr;
47 const container_type* container_ = nullptr;
48
49public:
50 constexpr array_iterator() noexcept = default;
51 NEFORCE_CONSTEXPR20 ~array_iterator() = default;
52
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;
57
63 constexpr array_iterator(pointer ptr, const container_type* vec) noexcept :
64 current_(ptr),
65 container_(vec) {}
66
71 NEFORCE_NODISCARD constexpr reference dereference() const noexcept {
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");
75 return *current_;
76 }
77
81 constexpr void increment() noexcept {
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");
84 ++current_;
85 }
86
90 constexpr void decrement() noexcept {
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");
93 --current_;
94 }
95
100 constexpr void advance(difference_type off) noexcept {
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");
104 current_ += off;
105 }
106
112 NEFORCE_NODISCARD constexpr difference_type distance_to(const array_iterator& other) const noexcept {
113 NEFORCE_DEBUG_VERIFY(container_ == other.container_, "Attempting to distance to a different container");
114 return static_cast<difference_type>(current_ - other.current_);
115 }
116
122 NEFORCE_NODISCARD constexpr reference operator[](const difference_type off) const noexcept {
123 return *(*this + off);
124 }
125
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_;
134 }
135
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_;
144 }
145
150 NEFORCE_NODISCARD constexpr pointer base() const noexcept { return current_; }
151
156 NEFORCE_NODISCARD constexpr const container_type* container() const noexcept { return container_; }
157};
158
159
171template <typename T, size_t Size>
172class array : public icollector<array<T, Size>> {
173 static_assert(is_object_v<T>, "array only containers of object types.");
174
175public:
176 using value_type = T;
177 using pointer = T*;
178 using reference = T&;
179 using const_pointer = const T*;
180 using const_reference = const T&;
181 using size_type = size_t;
182 using difference_type = ptrdiff_t;
183
188
189private:
190 T array_[Size];
191
192public:
193 constexpr array() noexcept = default;
194 NEFORCE_CONSTEXPR20 ~array() noexcept = default;
195
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;
200
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_);
208 }
209
214 NEFORCE_NODISCARD constexpr iterator begin() noexcept { return iterator(array_, this); }
215
220 NEFORCE_NODISCARD constexpr iterator end() noexcept { return iterator(array_ + Size, this); }
221
226 NEFORCE_NODISCARD constexpr const_iterator begin() const noexcept { return const_iterator(array_, this); }
227
232 NEFORCE_NODISCARD constexpr const_iterator end() const noexcept { return const_iterator(array_ + Size, this); }
233
238 NEFORCE_NODISCARD constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
239
244 NEFORCE_NODISCARD constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
245
250 NEFORCE_NODISCARD constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
251
256 NEFORCE_NODISCARD constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
257
262 NEFORCE_NODISCARD constexpr const_iterator cbegin() const noexcept { return const_iterator(array_, this); }
263
268 NEFORCE_NODISCARD constexpr const_iterator cend() const noexcept { return const_iterator(array_ + Size, this); }
269
274 NEFORCE_NODISCARD constexpr const_reverse_iterator crbegin() const noexcept {
276 }
277
282 NEFORCE_NODISCARD constexpr const_reverse_iterator crend() const noexcept {
284 }
285
290 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type size() const noexcept {
291 return Size;
292 }
293
298 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type max_size() const noexcept {
299 return Size;
300 }
301
306 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr bool empty() const noexcept {
307 return false;
308 }
309
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];
318 }
319
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];
327 }
328
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];
336 }
337
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];
345 }
346
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 {
377 return array_;
378 }
379
384 constexpr void fill(const T& value) { _NEFORCE fill_n(array_, Size, value); }
385
390 constexpr void swap(array& other) noexcept(is_nothrow_swappable_v<T>) { _NEFORCE swap(array_, other.array_); }
391
397 NEFORCE_NODISCARD constexpr bool equal_to(const array& rhs) const noexcept {
398 return _NEFORCE equal(this->cbegin(), this->cend(), rhs.cbegin());
399 }
400
405 NEFORCE_NODISCARD constexpr bool less_than(const array& rhs) const noexcept {
406 return _NEFORCE lexicographical_compare(this->cbegin(), this->cend(), rhs.cbegin(), rhs.cend());
407 }
408};
409
410struct empty_array_element_tag {
411 constexpr explicit empty_array_element_tag() noexcept = default;
412};
413
420template <typename T>
421class array<T, 0> : public icollector<array<T, 0>> {
422 static_assert(is_object_v<T>, "array only containers of object types.");
423
424public:
425 using value_type = T;
426 using pointer = T*;
427 using reference = T&;
428 using const_pointer = const T*;
429 using const_reference = const T&;
430 using size_type = size_t;
431 using difference_type = ptrdiff_t;
432
433 using iterator = array_iterator<false, 0, array>;
434 using const_iterator = array_iterator<true, 0, array>;
435 using reverse_iterator = _NEFORCE reverse_iterator<iterator>;
436 using const_reverse_iterator = _NEFORCE reverse_iterator<const_iterator>;
437
438private:
439 using placeholder =
441 empty_array_element_tag>;
442
443 placeholder array_[1]{placeholder{}};
444
445public:
446 constexpr array() noexcept = default;
447 NEFORCE_CONSTEXPR20 ~array() noexcept = default;
448
449 constexpr array(const array& /*unused*/) noexcept {}
450 // NOLINTNEXTLINE(bugprone-unhandled-self-assignment)
451 constexpr array& operator=(const array& /*unused*/) noexcept { return *this; }
452 constexpr array(array&& /*unused*/) noexcept {}
453 constexpr array& operator=(array&& /*unused*/) noexcept { return *this; }
454
455 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr iterator begin() noexcept {
456 return iterator{};
457 }
458 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr iterator end() noexcept {
459 return iterator{};
460 }
461 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr const_iterator begin() const noexcept {
462 return const_iterator{};
463 }
464 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr const_iterator end() const noexcept {
465 return const_iterator{};
466 }
467 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr reverse_iterator rbegin() noexcept {
468 return reverse_iterator(end());
469 }
470 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr reverse_iterator rend() noexcept {
471 return reverse_iterator(begin());
472 }
473 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr const_reverse_iterator
474 rbegin() const noexcept {
475 return const_reverse_iterator(end());
476 }
477 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr const_reverse_iterator
478 rend() const noexcept {
479 return const_reverse_iterator(begin());
480 }
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 {
484 return rbegin();
485 }
486 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr const_reverse_iterator crend() const noexcept { return rend(); }
487
488 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type size() const noexcept {
489 return 0;
490 }
491 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr size_type max_size() const noexcept {
492 return 0;
493 }
494 NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE constexpr bool empty() const noexcept {
495 return true;
496 }
497
498 NEFORCE_NODISCARD reference at(size_type /*unused*/) {
499 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
500 return array_[0];
501 }
502
503 NEFORCE_NODISCARD const_reference at(size_type /*unused*/) const {
504 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
505 return array_[0];
506 }
507
508 NEFORCE_NODISCARD reference operator[](size_type /*unused*/) {
509 NEFORCE_THROW_EXCEPTION(iterator_exception("array index out of range"));
510 return *data();
511 }
512 NEFORCE_NODISCARD const_reference operator[](size_type /*unused*/) const {
513 NEFORCE_THROW_EXCEPTION(iterator_exception("array index out of range"));
514 return *data();
515 }
516
517 NEFORCE_NODISCARD reference front() {
518 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
519 return *data();
520 }
521 NEFORCE_NODISCARD const_reference front() const {
522 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
523 return *data();
524 }
525
526 NEFORCE_NODISCARD reference back() {
527 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
528 return *data();
529 }
530
531 NEFORCE_NODISCARD const_reference back() const {
532 NEFORCE_THROW_EXCEPTION(iterator_exception("array empty."));
533 return *data();
534 }
535
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 {
538 return nullptr;
539 }
540
541 NEFORCE_ALWAYS_INLINE constexpr void fill(const T& /*unused*/) {}
542 NEFORCE_ALWAYS_INLINE constexpr void swap(array& /*unused*/) noexcept {}
543
544 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr bool equal_to(const array& /*unused*/) const noexcept {
545 return true;
546 }
547 NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr bool less_than(const array& /*unused*/) const noexcept {
548 return false;
549 }
550};
551
552#ifdef NEFORCE_STANDARD_17
553NEFORCE_BEGIN_INNER__
554template <typename First, typename... Rest>
555struct __array_same {
556 static_assert(conjunction_v<is_same<First, Rest>...>, "array types mismatch.");
557 using type = First;
558};
559NEFORCE_END_INNER__
560
561template <typename First, typename... Rest>
562array(First, Rest...) -> array<typename inner::__array_same<First, Rest...>::type, 1 + sizeof...(Rest)>;
563#endif
564
565
574template <size_t Idx, typename T, size_t Size>
575NEFORCE_NODISCARD constexpr T& get(array<T, Size>& arr) noexcept {
576 static_assert(Idx < Size, "array index out of bounds");
577 return arr[Idx];
578}
579
588template <size_t Idx, typename T, size_t Size>
589NEFORCE_NODISCARD constexpr const T& get(const array<T, Size>& arr) noexcept {
590 static_assert(Idx < Size, "array index out of bounds");
591 return arr[Idx];
592}
593
602template <size_t Idx, typename T, size_t Size>
603NEFORCE_NODISCARD constexpr T&& get(array<T, Size>&& arr) noexcept {
604 static_assert(Idx < Size, "array index out of bounds");
605 return _NEFORCE move(arr[Idx]);
606}
607
616template <size_t Idx, typename T, size_t Size>
617NEFORCE_NODISCARD constexpr const T&& get(const array<T, Size>&& arr) noexcept {
618 static_assert(Idx < Size, "array index out of bounds");
619 return _NEFORCE move(arr[Idx]);
620}
621 // Array
623
629
636template <typename T, size_t Size>
637struct tuple_size<array<T, Size>> : integral_constant<size_t, Size> {};
638
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> {};
642NEFORCE_MACRO_RANGES_CV(__NEFORCE_BUILD_ARRAY_TUPLE_SIZE)
643#undef __NEFORCE_BUILD_ARRAY_TUPLE_SIZE
644
651template <size_t Idx, typename T, size_t Size>
652struct tuple_element<Idx, array<T, Size>> {
653 static_assert(Idx < Size, "array index is in range");
654 using type = T;
655};
656
657template <typename T, size_t Size>
658NEFORCE_INLINE17 constexpr size_t tuple_size_v<array<T, Size>> = Size;
659
660template <typename T, size_t Size>
661NEFORCE_INLINE17 constexpr size_t tuple_size_v<const array<T, Size>> = Size;
662 // Tuple
664
665NEFORCE_END_NAMESPACE__
666
667#ifdef NEFORCE_STANDARD_17
668# include <utility>
669namespace std {
670 template <typename T, size_t Size>
671 struct tuple_size<_NEFORCE array<T, Size>> : _NEFORCE integral_constant<_NEFORCE size_t, Size> {};
672
673 template <size_t Idx, typename T, size_t Size>
674 struct tuple_element<Idx, _NEFORCE array<T, Size>> {
676 };
677} // namespace std
678#endif
679
680#endif // NEFORCE_CORE_CONTAINER_ARRAY_HPP__
固定大小数组容器
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)))
比较两个范围是否相等
uint64_t size_t
无符号大小类型
int64_t ptrdiff_t
指针差类型
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
下标访问操作符
Array container_type
容器类型
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
引用类型
连续迭代器标签
集合器接口模板
迭代器接口模板
整数常量包装器
判断类型是否可隐式默认构造
指针或迭代器行为异常
获取tuple元素类型的特化
获取tuple大小的特化