libzed 1.12.3
A general-purpose library for quick and simple data manipulation.
Loading...
Searching...
No Matches
array.hpp
1#pragma once
2
3#include <algorithm>
4#include <functional>
5#include <initializer_list>
6#include <random>
7#include <stdexcept>
8#include <vector>
9
10#include "arrayLike.hpp"
11#include "compare.hpp"
12#include "sizable.hpp"
13#include "typeChecks.hpp"
14
15#ifdef __has_include
16#if __has_include(<cereal/cereal.hpp>)
17#include <cereal/archives/json.hpp>
18#include <cereal/archives/xml.hpp>
19#endif
20#endif
21
22namespace z {
23namespace core {
37template <typename T>
38class array : public sizable, public arrayLike<const T &, T *> {
39protected:
41 std::vector<T> array_data;
42
47 inline void init(const T &arg1) {
48 add(arg1);
49 }
50
56 template <typename... Args>
57 inline void init(const T &arg1, const Args &...args) {
58 add(arg1);
59 init(args...);
60 }
61
74 virtual bool eq(const T &arg1, const T &arg2) const {
75 return equals(arg1, arg2);
76 }
77
90 virtual bool gt(const T &arg1, const T &arg2) const {
91 return greater(arg1, arg2);
92 }
93
106 virtual bool lt(const T &arg1, const T &arg2) const {
107 return lesser(arg1, arg2);
108 }
109
110public:
112 array() {}
113
115 array(const array &other);
116
118 array(const std::vector<T> &other);
119
132 template <typename... Args>
133 array(const T &arg1, const Args &...args);
134
140 array(const std::initializer_list<T> &other) : array_data(other) {}
141
143 virtual ~array() {}
144
145 inline void clear();
146
155 void increase(int newSize) noexcept {
156 array_data.reserve(newSize);
157 }
158
171 virtual int add(const T &object) {
172 array_data.push_back(object);
173
174 return (array_data.size() - 1);
175 }
176
187 void add(const array &other) noexcept {
188 for (auto i : other.array_data) {
189 array_data.push_back(i);
190 }
191 }
192
205 inline int push(const T &object) noexcept {
206 return add(object);
207 }
208
219 inline void push(const array &other) noexcept {
220 add(other);
221 }
222
231 T pop() {
232 if (!length()) {
233 throw std::out_of_range("No more elements in array.");
234 }
235
236 T element = at(length() - 1);
237 array_data.pop_back();
238 return element;
239 }
240
241 array &insert(const T &, int);
242
243 void append(const T &);
244
246 array &remove(int, int);
247
248 array &replace(int, int, const T &);
249 array &replace(int, int, const array<T> &);
250
264 array subset(int index, int count) const;
265
271 size_t size() const noexcept override;
272
278 int length() const noexcept override;
279
280 T &at(int);
281 const T &at(int) const override;
282
295 const T &operator[](int index) const override {
296 return at(index);
297 }
298
311 T &operator[](int index) {
312 return at(index);
313 }
314
326 virtual int find(const T &object) const {
327 for (int i = 0; i < (int)array_data.size(); i++) {
328 if (eq(array_data.at(i), object)) {
329 return i;
330 }
331 }
332
333 return -1;
334 }
335
347 int find(std::function<bool(const T &)> predicate) const {
348 for (int i = 0; i < (int)array_data.size(); i++) {
349 if (predicate(array_data.at(i))) {
350 return i;
351 }
352 }
353
354 return -1;
355 }
356
368 int find(std::function<bool(int, const T &)> predicate) const {
369 for (int i = 0; i < (int)array_data.size(); i++) {
370 if (predicate(i, array_data.at(i))) {
371 return i;
372 }
373 }
374
375 return -1;
376 }
377
385 bool contains(const T &object) const noexcept {
386 return find(object) > -1;
387 }
388
399 bool contains(std::function<bool(const T &)> predicate) const {
400 return find(predicate) > -1;
401 }
402
413 bool contains(std::function<bool(int, const T &)> predicate) const {
414 return find(predicate) > -1;
415 }
416
422 void sort() noexcept {
423 sort(*this);
424 }
425
433 void sort(std::function<bool(const T &, const T &)> lambda) noexcept {
434 std::sort(array_data.begin(), array_data.end(), lambda);
435 }
436
444 array sorted() const noexcept {
445 auto new_array = *this;
446 new_array.sort();
447 return new_array;
448 }
449
458 array sorted(std::function<bool(const T &, const T &)> lambda) const noexcept {
459 auto new_array = *this;
460 new_array.sort(lambda);
461 return new_array;
462 }
463
470 virtual void shuffle() noexcept {
471 std::random_device device;
472 std::mt19937 generator(device());
473 std::shuffle(array_data.begin(), array_data.end(), generator);
474 }
475
484 array shuffled() const noexcept {
485 auto new_array = *this;
486 new_array.shuffle();
487 return new_array;
488 }
489
496 virtual void reverse() noexcept {
497 const auto len = length();
498 for (int i = 0; i < (len / 2); ++i) {
499 std::swap(array_data[i], array_data[len - 1 - i]);
500 }
501 }
502
511 array reversed() const noexcept {
512 auto new_array = *this;
513 new_array.reverse();
514 return new_array;
515 }
516
517 array &operator=(const array &other);
518 array &operator=(const std::initializer_list<T> &other);
519
520 bool operator==(const array &other) const;
521 bool operator>(const array &other) const;
522 bool operator<(const array &other) const;
523 inline bool operator!=(const array &other) const;
524 inline bool operator>=(const array &other) const;
525 inline bool operator<=(const array &other) const;
526
536 virtual bool operator()(const T &arg1, const T &arg2) const;
537
546 bool isValid(int index) const;
547
556 array &swap(int index1, int index2);
557
568 template <typename U>
569 array<U> map(std::function<U(const T &)> lambda) const;
570
581 array filter(std::function<bool(const T &)> lambda) const;
582
593 T reduce(std::function<T(const T &, const T &)> lambda, const T &defaultValue = {}) const;
594
600 template <typename U>
601 inline array<U> operator|(std::function<U(T)> lambda) noexcept {
602 return map<U>(lambda);
603 }
604
610 template <typename U>
611 inline array<U> operator|(U (*lambda)(T)) noexcept {
612 return map<U>(lambda);
613 }
614
620 inline array operator&&(std::function<T(const T &)> lambda) noexcept {
621 return filter(lambda);
622 }
623
635 inline T operator>>(std::function<T(const T &, const T &)> lambda) {
636 return reduce(lambda);
637 }
638
648 T randomElement() const {
649 if (array_data.empty()) {
650 throw std::out_of_range("Array is empty");
651 }
652
653 std::random_device device;
654 std::mt19937 generator(device());
655 std::uniform_int_distribution<int> distribution(0, array_data.size() - 1);
656 return array_data[distribution(generator)];
657 }
658
669 array randomElements(int count) const noexcept {
670 if (array_data.empty()) {
671 return array();
672 }
673
674 std::random_device device;
675 std::mt19937 generator(device());
676 std::uniform_int_distribution<int> distribution(0, array_data.size() - 1);
677
678 const int numElements = std::min(count, length());
679
680 array randomArray;
681 randomArray.increase(numElements);
682 for (int i = 0; i < numElements; ++i) {
683 randomArray.push(array_data[distribution(generator)]);
684 }
685
686 return randomArray;
687 }
688
697 T *begin() const noexcept override {
698 return array_data.empty() ? NULL : (T *)&array_data.front();
699 }
700
709 T *end() const noexcept override {
710 return begin() + array_data.size();
711 }
712
713#ifdef __has_include
714#if __has_include(<cereal/cereal.hpp>)
719 void save(cereal::JSONOutputArchive &ar) const {
720 ar.makeArray();
721 for (int i = 0; i < (int)array_data.size(); i++) {
722 ar(array_data[i]);
723 }
724 }
725
730 void save(cereal::XMLOutputArchive &ar) const {
731 for (int i = 0; i < (int)array_data.size(); i++) {
732 ar(cereal::make_nvp(std::to_string(i), array_data[i]));
733 }
734 }
735
740 template <typename archive>
741 void save(archive &ar) const {
742 ar((size_t)array_data.size());
743 for (int i = 0; i < (int)array_data.size(); i++) {
744 ar(array_data[i]);
745 }
746 }
747
752 void load(cereal::JSONInputArchive &ar) {
753 CEREAL_SIZE_TYPE sz;
754 ar.loadSize(sz);
755 array_data.reserve(sz);
756
757 T data;
758 for (int i = 0; i < sz; i++) {
759 ar(data);
760 array_data.push_back(data);
761 }
762 }
763
768 void load(cereal::XMLInputArchive &ar) {
769 CEREAL_SIZE_TYPE sz;
770 ar.loadSize(sz);
771 array_data.reserve(sz);
772
773 T data;
774 for (CEREAL_SIZE_TYPE i = 0; i < sz; i++) {
775 ar(data);
776 array_data.push_back(data);
777 }
778 }
779
784 template <class archive>
785 void load(archive &ar) {
786 clear();
787 CEREAL_SIZE_TYPE sz;
788 ar(sz);
789 array_data.reserve(sz);
790
791 T data;
792 for (CEREAL_SIZE_TYPE i = 0; i < sz; i++) {
793 ar(data);
794 array_data.push_back(data);
795 }
796 }
797
798#endif
799#endif
800};
801
802template <typename T>
804 array_data = other.array_data;
805}
806
807template <typename T>
808array<T>::array(const std::vector<T> &other) {
809 array_data = other;
810}
811
812template <typename T>
813template <typename... Args>
814array<T>::array(const T &arg1, const Args &...args) {
815 init(arg1, args...);
816}
817
829template <typename T>
831 array_data = other.array_data;
832
833 return *this;
834}
835
847template <typename T>
848array<T> &array<T>::operator=(const std::initializer_list<T> &other) {
849 array_data.clear();
850 array_data.reserve(other.size());
851 for (auto &item : other) {
852 array_data.push_back(item);
853 }
854
855 return *this;
856}
857
867template <typename T>
868bool array<T>::operator==(const array<T> &other) const {
869 if (array_data.size() != other.array_data.size()) {
870 return false;
871 }
872
873 for (int i = 0; i < (int)array_data.size(); i++) {
874 if (!eq(array_data.at(i), other.array_data.at(i))) {
875 return false;
876 }
877 }
878
879 return true;
880}
881
891template <typename T>
892bool array<T>::operator>(const array<T> &other) const {
893 if (array_data.size() != other.array_data.size()) {
894 return (array_data.size() > other.array_data.size());
895 }
896
897 int gt_count = 0;
898
899 for (int i = 0; i < (int)array_data.size(); i++) {
900 if (gt(array_data.at(i), other.array_data.at(i))) {
901 gt_count++;
902 } else if (lt(array_data.at(i), other.array_data.at(i))) {
903 gt_count--;
904 }
905 }
906
907 return gt_count > 0;
908}
909
919template <typename T>
920bool array<T>::operator<(const array &other) const {
921 if (array_data.size() != other.array_data.size()) {
922 return (array_data.size() < other.array_data.size());
923 }
924
925 int gt_count = 0;
926
927 for (int i = 0; i < (int)array_data.size(); i++) {
928 if (gt(array_data.at(i), other.array_data.at(i))) {
929 gt_count++;
930 } else if (lt(array_data.at(i), other.array_data.at(i))) {
931 gt_count--;
932 }
933 }
934
935 return gt_count < 0;
936}
937
947template <typename T>
948inline bool array<T>::operator!=(const array &other) const {
949 return !operator==(other);
950}
951
961template <typename T>
962inline bool array<T>::operator>=(const array &other) const {
963 return !operator<(other);
964}
965
975template <typename T>
976inline bool array<T>::operator<=(const array<T> &other) const {
977 return !operator>(other);
978}
979
981template <typename T>
982inline void array<T>::clear() {
983 array_data.clear();
984}
985
998template <typename T>
999array<T> &array<T>::insert(const T &object, int index) {
1000 // if index is negative, insert from end of the array.
1001 if (index < 0) {
1002 index += array_data.size() + 1;
1003 }
1004
1005 // keep within bounds of array.
1006 if (index > (int)array_data.size()) {
1007 index = array_data.size();
1008 }
1009 if (index < 0) {
1010 index = 0;
1011 }
1012
1013 array_data.insert(array_data.begin() + index, object);
1014
1015 return *this;
1016}
1017
1030template <typename T>
1031void array<T>::append(const T &object) {
1032 array_data.push_back(object);
1033}
1034
1042template <typename T>
1044 if (index < 0) {
1045 index += array_data.size() + 1;
1046 }
1047 if ((index >= array_data.size()) || (index < 0)) {
1048 return *this;
1049 }
1050
1051 array_data.erase(array_data.begin() + index);
1052
1053 return *this;
1054}
1055
1064template <typename T>
1065array<T> &array<T>::remove(int index, int count) {
1066 if (!count) {
1067 return *this;
1068 }
1069
1070 if (index < 0) {
1071 index += array_data.size() + 1;
1072 }
1073
1074 int start, end;
1075
1076 if (count > 0) {
1077 start = index;
1078 end = index + count;
1079 } else {
1080 start = index + count + 1;
1081 end = index + 1;
1082 }
1083
1084 if ((end <= 0) || (start >= (int)array_data.size())) {
1085 return *this;
1086 }
1087 if (start < 0) {
1088 start = 0;
1089 }
1090 if (end > (int)array_data.size()) {
1091 end = array_data.size();
1092 }
1093
1094 array_data.erase(array_data.begin() + start, array_data.begin() + end);
1095
1096 return *this;
1097}
1098
1099template <typename T>
1100size_t array<T>::size() const noexcept {
1101 size_t bytes = 0;
1102 for (auto &item : array_data) {
1103 size_t objBytes;
1104 z::core::size(item, objBytes);
1105 bytes += objBytes;
1106 }
1107 return bytes;
1108}
1109
1110template <typename T>
1111int array<T>::length() const noexcept {
1112 return array_data.size();
1113}
1114
1127template <typename T>
1128T &array<T>::at(int index) {
1129 return array_data.at(index);
1130}
1131
1144template <typename T>
1145const T &array<T>::at(int index) const {
1146 return array_data.at(index);
1147}
1148
1160template <typename T>
1161array<T> &array<T>::replace(int index, int count, const T &object) {
1162 if (!count) {
1163 return *this;
1164 }
1165
1166 if (index < 0) {
1167 index += array_data.size() + 1;
1168 }
1169
1170 int start, end;
1171
1172 if (count > 0) {
1173 start = index;
1174 end = index + count;
1175 } else {
1176 start = index + count + 1;
1177 end = index + 1;
1178 }
1179
1180 if ((end <= 0) || (start >= (int)array_data.size())) {
1181 return *this;
1182 }
1183 if (start < 0) {
1184 start = 0;
1185 }
1186 if (end > (int)array_data.size()) {
1187 end = array_data.size();
1188 }
1189
1190 array_data.erase(array_data.begin() + start, array_data.begin() + end);
1191 array_data.insert(array_data.begin() + start, object);
1192
1193 return *this;
1194}
1195
1207template <typename T>
1208array<T> &array<T>::replace(int index, int count, const array<T> &other) {
1209 if (index < 0) {
1210 index += array_data.size();
1211 }
1212
1213 int start, end;
1214
1215 if (count >= 0) {
1216 start = index;
1217 end = index + count;
1218 } else {
1219 start = index + count + 1;
1220 end = index + 1;
1221 }
1222
1223 if ((end <= 0) || (start >= (int)array_data.size())) {
1224 return *this;
1225 }
1226 if (start < 0) {
1227 start = 0;
1228 }
1229 if (end > (int)array_data.size()) {
1230 end = array_data.size();
1231 }
1232
1233 if (count) {
1234 array_data.erase(array_data.begin() + start, array_data.begin() + end);
1235 }
1236 array_data.insert(array_data.begin() + start, other.array_data.begin(), other.array_data.end());
1237
1238 return *this;
1239}
1240
1241template <typename T>
1242array<T> array<T>::subset(int index, int count) const {
1243 array<T> output;
1244
1245 if (!count) {
1246 return *this;
1247 }
1248
1249 if (index < 0) {
1250 index += array_data.size() + 1;
1251 }
1252
1253 int start, end;
1254
1255 if (count > 0) {
1256 start = index;
1257 end = index + count;
1258 } else {
1259 start = index + count + 1;
1260 end = index + 1;
1261 }
1262
1263 if ((end <= 0) || (start >= (int)array_data.size())) {
1264 return *this;
1265 }
1266 if (start < 0) {
1267 start = 0;
1268 }
1269 if (end > (int)array_data.size()) {
1270 end = array_data.size();
1271 }
1272
1273 if (end - start > 0) {
1274 output.array_data.reserve(end - start);
1275 }
1276 for (int i = start; i < end; i++) {
1277 output.array_data.push_back(array_data[i]);
1278 }
1279
1280 return output;
1281}
1282
1283template <typename T>
1284bool array<T>::operator()(const T &arg1, const T &arg2) const {
1285 return greater(arg1, arg2);
1286}
1287
1288template <typename T>
1289bool array<T>::isValid(int index) const {
1290 if (index < 0) {
1291 index += array_data.size();
1292 }
1293 return (index < (int)array_data.size()) && (index >= 0);
1294}
1295
1296template <typename T>
1297array<T> &array<T>::swap(int index1, int index2) {
1298 auto temp = at(index1);
1299 array_data[index1] = at(index2);
1300 array_data[index2] = temp;
1301 return *this;
1302}
1303
1304template <typename T>
1305template <typename U>
1306array<U> array<T>::map(std::function<U(const T &)> lambda) const {
1307 array<U> result;
1308 result.increase(array_data.size());
1309
1310 for (const auto &i : array_data) {
1311 result.add(lambda(i));
1312 }
1313
1314 return result;
1315}
1316
1317template <typename T>
1318array<T> array<T>::filter(std::function<bool(const T &)> lambda) const {
1319 array result;
1320 result.increase(array_data.size()); // Increase it to the max size for performance, but it will likely be smaller than this.
1321
1322 for (const auto &i : array_data) {
1323 if (lambda(i)) {
1324 result.add(i);
1325 }
1326 }
1327
1328 return result;
1329}
1330
1331template <typename T>
1332T array<T>::reduce(std::function<T(const T &, const T &)> lambda, const T &defaultValue) const {
1333 const auto len = array_data.size();
1334 if (len == 0) {
1335 return defaultValue;
1336 }
1337
1338 auto result = array_data[0];
1339 for (int i = 1; i < len; ++i) {
1340 result = lambda(result, array_data[i]);
1341 }
1342
1343 return result;
1344}
1345
1346} // namespace core
1347} // namespace z
1348
1349#define zarray z::core::array
An interface for all objects that can be both iterated over and directly indexed.
Definition arrayLike.hpp:13
bool isValid(int index) const
Check if an index is within the bounds of the array.
Definition array.hpp:1289
void increase(int newSize) noexcept
Increase the space allocated for this array.
Definition array.hpp:155
int push(const T &object) noexcept
Add an object to the array.
Definition array.hpp:205
virtual bool eq(const T &arg1, const T &arg2) const
Check if two objects are equal.
Definition array.hpp:74
bool contains(const T &object) const noexcept
Check if a given object is in the array.
Definition array.hpp:385
bool operator>(const array &other) const
Array greater-than operator.
Definition array.hpp:892
array filter(std::function< bool(const T &)> lambda) const
Filters the array based on a predicate and returns a new array containing the elements that satisfy t...
Definition array.hpp:1318
array(const array &other)
Copy constructor.
Definition array.hpp:803
virtual void shuffle() noexcept
Shuffle the elements of the array into a random order.
Definition array.hpp:470
int find(std::function< bool(int, const T &)> predicate) const
Find the index of the first element in the array that satisfies a given predicate.
Definition array.hpp:368
void sort(std::function< bool(const T &, const T &)> lambda) noexcept
Sort the array based on an arbitrary function.
Definition array.hpp:433
array< U > operator|(U(*lambda)(T)) noexcept
Definition array.hpp:611
array sorted() const noexcept
Sort the array based on default comparison operator.
Definition array.hpp:444
void init(const T &arg1)
Helper function for single object initialization.
Definition array.hpp:47
virtual int find(const T &object) const
Find the index of a given object in the array.
Definition array.hpp:326
void add(const array &other) noexcept
Add another array to this array.
Definition array.hpp:187
array sorted(std::function< bool(const T &, const T &)> lambda) const noexcept
Sort the array based on an arbitrary function.
Definition array.hpp:458
std::vector< generic > array_data
Definition array.hpp:41
array & operator=(const std::initializer_list< T > &other)
Initializer list assignment operator.
Definition array.hpp:848
array(const T &arg1, const Args &...args)
List-initialized constructor.
Definition array.hpp:814
void sort() noexcept
Sort the array based on default comparison operator.
Definition array.hpp:422
bool operator<=(const array &other) const
Array less-than-or-equal operator.
Definition array.hpp:976
array & operator=(const array &other)
Array assignment operator.
Definition array.hpp:830
bool operator!=(const array &other) const
Check whether two arrays' contents are different.
Definition array.hpp:948
T & operator[](int index)
Function to get the object at the given index.
Definition array.hpp:311
size_t size() const noexcept override
Get the size of the array.
Definition array.hpp:1100
array()
Default constructor.
Definition array.hpp:112
int length() const noexcept override
Get the length of the array.
Definition array.hpp:1111
array shuffled() const noexcept
Shuffle the elements of the array into a random order.
Definition array.hpp:484
array & insert(const T &, int)
Insert an object into the array.
Definition array.hpp:999
virtual bool operator()(const T &arg1, const T &arg2) const
Callable operator.
Definition array.hpp:1284
bool operator<(const array &other) const
Array less-than operator.
Definition array.hpp:920
array randomElements(int count) const noexcept
Get N random elements from the array.
Definition array.hpp:669
array reversed() const noexcept
Reverse the order of all elements in the array.
Definition array.hpp:511
int find(std::function< bool(const T &)> predicate) const
Find the index of the first element in the array that satisfies a given predicate.
Definition array.hpp:347
T & at(int)
Function to get the object at the given index.
Definition array.hpp:1128
void init(const T &arg1, const Args &...args)
Helper function for brace-enclosed list initialization.
Definition array.hpp:57
T randomElement() const
Get a random element from the array.
Definition array.hpp:648
void push(const array &other) noexcept
Add another array to this array.
Definition array.hpp:219
T operator>>(std::function< T(const T &, const T &)> lambda)
Reduces the array to a single value by applying a binary operation cumulatively to the elements.
Definition array.hpp:635
array & replace(int, int, const T &)
Replace all objects in the given range with an object.
Definition array.hpp:1161
bool contains(std::function< bool(const T &)> predicate) const
Check if an element in the array satisfies a given predicate.
Definition array.hpp:399
array(const std::vector< T > &other)
Copy from std::vector.
Definition array.hpp:808
void append(const T &)
Append an object to the end of the array.
Definition array.hpp:1031
array & remove(int)
Remove an object from the array.
Definition array.hpp:1043
virtual ~array()
Destructor.
Definition array.hpp:143
bool operator>=(const array &other) const
Array greater-than-or-equal operator.
Definition array.hpp:962
virtual void reverse() noexcept
Reverse the order of all elements in the array.
Definition array.hpp:496
array & replace(int, int, const array< T > &)
Replace all objects in the given range with an array of objects.
Definition array.hpp:1208
virtual int add(const T &object)
Add an object to the array.
Definition array.hpp:171
array operator&&(std::function< T(const T &)> lambda) noexcept
Definition array.hpp:620
virtual bool gt(const T &arg1, const T &arg2) const
Check if one object is greater than another.
Definition array.hpp:90
array< U > operator|(std::function< U(T)> lambda) noexcept
Definition array.hpp:601
bool contains(std::function< bool(int, const T &)> predicate) const
Check if an element in the array satisfies a given predicate.
Definition array.hpp:413
array(const std::initializer_list< T > &other)
Construct from a generic initializer list.
Definition array.hpp:140
array subset(int index, int count) const
Get a contiguous subset of the elements in the array.
Definition array.hpp:1242
T reduce(std::function< T(const T &, const T &)> lambda, const T &defaultValue={}) const
Reduces the array to a single value by applying a binary operation cumulatively to the elements.
Definition array.hpp:1332
array & remove(int, int)
Remove all elements in a subset of the array.
Definition array.hpp:1065
T * begin() const noexcept override
Get pointer to the beginning of the array.
Definition array.hpp:697
virtual bool lt(const T &arg1, const T &arg2) const
Check if one object is less than another.
Definition array.hpp:106
T * end() const noexcept override
Get pointer to the end of the array.
Definition array.hpp:709
bool operator==(const array &other) const
Check whether two arrays' contents are the same.
Definition array.hpp:868
array< U > map(std::function< U(const T &)> lambda) const
Applies a transformation function to each element of the array and returns a new array with the resul...
Definition array.hpp:1306
array & swap(int index1, int index2)
Swap two elements in an array.
Definition array.hpp:1297
void clear()
Clear the data in the array.
Definition array.hpp:982
T pop()
Remove the last element from this array.
Definition array.hpp:231
An arbitrary generator for producing sequential results on-the-fly.
Definition generator.hpp:71
An interface for getting an object's size.
Definition sizable.hpp:13
Section containing core functions and classes.
std::enable_if< std::is_base_of< z::core::sizable, T >::value >::type size(const T &object, size_t &bytes) noexcept
Get the size of a sizable object.
Definition sizable.hpp:31