Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
multiarray.h
Go to the documentation of this file.
1
12
13/*
14Copyright (c) 2026 MrXie1109
15
16Permission is hereby granted, free of charge, to any person obtaining a copy
17of this software and associated documentation files (the "Software"), to deal
18in the Software without restriction, including without limitation the rights
19to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20copies of the Software, and to permit persons to whom the Software is
21furnished to do so, subject to the following conditions:
22
23The above copyright notice and this permission notice shall be included in all
24copies or substantial portions of the Software.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32SOFTWARE.
33*/
34
35#pragma once
36#include <algorithm>
37#include <array>
38#include <cstddef>
39#include <cstring>
40#include <initializer_list>
41#include <iostream>
42#include <memory>
43#include <stdexcept>
44#include <type_traits>
45
46#include "../core/csexc.h"
47#include "../text/repr.h"
48
49namespace console {
50#ifdef CONSOLE_MULTIARRAY_V1
51 inline
52#endif
54 namespace _V1 {
66 template <class T, size_t... Dims>
68
74 template <class T, size_t D>
75 class MultiArray<T, D> : public std::array<T, D> {
76 using base_type = std::array<T, D>;
77
78 public:
79 using value_type = T;
80 using reference = T &;
81 using const_reference = const T &;
82
84 MultiArray() = default;
85
90 explicit MultiArray(const T &value) { fill(value); }
91
93 MultiArray(const base_type &other) : base_type(other) {}
94
99 MultiArray(std::initializer_list<T> init) {
100 std::copy(init.begin(), init.end(), this->begin());
101 }
102
104 static constexpr size_t rank() { return 1; }
105
107 static constexpr size_t fsize() { return D; }
108
110 void fill(const T &value) {
111 for (auto &item : *this) item = value;
112 }
113
119 template <class F>
120 void for_each(F &&visit) {
121 for (auto &item : *this) visit(item);
122 }
123
129 template <class F>
130 void for_each(F &&visit) const {
131 for (const auto &item : *this) visit(item);
132 }
133
141 if (i >= D)
142 throw MultiArrayError("index " + std::to_string(i)
143 + " out of range [0, "
144 + std::to_string(D) + ')');
145 return (*this)[i];
146 }
147
149 const_reference operator()(size_t i) const {
150 if (i >= D)
151 throw MultiArrayError("index " + std::to_string(i)
152 + " out of range [0, "
153 + std::to_string(D) + ')');
154 return (*this)[i];
155 }
156
158 friend std::ostream &
159 operator<<(std::ostream &os, const MultiArray &ma) {
160 if (ma.begin() == ma.end()) return os << "[]";
161 auto it = ma.begin();
162 os << '[';
163 repr(*it, os);
164 while (++it != ma.end()) {
165 os << ", ";
166 repr(*it, os);
167 }
168 return os << ']';
169 }
170
172 T *fbegin() { return this->data(); }
173
175 const T *fbegin() const { return this->data(); }
176
178 T *fend() { return this->data() + fsize(); }
179
181 const T *fend() const { return this->data() + fsize(); }
182
187 MultiArray &flatten() { return *this; }
188
193 const MultiArray &flatten() const { return *this; }
194
199 static constexpr std::array<size_t, 1> dims() { return {D}; }
200
206 template <size_t... Dims>
207 MultiArray<T, Dims...> &reshape() {
208 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
209 "reshape: total element count must match");
210 return *reinterpret_cast<MultiArray<T, Dims...> *>(this);
211 }
212
218 template <size_t... Dims>
219 const MultiArray<T, Dims...> &reshape() const {
220 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
221 "reshape: total element count must match");
222 return *reinterpret_cast<const MultiArray<T, Dims...> *>(this);
223 }
224 };
225
232 template <class T, size_t First, size_t... Rest>
233 class MultiArray<T, First, Rest...>
234 : public std::array<MultiArray<T, Rest...>, First> {
235 using base_type = std::array<MultiArray<T, Rest...>, First>;
236
237 public:
238 using value_type = MultiArray<T, Rest...>;
239 using reference = MultiArray<T, Rest...> &;
240 using const_reference = const MultiArray<T, Rest...> &;
241
243 MultiArray() = default;
244
249 explicit MultiArray(const T &value) { fill(value); }
250
252 MultiArray(const base_type &other) : base_type(other) {}
253
258 MultiArray(std::initializer_list<MultiArray<T, Rest...>> init) {
259 std::copy(init.begin(), init.end(), this->begin());
260 }
261
263 static constexpr size_t rank() { return 1 + sizeof...(Rest); }
264
266 static constexpr size_t fsize() {
267 return First * MultiArray<T, Rest...>::fsize();
268 }
269
271 void fill(const T &value) {
272 for (auto &sub : *this) sub.fill(value);
273 }
274
279 template <class F>
280 void for_each(F &&visit) {
281 for (auto &sub : *this) sub.for_each(visit);
282 }
283
288 template <class F>
289 void for_each(F &&visit) const {
290 for (const auto &sub : *this) sub.for_each(visit);
291 }
292
299 reference operator()(size_t idx) {
300 if (idx >= First)
301 throw MultiArrayError("index " + std::to_string(idx)
302 + " out of range [0, "
303 + std::to_string(First) + ')');
304 return base_type::operator[](idx);
305 }
306
308 const_reference operator()(size_t idx) const {
309 if (idx >= First)
310 throw MultiArrayError("index " + std::to_string(idx)
311 + " out of range [0, "
312 + std::to_string(First) + ')');
313 return base_type::operator[](idx);
314 }
315
323 template <class... Indices>
324 auto operator()(size_t idx, Indices... rest)
325 -> decltype(base_type::operator[](idx)(rest...)) {
326 static_assert(
327 sizeof...(Indices) < rank(), "Too Many Arguments!");
328 if (idx >= First)
329 throw MultiArrayError("index " + std::to_string(idx)
330 + " out of range [0, "
331 + std::to_string(First) + ')');
332 return base_type::operator[](idx)(rest...);
333 }
334
336 template <class... Indices>
337 auto operator()(size_t idx, Indices... rest) const
338 -> decltype(base_type::operator[](idx)(rest...)) {
339 static_assert(
340 sizeof...(Indices) < rank(), "Too Many Arguments!");
341 if (idx >= First)
342 throw MultiArrayError("index " + std::to_string(idx)
343 + " out of range [0, "
344 + std::to_string(First) + ')');
345 return base_type::operator[](idx)(rest...);
346 }
347
349 friend std::ostream &
350 operator<<(std::ostream &os, const MultiArray &ma) {
351 if (ma.begin() == ma.end()) return os << "[]";
352 auto it = ma.begin();
353 os << '[' << *it;
354 while (++it != ma.end()) {
355 os << ", " << *it;
356 }
357 return os << ']';
358 }
359
361 T *fbegin() { return this->data()->fbegin(); }
362
364 const T *fbegin() const { return this->data()->fbegin(); }
365
367 T *fend() { return this->fbegin() + this->fsize(); }
368
370 const T *fend() const { return this->fbegin() + this->fsize(); }
371
377 return reinterpret_cast<MultiArray<T, fsize()> &>(*this);
378 }
379
384 const MultiArray<T, fsize()> &flatten() const {
385
386 return reinterpret_cast<const MultiArray<T, fsize()> &>(*this);
387 }
388
393 static constexpr std::array<size_t, rank()> dims() {
394 return {First, Rest...};
395 }
396
402 template <size_t... Dims>
403 MultiArray<T, Dims...> &reshape() {
404 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
405 "reshape: total element count must match");
406 return *reinterpret_cast<MultiArray<T, Dims...> *>(this);
407 }
408
414 template <size_t... Dims>
415 const MultiArray<T, Dims...> &reshape() const {
416 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
417 "reshape: total element count must match");
418 return *reinterpret_cast<const MultiArray<T, Dims...> *>(this);
419 }
420 };
421 }
422
423#ifndef CONSOLE_MULTIARRAY_V1
424 inline
425#endif
426 namespace _V2 {
427
432 template <class T>
436
442 _multi_array_base(T *data, bool is_views) :
443 data_(data), is_views_(is_views) {}
444 };
445
460 template <class T, size_t... Dims>
462
469 template <class T, size_t D>
470 class MultiArray<T, D> : private _multi_array_base<T> {
471 public:
474
475 static constexpr size_t SIZE = D;
476
478 MultiArray(T *data, bool is_views) :
479 _multi_array_base<T>{data, is_views} {}
480
481 MultiArray(const T *data, bool is_views) :
482 _multi_array_base<T>{const_cast<T *>(data), is_views} {}
483
484 template <class U, size_t... Dims>
485 friend class MultiArray;
486
487 public:
488 using value_type = T;
489 using size_type = size_t;
490 using difference_type = ptrdiff_t;
492 using const_pointer = const value_type *;
496 using const_iterator = const value_type *;
497 using reverse_iterator = std::reverse_iterator<iterator>;
499 = std::reverse_iterator<const_iterator>;
500
502 MultiArray() : _multi_array_base<T>{new T[SIZE], false} {}
503
507 */
508 MultiArray(const T &value) :
509 _multi_array_base<T>{new T[SIZE], false} {
510 std::fill(data_, data_ + SIZE, value);
511 }
512
516 */
517 MultiArray(std::initializer_list<T> init) :
518 _multi_array_base<T>{new T[SIZE], false} {
519 std::copy(init.begin(), init.end(), data_);
520 }
521
525 */
526 MultiArray(const MultiArray &other) :
527 _multi_array_base<T>{new T[SIZE], false} {
528 std::copy(other.data_, other.data_ + SIZE, data_);
529 }
530
535 */
536 MultiArray(MultiArray &&other) noexcept :
537 _multi_array_base<T>{other.data_, other.is_views_} {
538 other.is_views_ = true;
539 }
540
545 */
546 MultiArray &operator=(const MultiArray &other) {
547 if (this != &other) {
548 if (!is_views_) delete[] data_;
549 data_ = new T[SIZE];
550 std::copy(other.data_, other.data_ + SIZE, data_);
551 }
552 return *this;
553 }
554
560 */
561 MultiArray &operator=(MultiArray &&other) noexcept {
562 if (this != &other) {
563 if (!is_views_) delete[] data_;
564 data_ = other.data_;
565 is_views_ = other.is_views_;
566 other.data_ = nullptr;
567 }
568 return *this;
569 }
570
575 MultiArray clone() const { return MultiArray(*this); }
576
577 /// @brief 析构,拥有者释放堆内存,视图不释放。
578 ~MultiArray() {
579 if (!is_views_) delete[] data_;
580 }
581
582 /// @brief 迭代器 begin,返回指向首元素的迭代器。
583 iterator begin() { //
584 return iterator(data_);
585 }
586 /// @brief 迭代器 end,返回指向尾元素的迭代器。
587 iterator end() { //
588 return iterator(data_ + SIZE);
589 }
590 /// @brief const迭代器 begin,返回指向首元素的 const 迭代器。
591 const_iterator begin() const { //
592 return const_iterator(data_);
593 }
594 /// @brief const迭代器 end,返回指向尾元素的 const 迭代器。
595 const_iterator end() const { //
596 return const_iterator(data_ + SIZE);
597 }
598 /// @brief 反向迭代器 rbegin,返回指向尾元素的反向迭代器。
600 return reverse_iterator(data_ + SIZE);
601 }
602 /// @brief 反向迭代器 rend,返回指向首元素的反向迭代器。
604 return reverse_iterator(data_);
605 }
606 /// @brief const 反向迭代器 rbegin,返回指向尾元素的 const 反向迭代器。
609 }
610 /// @brief const 反向迭代器 rend,返回指向首元素的 const 反向迭代器。
613 }
614 /// @brief const 迭代器 cbegin,返回指向首元素的 const 迭代器。
615 const_iterator cbegin() const { //
616 return const_iterator(data_);
617 }
618 /// @brief const 迭代器 cend,返回指向尾元素的 const 迭代器。
619 const_iterator cend() const { //
620 return const_iterator(data_ + SIZE);
621 }
622 /// @brief const 反向迭代器 crbegin,返回指向尾元素的 const 反向迭代器。
625 }
626 /// @brief const 反向迭代器 crend,返回指向首元素的 const 反向迭代器。
629 }
630
632 T *fbegin() { return data_; }
634 const T *fbegin() const { return data_; }
636 T *fend() { return data_ + SIZE; }
638 const T *fend() const { return data_ + SIZE; }
639
641 static constexpr size_t rank() { return 1; }
643 static constexpr std::array<size_t, rank()> dims() { return {D}; }
645 static constexpr size_t fsize() { return SIZE; }
647 static constexpr bool fempty() { return SIZE == 0; }
649 static constexpr size_t fmax_size() { return SIZE; }
650
652 MultiArray<T, SIZE> &flatten() { return *this; }
653
655 const MultiArray<T, SIZE> &flatten() const { return *this; }
656
657 /// @brief 下标运算符,返回指向 index 位置的引用。
658 reference operator[](size_t index) { //
659 return data_[index];
660 }
661 /// @brief 下标运算符,返回指向 index 位置的 const 引用。
662 const_reference operator[](size_t index) const {
663 return data_[index];
664 }
665
671 */
672 reference at(size_t index) {
673 if (index >= D)
674 throw MultiArrayError("index " + std::to_string(index)
675 + " out of range [0, "
676 + std::to_string(D) + ')');
677 return data_[index];
678 }
684 */
685 const_reference at(size_t index) const {
686 if (index >= D)
687 throw MultiArrayError("index " + std::to_string(index)
688 + " out of range [0, "
689 + std::to_string(D) + ')');
690 return data_[index];
691 }
692
699 reference operator()(size_t index) { return at(index); }
706 const_reference operator()(size_t index) const { return at(index); }
707
709 reference front() { return operator[](0); }
711 const_reference front() const { return operator[](0); }
713 reference back() { return operator[](D - 1); }
715 const_reference back() const { return operator[](D - 1); }
716
718 static size_t size() { return D; }
720 static bool empty() { return D == 0; }
722 static size_t max_size() { return D; }
723
729 template <class CharT, class Traits>
730 friend std::basic_ostream<CharT, Traits> &operator<<(
731 std::basic_ostream<CharT, Traits> &os, const MultiArray &ma) {
732 if (ma.begin() == ma.end()) return os << "[]";
733 auto it = ma.begin();
734 os << '[';
735 repr(*it, os);
736 while (++it != ma.end()) {
737 os << ", ";
738 repr(*it, os);
739 }
740 return os << ']';
741 }
742
747 void fill(const T &value) { std::fill(data_, data_ + SIZE, value); }
748
754 template <class F>
755 void for_each(F f) {
756 std::for_each(data_, data_ + SIZE, f);
757 }
758
764 template <class F>
765 void for_each(F f) const {
766 std::for_each(data_, data_ + SIZE, f);
767 }
768
772 */
773 void swap(MultiArray &other) noexcept {
774 std::swap(data_, other.data_);
775 std::swap(is_views_, other.is_views_);
776 }
777
781 */
782 friend void swap(MultiArray &a, MultiArray &b) noexcept {
783 a.swap(b);
784 }
785
791 template <size_t... Dims>
792 MultiArray<T, Dims...> &reshape() {
793 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
794 "reshape: total element count must match");
795 return *reinterpret_cast<MultiArray<T, Dims...> *>(this);
796 }
797
803 template <size_t... Dims>
804 const MultiArray<T, Dims...> &reshape() const {
805 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
806 "reshape: total element count must match");
807 return *reinterpret_cast<const MultiArray<T, Dims...> *>(this);
808 }
809 };
810
818 template <class T, size_t First, size_t... Rest>
819 class MultiArray<T, First, Rest...> : private _multi_array_base<T> {
822
824 template <size_t... Is>
825 struct prod;
826
827 template <size_t I>
828 struct prod<I> {
829 static constexpr size_t value = I;
830 };
831
832 template <size_t I, size_t... Is>
833 struct prod<I, Is...> {
834 static constexpr size_t value = I * prod<Is...>::value;
835 };
836
837 static constexpr size_t SIZE = prod<First, Rest...>::value;
838
840 MultiArray(T *data, bool is_views) :
841 _multi_array_base<T>{data, is_views} {}
842
843 MultiArray(const T *data, bool is_views) :
844 _multi_array_base<T>{const_cast<T *>(data), is_views} {}
845
846 template <class U, size_t... Dims>
847 friend class MultiArray;
848
849 friend class iterator;
850 friend class const_iterator;
851
852 public:
858 class iterator {
860
861 public:
862 using iterator_category = std::random_access_iterator_tag;
863 using value_type = MultiArray<T, Rest...>;
864 using difference_type = ptrdiff_t;
865 using pointer = std::shared_ptr<value_type>;
867 explicit iterator(T *ptr) : ptr_(ptr) {}
868 reference operator*() const { return reference(ptr_, true); }
870 return pointer(new value_type(ptr_, true));
871 }
873 ptr_ += SIZE / First;
874 return *this;
875 }
877 auto tmp = *this;
878 ++*this;
879 return tmp;
880 }
882 ptr_ -= SIZE / First;
883 return *this;
884 }
886 auto tmp = *this;
887 --*this;
888 return tmp;
889 }
891 return reference(ptr_ + SIZE / First * n, true);
892 }
893 friend bool operator==(const iterator &a, const iterator &b) {
894 return a.ptr_ == b.ptr_;
895 }
896 friend bool operator!=(const iterator &a, const iterator &b) {
897 return a.ptr_ != b.ptr_;
898 }
899 friend bool operator<(const iterator &a, const iterator &b) {
900 return a.ptr_ < b.ptr_;
901 }
902 friend difference_type
903 operator-(const iterator &a, const iterator &b) {
904 return (a.ptr_ - b.ptr_) / (SIZE / First);
905 }
907 it.ptr_ += n * (SIZE / First);
908 return it;
909 }
911 it.ptr_ += n * (SIZE / First);
912 return it;
913 }
915 ptr_ += n * (SIZE / First);
916 return *this;
917 }
919 ptr_ -= n * (SIZE / First);
920 return *this;
921 }
922 };
923
929 const T *ptr_;
930
931 public:
932 using iterator_category = std::random_access_iterator_tag;
933 using value_type = const MultiArray<T, Rest...>;
934 using difference_type = ptrdiff_t;
935 using pointer = std::shared_ptr<value_type>;
937 explicit const_iterator(const T *ptr) : ptr_(ptr) {}
938 reference operator*() const { return reference(ptr_, true); }
940 return pointer(new value_type(ptr_, true));
941 }
943 ptr_ += SIZE / First;
944 return *this;
945 }
947 auto tmp = *this;
948 ++*this;
949 return tmp;
950 }
952 ptr_ -= SIZE / First;
953 return *this;
954 }
956 auto tmp = *this;
957 --*this;
958 return tmp;
959 }
961 return reference(ptr_ + SIZE / First * n, true);
962 }
963 friend bool
965 return a.ptr_ == b.ptr_;
966 }
967 friend bool
969 return a.ptr_ != b.ptr_;
970 }
971 friend bool
972 operator<(const const_iterator &a, const const_iterator &b) {
973 return a.ptr_ < b.ptr_;
974 }
975 friend difference_type
977 return (a.ptr_ - b.ptr_) / (SIZE / First);
978 }
979 friend const_iterator
981 it.ptr_ += n * (SIZE / First);
982 return it;
983 }
984 friend const_iterator
986 it.ptr_ += n * (SIZE / First);
987 return it;
988 }
990 ptr_ += n * (SIZE / First);
991 return *this;
992 }
994 ptr_ -= n * (SIZE / First);
995 return *this;
996 }
997 };
998
999 using value_type = MultiArray<T, Rest...>;
1000 using size_type = size_t;
1001 using difference_type = ptrdiff_t;
1003 using const_pointer = const value_type *;
1006 using reverse_iterator = std::reverse_iterator<iterator>;
1008 = std::reverse_iterator<const_iterator>;
1009
1011 MultiArray() : _multi_array_base<T>{new T[SIZE], false} {}
1012
1017 MultiArray(const T &value) :
1018 _multi_array_base<T>{new T[SIZE], false} {
1019 std::fill(data_, data_ + SIZE, value);
1020 }
1021
1026 MultiArray(std::initializer_list<T> init) :
1027 _multi_array_base<T>{new T[SIZE], false} {
1028 std::copy(init.begin(), init.end(), data_);
1029 }
1030
1035 MultiArray(std::initializer_list<MultiArray<T, Rest...>> init) :
1036 _multi_array_base<T>{new T[SIZE], false} {
1037 size_t offset = 0;
1038 for (const auto &sub : init) {
1039 std::copy(sub.fbegin(), sub.fend(), data_ + offset);
1040 offset += sub.fsize();
1041 }
1042 }
1043
1048 MultiArray(const MultiArray &other) :
1049 _multi_array_base<T>{new T[SIZE], false} {
1050 std::copy(other.data_, other.data_ + SIZE, data_);
1051 }
1052
1058 MultiArray(MultiArray &&other) noexcept :
1059 _multi_array_base<T>{other.data_, other.is_views_} {
1060 other.is_views_ = true;
1061 }
1062
1068 MultiArray &operator=(const MultiArray &other) {
1069 if (this != &other) {
1070 if (!is_views_) delete[] data_;
1071 data_ = new T[SIZE];
1072 std::copy(other.data_, other.data_ + SIZE, data_);
1073 }
1074 return *this;
1075 }
1076
1082 MultiArray &operator=(MultiArray &&other) noexcept {
1083 if (this != &other) {
1084 if (!is_views_) delete[] data_;
1085 data_ = other.data_;
1086 is_views_ = other.is_views_;
1087 other.data_ = nullptr;
1088 }
1089 return *this;
1090 }
1091
1096 MultiArray clone() const { return MultiArray(*this); }
1097
1098 /// @brief 析构,拥有者释放堆内存,视图不释放。
1099 ~MultiArray() {
1100 if (!is_views_) delete[] data_;
1101 }
1102
1103 /// @brief 迭代器 begin,返回指向首元素的迭代器。
1104 iterator begin() { //
1105 return iterator(data_);
1106 }
1107 /// @brief 迭代器 end,返回指向尾元素的迭代器。
1108 iterator end() { //
1109 return iterator(data_ + SIZE);
1110 }
1111 /// @brief const迭代器 begin,返回指向首元素的 const 迭代器。
1112 const_iterator begin() const { //
1113 return const_iterator(data_);
1114 }
1115 /// @brief const迭代器 end,返回指向尾元素的 const 迭代器。
1116 const_iterator end() const { //
1117 return const_iterator(data_ + SIZE);
1118 }
1119 /// @brief 反向迭代器 rbegin,返回指向尾元素的反向迭代器。
1121 return reverse_iterator(data_ + SIZE);
1122 }
1123 /// @brief 反向迭代器 rend,返回指向首元素的反向迭代器。
1124 reverse_iterator rend() { //
1125 return reverse_iterator(data_);
1126 }
1127 /// @brief const 反向迭代器 rbegin,返回指向尾元素的 const 反向迭代器。
1130 }
1131 /// @brief const 反向迭代器 rend,返回指向首元素的 const 反向迭代器。
1134 }
1135 /// @brief const 迭代器 cbegin,返回指向首元素的 const 迭代器。
1136 const_iterator cbegin() const { //
1137 return const_iterator(data_);
1138 }
1139 /// @brief const 迭代器 cend,返回指向尾元素的 const 迭代器。
1140 const_iterator cend() const { //
1141 return const_iterator(data_ + SIZE);
1142 }
1143 /// @brief const 反向迭代器 crbegin,返回指向尾元素的 const 反向迭代器。
1146 }
1147 /// @brief const 反向迭代器 crend,返回指向首元素的 const 反向迭代器。
1150 }
1151
1153 T *fbegin() { return data_; }
1155 const T *fbegin() const { return data_; }
1157 T *fend() { return data_ + SIZE; }
1159 const T *fend() const { return data_ + SIZE; }
1160
1162 static constexpr size_t rank() { return 1 + sizeof...(Rest); }
1163 /// @brief 静态成员函数 dims,返回数组的维度数组。
1164 static constexpr std::array<size_t, rank()> dims() {
1165 return {First, Rest...};
1166 }
1168 static constexpr size_t fsize() { return SIZE; }
1170 static constexpr bool fempty() { return SIZE == 0; }
1172 static constexpr size_t fmax_size() { return SIZE; }
1173
1180 return *reinterpret_cast<MultiArray<T, SIZE> *>(this);
1181 }
1187 const MultiArray<T, SIZE> &flatten() const {
1188 return *reinterpret_cast<const MultiArray<T, SIZE> *>(this);
1189 }
1190
1197 reference operator[](size_t index) {
1198 return reference(data_ + SIZE / First * index, true);
1199 }
1206 const_reference operator[](size_t index) const {
1207 return const_reference(data_ + SIZE / First * index, true);
1208 }
1209
1216 reference at(size_t index) {
1217 if (index >= First)
1218 throw MultiArrayError("index " + std::to_string(index)
1219 + " out of range [0, "
1220 + std::to_string(First) + ')');
1221 return operator[](index);
1222 }
1229 const_reference at(size_t index) const {
1230 if (index >= First)
1231 throw MultiArrayError("index " + std::to_string(index)
1232 + " out of range [0, "
1233 + std::to_string(First) + ')');
1234 return operator[](index);
1235 }
1236
1243 reference operator()(size_t index) { return at(index); }
1250 const_reference operator()(size_t index) const { return at(index); }
1251
1260 template <class... Indices>
1261 auto operator()(size_t idx, Indices... rest) //
1262 -> decltype(at(idx)(rest...)) {
1263 static_assert(
1264 sizeof...(Indices) < rank(), "Too Many Arguments!");
1265 return at(idx)(rest...);
1266 }
1275 template <class... Indices>
1276 auto operator()(size_t idx, Indices... rest) const //
1277 -> decltype(at(idx)(rest...)) {
1278 static_assert(
1279 sizeof...(Indices) < rank(), "Too Many Arguments!");
1280 return at(idx)(rest...);
1281 }
1282
1284#if __cplusplus >= 202302L
1293 template <class... Indices>
1294 auto operator[](size_t idx, Indices... rest) //
1295 -> decltype(operator[](idx)[rest...]) {
1296 static_assert(
1297 sizeof...(Indices) < rank(), "Too Many Arguments!");
1298 return operator[](idx)[rest...];
1299 }
1308 template <class... Indices>
1309 auto operator[](size_t idx, Indices... rest) const //
1310 -> decltype(operator[](idx)[rest...]) {
1311 static_assert(
1312 sizeof...(Indices) < rank(), "Too Many Arguments!");
1313 return operator[](idx)[rest...];
1314 }
1315#endif
1316
1318 reference front() { return operator[](0); }
1320 const_reference front() const { return operator[](0); }
1322 reference back() { return operator[](First - 1); }
1324 const_reference back() const { return operator[](First - 1); }
1325
1327 static size_t size() { return First; }
1329 static bool empty() { return First == 0; }
1331 static size_t max_size() { return First; }
1332
1338 template <class CharT, class Traits>
1339 friend std::basic_ostream<CharT, Traits> &operator<<(
1340 std::basic_ostream<CharT, Traits> &os, const MultiArray &ma) {
1341 if (ma.begin() == ma.end()) return os << "[]";
1342 auto it = ma.begin();
1343 os << '[';
1344 repr(*it, os);
1345 while (++it != ma.end()) {
1346 os << ", ";
1347 repr(*it, os);
1348 }
1349 return os << ']';
1350 }
1351
1356 void fill(const T &value) { std::fill(data_, data_ + SIZE, value); }
1357
1363 template <class F>
1364 void for_each(F f) {
1365 std::for_each(data_, data_ + SIZE, f);
1366 }
1367
1373 template <class F>
1374 void for_each(F f) const {
1375 std::for_each(data_, data_ + SIZE, f);
1376 }
1377
1382 void swap(MultiArray &other) noexcept {
1383 std::swap(data_, other.data_);
1384 std::swap(is_views_, other.is_views_);
1385 }
1386
1391 friend void swap(MultiArray &a, MultiArray &b) noexcept {
1392 a.swap(b);
1393 }
1394
1400 template <size_t... Dims>
1401 MultiArray<T, Dims...> &reshape() {
1402 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
1403 "reshape: total element count must match");
1404 return *reinterpret_cast<MultiArray<T, Dims...> *>(this);
1405 }
1406
1412 template <size_t... Dims>
1413 const MultiArray<T, Dims...> &reshape() const {
1414 static_assert(MultiArray<T, Dims...>::fsize() == fsize(),
1415 "reshape: total element count must match");
1416 return *reinterpret_cast<const MultiArray<T, Dims...> *>(this);
1417 }
1418 };
1419 }
1420
1421 // clang-format off
1422#define ARRAY_AND_ARRAY(OP) \
1423 template <class T, class U, size_t... Dims> \
1424 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1425 operator OP(const MultiArray<T, Dims...> &a, \
1426 const MultiArray<U, Dims...> &b) { \
1427 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1428 c; \
1429 auto ai = a.fbegin(); \
1430 auto bi = b.fbegin(); \
1431 auto ci = c.fbegin(); \
1432 while (ci != c.fend()) *ci++ = *ai++ OP *bi++; \
1433 return c; \
1434 }
1435
1436#define ARRAY_AND_SCALAR(OP) \
1437 template <class T, class U, size_t... Dims> \
1438 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1439 operator OP(const MultiArray<T, Dims...> &a, const U &b) { \
1440 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1441 c; \
1442 auto ai = a.fbegin(); \
1443 auto ci = c.fbegin(); \
1444 while (ci != c.fend()) *ci++ = *ai++ OP b; \
1445 return c; \
1446 }
1447
1448#define SCALAR_AND_ARRAY(OP) \
1449 template <class T, class U, size_t... Dims> \
1450 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1451 operator OP(const U &a, const MultiArray<T, Dims...> &b) { \
1452 MultiArray<decltype(std::declval<T>() OP std::declval<U>()), Dims...> \
1453 c; \
1454 auto bi = b.fbegin(); \
1455 auto ci = c.fbegin(); \
1456 while (ci != c.fend()) *ci++ = a OP *bi++; \
1457 return c; \
1458 }
1459
1460#define ARRAY_AND_ARRAY_INPLACE(OP) \
1461 template <class T, class U, size_t... Dims> \
1462 MultiArray<T, Dims...> & operator OP( \
1463 MultiArray<T, Dims...> &a, \
1464 const MultiArray<U, Dims...> &b) { \
1465 auto ai = a.fbegin(); \
1466 auto bi = b.fbegin(); \
1467 while (ai != a.fend()) *ai++ OP *bi++; \
1468 return a;\
1469 }
1470
1471#define ARRAY_AND_SCALAR_INPLACE(OP) \
1472 template <class T, class U, size_t... Dims> \
1473 MultiArray<T, Dims...> & operator OP(MultiArray<T, Dims...> &a, \
1474 const U &b) { \
1475 auto ai = a.fbegin(); \
1476 while (ai != a.fend()) *ai++ OP b; \
1477 return a; \
1478 }
1479
1480#define ARRAY_AND_ARRAY_BOOL(OP) \
1481 template <class T, class U, size_t... Dims> \
1482 MultiArray<bool, Dims...> \
1483 operator OP(const MultiArray<T, Dims...> &a, \
1484 const MultiArray<U, Dims...> &b) { \
1485 MultiArray<bool, Dims...> c; \
1486 auto ai = a.fbegin(); \
1487 auto bi = b.fbegin(); \
1488 auto ci = c.fbegin(); \
1489 while (ci != c.fend()) *ci++ = *ai++ OP *bi++; \
1490 return c; \
1491 }
1492
1493#define ARRAY_AND_SCALAR_BOOL(OP) \
1494 template <class T, class U, size_t... Dims> \
1495 MultiArray<bool, Dims...> \
1496 operator OP(const MultiArray<T, Dims...> &a, const U &b) { \
1497 MultiArray<bool, Dims...> c; \
1498 auto ai = a.fbegin(); \
1499 auto ci = c.fbegin(); \
1500 while (ci != c.fend()) *ci++ = *ai++ OP b; \
1501 return c; \
1502 }
1503
1504#define SCALAR_AND_ARRAY_BOOL(OP) \
1505 template <class T, class U, size_t... Dims> \
1506 MultiArray<bool, Dims...> \
1507 operator OP(const U &a, const MultiArray<T, Dims...> &b) { \
1508 MultiArray<bool, Dims...> c; \
1509 auto bi = b.fbegin(); \
1510 auto ci = c.fbegin(); \
1511 while (ci != c.fend()) *ci++ = a OP *bi++; \
1512 return c; \
1513 }
1514
1515#define UNARY_ARRAY(OP) \
1516 template <class T, size_t... Dims> \
1517 MultiArray<decltype(OP std::declval<T>()), Dims...> \
1518 operator OP(const MultiArray<T, Dims...> &a) { \
1519 MultiArray<decltype(OP std::declval<T>()), Dims...> c; \
1520 auto ai = a.fbegin(); \
1521 auto ci = c.fbegin(); \
1522 while (ci != c.fend()) *ci++ = OP *ai++; \
1523 return c; \
1524 }
1525
1526#define UNARY_ARRAY_BOOL(OP) \
1527 template <class T, size_t... Dims> \
1528 MultiArray<bool, Dims...> \
1529 operator OP(const MultiArray<T, Dims...> &a) { \
1530 MultiArray<bool, Dims...> c; \
1531 auto ai = a.fbegin(); \
1532 auto ci = c.fbegin(); \
1533 while (ci != c.fend()) *ci++ = OP *ai++; \
1534 return c; \
1535 }
1536 // clang-format on
1537
1543
1549
1555
1562
1568
1574
1578
1580
1587
1594
1597
1600
1603
1609
1615
1621
1626
1627 // SCALAR_AND_ARRAY(<<)
1628 template <class T, class U, size_t... Dims>
1629 typename std::enable_if<!std::is_base_of<std::ios_base, U>::value,
1630 MultiArray<decltype(std::declval<U>() << std::declval<T>()),
1631 Dims...>>::type
1632 operator<<(const U &value, const MultiArray<T, Dims...> &a) {
1633 MultiArray<decltype(std::declval<U>() << std::declval<T>()), Dims...> b;
1634 auto ai = a.fbegin();
1635 auto bi = b.fbegin();
1636 while (bi != b.fend()) *bi++ = value << *ai++;
1637 return b;
1638 }
1639
1645
1646#undef ARRAY_AND_ARRAY
1647#undef ARRAY_AND_SCALAR
1648#undef SCALAR_AND_ARRAY
1649#undef ARRAY_AND_ARRAY_INPLACE
1650#undef ARRAY_AND_SCALAR_INPLACE
1651#undef ARRAY_AND_ARRAY_BOOL
1652#undef ARRAY_AND_SCALAR_BOOL
1653#undef SCALAR_AND_ARRAY_BOOL
1654#undef UNARY_ARRAY
1655#undef UNARY_ARRAY_BOOL
1656
1664 template <class T, size_t... Dims>
1666 T result{};
1667 a.for_each([&](const T &ref) { result += ref; });
1668 return result;
1669 }
1670
1675 template <class T, size_t... Dims>
1677 return *std::min_element(a.fbegin(), a.fend());
1678 }
1679
1684 template <class T, size_t... Dims>
1686 return *std::max_element(a.fbegin(), a.fend());
1687 }
1688
1693 template <class T, size_t... Dims>
1695 for (auto it = a.fbegin(); it != a.fend(); ++it)
1696 if (!*it) return false;
1697 return true;
1698 }
1699
1704 template <class T, size_t... Dims>
1706 for (auto it = a.fbegin(); it != a.fend(); ++it)
1707 if (*it) return true;
1708 return false;
1709 }
1710
1715 template <class T, class U, size_t... Dims>
1716 bool
1718 for (size_t i = 0; i < a.fsize(); ++i)
1719 if (a[i] != b[i]) return false;
1720 return true;
1721 }
1722
1727 template <class T, class U, size_t... Dims1, size_t... Dims2>
1728 constexpr bool
1730 return false;
1731 }
1732
1737 template <class T, class U, size_t... Dims, class Op>
1739 const MultiArray<U, Dims...> &b,
1740 Op &&op) {
1741 for (size_t i = 0; i < a.fsize(); ++i)
1742 if (!op(a[i], b[i])) return false;
1743 return true;
1744 }
1745
1750 template <class T, class U, size_t... Dims1, size_t... Dims2, class Op>
1751 constexpr bool equals(const MultiArray<T, Dims1...> &,
1753 Op &&) {
1754 return false;
1755 }
1756
1761 template <class T, class U, size_t... Dims>
1762 int
1764 for (auto it1 = a.fbegin(), it2 = b.fbegin(); //
1765 it1 != a.fend(); //
1766 ++it1, ++it2) {
1767 if (*it1 < *it2) return -1;
1768 if (*it2 < *it1) return 1;
1769 }
1770 return 0;
1771 }
1772}
const T & const_reference
Definition multiarray.h:81
static constexpr size_t fsize()
返回元素总数。
Definition multiarray.h:107
void for_each(F &&visit)
遍历所有元素并应用函数(非常量版本)。
Definition multiarray.h:120
const MultiArray & flatten() const
扁平化视图(常量)。
Definition multiarray.h:193
const_reference operator()(size_t i) const
常量版本。
Definition multiarray.h:149
static constexpr std::array< size_t, 1 > dims()
返回包含维度信息的数组。
Definition multiarray.h:199
void fill(const T &value)
用给定值填充所有元素。
Definition multiarray.h:110
MultiArray(const base_type &other)
从 std::array 拷贝构造。
Definition multiarray.h:93
friend std::ostream & operator<<(std::ostream &os, const MultiArray &ma)
输出 MultiArray 到流,格式为嵌套的方括号。
Definition multiarray.h:159
MultiArray(const T &value)
用相同值填充所有元素。
Definition multiarray.h:90
T * fbegin()
返回指向扁平化数据起始的指针(非常量)。
Definition multiarray.h:172
const MultiArray< T, Dims... > & reshape() const
重新调整数组的形状(const版本)。
Definition multiarray.h:219
MultiArray< T, Dims... > & reshape()
重新调整数组的形状。
Definition multiarray.h:207
const T * fend() const
常量版本。
Definition multiarray.h:181
std::array< T, D > base_type
Definition multiarray.h:76
reference operator()(size_t i)
带边界检查的下标访问(一维)。
Definition multiarray.h:140
T * fend()
返回指向扁平化数据末尾的指针(非常量)。
Definition multiarray.h:178
const T * fbegin() const
常量版本。
Definition multiarray.h:175
T value_type
Definition multiarray.h:79
MultiArray()=default
默认构造,元素未初始化(基本类型为随机值)。
void for_each(F &&visit) const
遍历所有元素并应用函数(常量版本)。
Definition multiarray.h:130
MultiArray & flatten()
扁平化视图(可变)。
Definition multiarray.h:187
T & reference
Definition multiarray.h:80
MultiArray(std::initializer_list< T > init)
从初始化列表构造(仅一维)。
Definition multiarray.h:99
static constexpr size_t rank()
返回数组的维数(一维时为 1)。
Definition multiarray.h:104
MultiArray< T, Rest... > & reference
Definition multiarray.h:239
std::array< MultiArray< T, Rest... >, First > base_type
Definition multiarray.h:235
static constexpr std::array< size_t, rank()> dims()
返回包含维度信息的数组。
Definition multiarray.h:393
void for_each(F &&visit)
遍历所有元素(非常量版本)。
Definition multiarray.h:280
static constexpr size_t rank()
返回数组维数。
Definition multiarray.h:263
auto operator()(size_t idx, Indices... rest) const -> decltype(base_type::operator[](idx)(rest...))
常量版本。
Definition multiarray.h:337
friend std::ostream & operator<<(std::ostream &os, const MultiArray &ma)
输出 MultiArray 到流,递归输出嵌套方括号。
Definition multiarray.h:350
T * fend()
扁平化结束迭代器(非常量)。
Definition multiarray.h:367
MultiArray(std::initializer_list< MultiArray< T, Rest... > > init)
从初始化列表构造(多维)。
Definition multiarray.h:258
MultiArray< T, fsize()> & flatten()
扁平化视图(可变)。
Definition multiarray.h:376
const T * fbegin() const
常量版本。
Definition multiarray.h:364
void fill(const T &value)
递归填充所有元素。
Definition multiarray.h:271
const MultiArray< T, Rest... > & const_reference
Definition multiarray.h:240
const MultiArray< T, Dims... > & reshape() const
重新调整数组的形状(const版本)。
Definition multiarray.h:415
void for_each(F &&visit) const
遍历所有元素(常量版本)。
Definition multiarray.h:289
T * fbegin()
扁平化起始迭代器(非常量)。
Definition multiarray.h:361
MultiArray< T, Rest... > value_type
Definition multiarray.h:238
const MultiArray< T, fsize()> & flatten() const
扁平化视图(常量)。
Definition multiarray.h:384
static constexpr size_t fsize()
返回元素总数。
Definition multiarray.h:266
const T * fend() const
常量版本。
Definition multiarray.h:370
MultiArray(const base_type &other)
从 std::array 拷贝构造。
Definition multiarray.h:252
reference operator()(size_t idx)
单下标访问,返回子数组引用。
Definition multiarray.h:299
auto operator()(size_t idx, Indices... rest) -> decltype(base_type::operator[](idx)(rest...))
多维下标访问。
Definition multiarray.h:324
MultiArray(const T &value)
用相同值递归填充所有元素。
Definition multiarray.h:249
const_reference operator()(size_t idx) const
常量版本。
Definition multiarray.h:308
MultiArray< T, Dims... > & reshape()
重新调整数组的形状。
Definition multiarray.h:403
编译期固定维度的多维数组。
Definition multiarray.h:67
size_t size_type
Definition multiarray.h:489
const_iterator cbegin() const
const 迭代器 cbegin,返回指向首元素的 const 迭代器。
Definition multiarray.h:614
static constexpr size_t SIZE
< 是否为视图
Definition multiarray.h:475
reverse_iterator rend()
反向迭代器 rend,返回指向首元素的反向迭代器。
Definition multiarray.h:602
static constexpr size_t rank()
维度,返回 1。
Definition multiarray.h:640
static size_t max_size()
第一维最大大小,返回 D。
Definition multiarray.h:721
const_reverse_iterator crend() const
const 反向迭代器 crend,返回指向首元素的 const 反向迭代器。
Definition multiarray.h:626
static size_t size()
第一维元素数量,返回 D。
Definition multiarray.h:717
reference operator[](size_t index)
下标运算符,返回指向 index 位置的引用。
Definition multiarray.h:657
const_reverse_iterator crbegin() const
const 反向迭代器 crbegin,返回指向尾元素的 const 反向迭代器。
Definition multiarray.h:622
std::reverse_iterator< iterator > reverse_iterator
Definition multiarray.h:497
T * fbegin()
扁平化迭代器,返回指向首元素的指针。
Definition multiarray.h:631
void for_each(F f)
遍历所有元素并应用函数。
Definition multiarray.h:754
void swap(MultiArray &other) noexcept
交换两个数组的内容。
Definition multiarray.h:772
iterator begin()
迭代器 begin,返回指向首元素的迭代器。
Definition multiarray.h:582
static constexpr bool fempty()
扁平化是否为空,返回 SIZE == 0。
Definition multiarray.h:646
static constexpr size_t fsize()
扁平化大小,返回 SIZE。
Definition multiarray.h:644
MultiArray< T, Dims... > & reshape()
重新调整数组的形状。
Definition multiarray.h:791
value_type & reference
Definition multiarray.h:493
T value_type
Definition multiarray.h:488
value_type * pointer
Definition multiarray.h:491
const value_type * const_pointer
Definition multiarray.h:492
static bool empty()
第一维是否为空,返回 D == 0。
Definition multiarray.h:719
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition multiarray.h:498
MultiArray(const T *data, bool is_views)
私有构造函数,const 版本,仅供 const 视图使用。
Definition multiarray.h:481
reference at(size_t index)
带边界检查的下标访问。
Definition multiarray.h:671
iterator end()
迭代器 end,返回指向尾元素的迭代器。
Definition multiarray.h:586
MultiArray< T, SIZE > & flatten()
扁平化视图,一维数组返回自身。
Definition multiarray.h:651
const value_type * const_iterator
Definition multiarray.h:496
reverse_iterator rbegin()
反向迭代器 rbegin,返回指向尾元素的反向迭代器。
Definition multiarray.h:598
ptrdiff_t difference_type
Definition multiarray.h:490
value_type * iterator
Definition multiarray.h:495
friend class MultiArray
Definition multiarray.h:485
reference operator()(size_t index)
带边界检查的下标访问。
Definition multiarray.h:698
void fill(const T &value)
用给定值填充所有元素。
Definition multiarray.h:746
MultiArray clone() const
显式深拷贝,返回独立拥有者。
Definition multiarray.h:574
static constexpr std::array< size_t, rank()> dims()
维度数组,返回 {D}。
Definition multiarray.h:642
static constexpr size_t fmax_size()
扁平化最大大小,返回 SIZE。
Definition multiarray.h:648
reference front()
访问第一个元素。
Definition multiarray.h:708
const value_type & const_reference
Definition multiarray.h:494
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MultiArray &ma)
流输出,格式为嵌套方括号。
Definition multiarray.h:729
MultiArray & operator=(const MultiArray &other)
拷贝赋值,深拷贝,目标变为拥有者。
Definition multiarray.h:545
T * fend()
扁平化迭代器,返回指向尾元素的指针。
Definition multiarray.h:635
const_iterator cend() const
const 迭代器 cend,返回指向尾元素的 const 迭代器。
Definition multiarray.h:618
reference back()
访问最后一个元素。
Definition multiarray.h:712
MultiArray(T *data, bool is_views)
私有构造函数,仅供视图创建使用。
Definition multiarray.h:478
const 随机访问迭代器。
Definition multiarray.h:928
ptrdiff_t difference_type
Definition multiarray.h:934
const_iterator & operator--()
Definition multiarray.h:951
const_iterator & operator-=(difference_type n)
Definition multiarray.h:993
pointer operator->() const
Definition multiarray.h:939
const_iterator & operator+=(difference_type n)
Definition multiarray.h:989
const_iterator operator--(int)
Definition multiarray.h:955
const_iterator(const T *ptr)
Definition multiarray.h:937
const_iterator operator++(int)
Definition multiarray.h:946
std::shared_ptr< value_type > pointer
Definition multiarray.h:935
friend bool operator!=(const const_iterator &a, const const_iterator &b)
Definition multiarray.h:968
friend const_iterator operator+(const_iterator it, difference_type n)
Definition multiarray.h:980
friend bool operator==(const const_iterator &a, const const_iterator &b)
Definition multiarray.h:964
friend const_iterator operator+(difference_type n, const_iterator it)
Definition multiarray.h:985
std::random_access_iterator_tag iterator_category
Definition multiarray.h:932
reference operator*() const
Definition multiarray.h:938
friend bool operator<(const const_iterator &a, const const_iterator &b)
Definition multiarray.h:972
reference operator[](difference_type n) const
Definition multiarray.h:960
const_iterator & operator++()
Definition multiarray.h:942
friend difference_type operator-(const const_iterator &a, const const_iterator &b)
Definition multiarray.h:976
const MultiArray< T, Rest... > value_type
Definition multiarray.h:933
随机访问迭代器,遍历第一维的子数组。
Definition multiarray.h:858
reference operator[](difference_type n) const
Definition multiarray.h:890
iterator & operator--()
Definition multiarray.h:881
iterator & operator++()
Definition multiarray.h:872
value_type reference
Definition multiarray.h:866
reference operator*() const
Definition multiarray.h:868
friend bool operator!=(const iterator &a, const iterator &b)
Definition multiarray.h:896
friend iterator operator+(iterator it, difference_type n)
Definition multiarray.h:906
MultiArray< T, Rest... > value_type
Definition multiarray.h:863
iterator & operator-=(difference_type n)
Definition multiarray.h:918
friend bool operator==(const iterator &a, const iterator &b)
Definition multiarray.h:893
friend difference_type operator-(const iterator &a, const iterator &b)
Definition multiarray.h:903
iterator operator++(int)
Definition multiarray.h:876
iterator operator--(int)
Definition multiarray.h:885
std::shared_ptr< value_type > pointer
Definition multiarray.h:865
friend iterator operator+(difference_type n, iterator it)
Definition multiarray.h:910
ptrdiff_t difference_type
Definition multiarray.h:864
friend bool operator<(const iterator &a, const iterator &b)
Definition multiarray.h:899
iterator & operator+=(difference_type n)
Definition multiarray.h:914
std::random_access_iterator_tag iterator_category
Definition multiarray.h:862
pointer operator->() const
Definition multiarray.h:869
reverse_iterator rbegin()
反向迭代器 rbegin,返回指向尾元素的反向迭代器。
Definition multiarray.h:1119
static constexpr size_t SIZE
Definition multiarray.h:837
static constexpr bool fempty()
静态成员函数 fempty,返回数组是否为空。
Definition multiarray.h:1169
const value_type const_reference
const 视图
Definition multiarray.h:1005
reference back()
访问最后一个子数组。
Definition multiarray.h:1321
reference at(size_t index)
带边界检查的子数组访问。
Definition multiarray.h:1215
value_type reference
视图(值类型)
Definition multiarray.h:1004
ptrdiff_t difference_type
Definition multiarray.h:1001
const value_type * const_pointer
Definition multiarray.h:1003
reference operator()(size_t index)
带边界检查的子数组访问。
Definition multiarray.h:1242
std::reverse_iterator< iterator > reverse_iterator
Definition multiarray.h:1006
const_reverse_iterator crbegin() const
const 反向迭代器 crbegin,返回指向尾元素的 const 反向迭代器。
Definition multiarray.h:1143
const_iterator cbegin() const
const 迭代器 cbegin,返回指向首元素的 const 迭代器。
Definition multiarray.h:1135
static constexpr size_t fsize()
静态成员函数 fsize,返回数组的元素个数。
Definition multiarray.h:1167
void swap(MultiArray &other) noexcept
交换两个数组的内容。
Definition multiarray.h:1381
void for_each(F f)
遍历所有元素并应用函数。
Definition multiarray.h:1363
static size_t size()
第一维元素数量,返回 First。
Definition multiarray.h:1326
MultiArray(const T *data, bool is_views)
私有构造函数,const 版本。
Definition multiarray.h:843
static constexpr size_t rank()
静态成员函数 rank,返回数组的维度。
Definition multiarray.h:1161
size_t size_type
Definition multiarray.h:1000
const_reverse_iterator crend() const
const 反向迭代器 crend,返回指向首元素的 const 反向迭代器。
Definition multiarray.h:1147
MultiArray clone() const
显式深拷贝,返回独立拥有者。
Definition multiarray.h:1095
reverse_iterator rend()
反向迭代器 rend,返回指向首元素的反向迭代器。
Definition multiarray.h:1123
iterator end()
迭代器 end,返回指向尾元素的迭代器。
Definition multiarray.h:1107
const_iterator cend() const
const 迭代器 cend,返回指向尾元素的 const 迭代器。
Definition multiarray.h:1139
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition multiarray.h:1007
reference front()
若是C++23及以上版本,提供不进行边界检查的多维下标访问。
Definition multiarray.h:1317
reference operator[](size_t index)
访问第一维的子数组。
Definition multiarray.h:1196
value_type * pointer
Definition multiarray.h:1002
MultiArray< T, Dims... > & reshape()
重新调整数组的形状。
Definition multiarray.h:1400
MultiArray & operator=(const MultiArray &other)
拷贝赋值,深拷贝。
Definition multiarray.h:1067
MultiArray(T *data, bool is_views)
私有构造函数,仅供视图创建使用。
Definition multiarray.h:840
MultiArray< T, Rest... > value_type
Definition multiarray.h:999
friend class MultiArray
Definition multiarray.h:847
MultiArray< T, SIZE > & flatten()
扁平化视图,将多维数组视为一维数组。
Definition multiarray.h:1178
void fill(const T &value)
用给定值填充所有元素。
Definition multiarray.h:1355
static constexpr size_t fmax_size()
静态成员函数 fmax_size,返回数组的最大元素个数。
Definition multiarray.h:1171
T * fbegin()
扁平迭代器 fbegin,返回指向首元素的指针。
Definition multiarray.h:1152
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MultiArray &ma)
流输出,递归输出嵌套方括号。
Definition multiarray.h:1338
static bool empty()
第一维是否为空,返回 First == 0。
Definition multiarray.h:1328
iterator begin()
迭代器 begin,返回指向首元素的迭代器。
Definition multiarray.h:1103
static size_t max_size()
第一维最大大小,返回 First。
Definition multiarray.h:1330
static constexpr std::array< size_t, rank()> dims()
静态成员函数 dims,返回数组的维度数组。
Definition multiarray.h:1163
T * fend()
扁平迭代器 fend,返回指向尾元素的指针。
Definition multiarray.h:1156
编译期固定维度的多维数组(堆版本)。
Definition multiarray.h:461
MultiArrayError(const std::string &msg)
构造 MultiArrayError。
Definition csexc.h:127
定义 console 库使用的自定义异常类层次结构。
std::enable_if< is_string< typenamestd::decay< T >::type >::value >::type repr(T &&value, std::basic_ostream< CharT, Traits > &os=std::cout)
输出字符串类型(std::string, const char* 等)的表示,带双引号。
Definition repr.h:97
#define ARRAY_AND_ARRAY_BOOL(OP)
Definition multiarray.h:1480
#define UNARY_ARRAY_BOOL(OP)
Definition multiarray.h:1526
#define ARRAY_AND_SCALAR_BOOL(OP)
Definition multiarray.h:1493
#define ARRAY_AND_SCALAR_INPLACE(OP)
Definition multiarray.h:1471
#define ARRAY_AND_ARRAY(OP)
Definition multiarray.h:1422
#define ARRAY_AND_ARRAY_INPLACE(OP)
Definition multiarray.h:1460
#define ARRAY_AND_SCALAR(OP)
Definition multiarray.h:1436
#define SCALAR_AND_ARRAY(OP)
Definition multiarray.h:1448
#define UNARY_ARRAY(OP)
Definition multiarray.h:1515
#define SCALAR_AND_ARRAY_BOOL(OP)
Definition multiarray.h:1504
Definition multiarray.h:54
Definition multiarray.h:426
本库所有组件所在的顶层命名空间。
bool all(const MultiArray< T, Dims... > &a)
检查所有元素是否都为 true(逻辑与归约)。
Definition multiarray.h:1694
T min(const MultiArray< T, Dims... > &a)
求最小值。
Definition multiarray.h:1676
bool any(const MultiArray< T, Dims... > &a)
检查是否存在至少一个 true 元素(逻辑或归约)。
Definition multiarray.h:1705
T max(const MultiArray< T, Dims... > &a)
求最大值。
Definition multiarray.h:1685
@ U
Definition kb.h:100
@ T
Definition kb.h:99
@ D
Definition kb.h:83
int compare(const MultiArray< T, Dims... > &a, const MultiArray< U, Dims... > &b)
比较两个 MultiArray 的大小。
Definition multiarray.h:1763
T sum(const MultiArray< T, Dims... > &a)
求和所有元素。
Definition multiarray.h:1665
bool equals(const MultiArray< T, Dims... > &a, const MultiArray< U, Dims... > &b)
检查两个 MultiArray 是否相等。
Definition multiarray.h:1717
提供类似 Python 的 repr() 函数,用于生成对象的可读字符串表示。
编译期固定维度的多维数组元数据。
Definition multiarray.h:433
T * data_
指向堆内存数据的指针
Definition multiarray.h:434
_multi_array_base(T *data, bool is_views)
构造函数。
Definition multiarray.h:442
bool is_views_
true 表示视图(不拥有数据),false 表示拥有者
Definition multiarray.h:435
static constexpr size_t value
Definition multiarray.h:834
static constexpr size_t value
Definition multiarray.h:829
< 是否为视图
Definition multiarray.h:825