22 #include <type_traits>
63 inline void DelArray() {
64 if ((alloc_data != NULL) && (do_delete)) {
65 delete[] (alloc_data);
71 inline void AllocArray(
const size_t newsize) {
73 alloc_data =
new T[newsize];
75 catch (std::bad_alloc &) {
78 data = alloc_data + offset;
83 void Initialize(
size_t new_d_size) {
120 d_size (copy.d_size) {
122 std::copy(copy.data, copy.data + copy.d_size, data);
132 inline Data1D(
const std::initializer_list<T>& new_data)
134 d_size(new_data.
size()) {
136 std::copy(new_data.begin(), new_data.end(), data);
147 : rev_ptr(other.rev_ptr)
148 , d_alloc(other.d_alloc)
149 , alloc_data(other.alloc_data)
150 , offset(other.offset)
151 , d_size(other.d_size)
153 , do_delete(other.do_delete) {
156 other.rev_ptr.AutoRevoke(
false);
158 other.alloc_data = NULL;
159 other.do_delete =
false;
174 inline Data1D(
size_t d_size, T* new_data,
bool auto_delete =
false)
176 alloc_data (new_data),
180 do_delete (auto_delete) {
208 return (d_size == 0);
220 inline size_t Find(
const T2& elem,
size_t start_at=0)
const {
221 for (
size_t i=start_at; i<d_size; i++) {
222 if (data[i] == elem) {
240 inline bool Check(
const size_t x)
const {
252 inline void OutOfBounds()
const {
262 inline void Assert(
const size_t x)
const {
271 inline void Reserve(
const size_t reserve_size) {
273 size_t reserve_offset = reserve_size + offset;
275 if (reserve_offset <= d_alloc) {
279 tmp =
new T[reserve_offset];
281 std::move(alloc_data, alloc_data + d_alloc, tmp);
283 std::copy(alloc_data, alloc_data + d_alloc, tmp);
285 d_alloc = reserve_offset;
290 data = alloc_data + offset;
302 inline void Resize(
const size_t resize_size) {
304 d_size = resize_size;
315 if (new_offset > d_alloc) {
319 if ( (d_size + offset) > new_offset ) {
320 d_size += offset - new_offset;
327 data = alloc_data + offset;
338 inline void SetRange(
const size_t new_offset,
const size_t new_size) {
339 if (new_offset > d_alloc) {
343 data = alloc_data + offset;
356 inline T*
Raw()
const {
return data; }
359 inline size_t size()
const {
return d_size; }
361 inline size_t TypeSize()
const {
return sizeof(T); }
363 inline size_t ByteSize()
const {
return d_size*
sizeof(T); }
390 if (
reinterpret_cast<void*
>(data) ==
391 reinterpret_cast<void*
>(other.
Raw())) {
395 if (d_alloc < other.
size()) {
398 AllocArray(other.
size());
400 d_size = other.
size();
403 std::copy(other.
Raw(), other.
Raw() + other.
size(), data);
421 size_t pos,
size_t num_elem=
npos) {
422 if (
reinterpret_cast<void*
>(data) ==
423 reinterpret_cast<void*
>(other.
Raw())) {
429 if ( ! other.
Check(pos) ) {
440 size_t real_num_elem = num_elem;
441 if (num_elem > (other.
size()-pos)) {
442 real_num_elem = other.
size() - pos;
445 if (d_alloc < real_num_elem) {
448 AllocArray(real_num_elem);
450 d_size = real_num_elem;
453 std::copy(other.
Raw()+pos, other.
Raw()+pos+real_num_elem, data);
473 size_t other_size = other.
size();
474 size_t copy_end = pos + other_size;
475 if (d_size < copy_end) {
479 std::copy(other.
Raw(), other.
Raw() + other_size, data + pos);
494 const size_t other_start,
const size_t amnt=
npos) {
499 other.
Assert(other_start);
501 size_t real_amnt = amnt;
502 size_t to_end = other.
size() - other_start;
504 if ( real_amnt > to_end) {
508 size_t copy_end = pos + real_amnt;
509 if (d_size < copy_end) {
513 T2* s_first = other.
Raw() + other_start;
514 T2* s_last = other.
Raw() + other_start + real_amnt;
515 T* d_first = data + pos;
516 if (
reinterpret_cast<void*
>(d_first) >
517 reinterpret_cast<void*
>(s_last) ||
518 reinterpret_cast<void*
>(d_first) <=
519 reinterpret_cast<void*
>(s_first)) {
520 std::copy(s_first, s_last, d_first);
523 T* d_last = data + pos + real_amnt;
524 std::copy_backward(s_first, s_last, d_last);
536 inline void CopyData (
const size_t dest,
const size_t source,
537 const size_t amnt=
npos) {
538 CopyAt(dest, *
this, source, amnt);
581 Data1D<decltype(converter(*data))> retval(d_size);
582 for (
size_t i=0; i<d_size; i++) {
583 retval[i] = converter(data[i]);
601 size_t bytesize = d_size *
sizeof(T);
602 size_t newsize = bytesize /
sizeof(T2) +
603 (((bytesize %
sizeof(T2))>0)?1:0);
605 unsigned char *srcptr =
reinterpret_cast<unsigned char*
>(data);
606 unsigned char *destptr =
reinterpret_cast<unsigned char*
>(retval.
Raw());
607 std::copy(srcptr, srcptr+bytesize, destptr);
659 inline T&
At(
size_t x) {
Assert(x);
return data[x]; }
661 inline const T&
At(
size_t x)
const {
Assert(x);
return data[x]; }
667 inline T&
Last() {
Assert(d_size-1);
return data[d_size-1]; }
669 inline const T&
Last()
const {
Assert(d_size-1);
return data[d_size-1]; }
680 for (i=0; i<d_size; i++) {
691 if (
end == 0 ||
end < start) {
694 size_t realend =
end;
695 if (realend ==
size_t(-1)) {
700 for (
size_t i=start; i<=
end; i++) {
708 std::sort(data, data + d_size);
715 template <
class Comparator>
716 inline void Sort(Comparator comp) {
717 std::sort(data, data + d_size, comp);
727 std::shuffle(data, data + d_size,
RND_Gen());
739 std::shuffle(data, data + d_size,
URand_Gen());
754 T* retval = alloc_data;
772 if ((offset == 0) && (d_alloc <= d_size)) {
783 tmp =
new T[d_alloc];
786 std::move(data, data + d_size, tmp);
788 std::copy(data, data + d_size, tmp);
813 size_t offset_size = d_size + offset;
815 if (d_alloc <= offset_size) {
816 growto = d_size << 1;
817 if (growto <= d_size) {
823 data[d_size++] = newT;
832 size_t last_d_size = d_size;
833 size_t other_size = other.
size();
835 Resize(d_size + other_size);
837 std::copy(other.
Raw(), other.
Raw() + other_size, data + last_d_size);
866 inline void Insert(
size_t pos,
const T& newT) {
871 std::copy_backward(data+pos, data+
size(), data+
size()+1);
884 std::move(data+pos+1, data+
size(), data+pos);
886 std::copy(data+pos+1, data+
size(), data+pos);
927 for (
size_t i=0; i<d_size; i++) {
938 for (
size_t i=0; i<d_size; i++) {
953 template<
class AnyVal
idType>
957 if (d_size != other.d_size) {
961 if (data == other.data) {
965 for (i=0; i<d_size; i++) {
966 if ( ! (data[i] == other.data[i]) ) {
984 template<
class AnyVal
idType>
989 if (d_size < other.d_size) {
994 if (data == other.data && d_size == other.d_size) {
997 minsize = other.d_size;
998 left_smaller =
false;
1002 for (i=0; i<minsize; i++) {
1003 if (data[i] < other.data[i]) {
1006 else if (other.data[i] < data[i]) {
1012 return left_smaller;
1026 inline
void Get(T2& store_at,
size_t index_T)
const {
1027 size_t end_index = index_T +
sizeof(T2) /
sizeof(T) +
1028 (((
sizeof(T2)%
sizeof(T)) != 0) ? 1 : 0);
1029 if (end_index>0) { end_index--; }
1031 store_at = *
reinterpret_cast<T2*
>(data+index_T);
1036 inline T2
Get(
size_t index_T=0)
const {
1038 Get(retval, index_T);
1049 if (store_at.
size() == 0) {
1050 store_at.
Resize(((
size()-index_T)*
sizeof(T))/
sizeof(T2));
1052 size_t T2_fullsize =
sizeof(T2)*store_at.
size();
1053 size_t end_index = index_T + T2_fullsize /
sizeof(T) +
1054 (((T2_fullsize%
sizeof(T)) != 0) ? 1 : 0);
1055 if (end_index>0) { end_index--; }
1057 T2* T2_data_ptr =
reinterpret_cast<T2*
>(data+index_T);
1058 std::copy(T2_data_ptr, T2_data_ptr + store_at.
size(), store_at.
Raw());
1071 size_t end_index = index_T +
sizeof(T2) /
sizeof(T) +
1072 (((
sizeof(T2)%
sizeof(T)) != 0) ? 1 : 0);
1073 if (end_index>0) { end_index--; }
1075 *
reinterpret_cast<T2*
>(data+index_T) = read_from;
1088 size_t T2_fullsize =
sizeof(T2)*read_from.
size();
1089 size_t T1_sizeneeded = index_T + T2_fullsize /
sizeof(T) +
1090 (((T2_fullsize%
sizeof(T)) != 0) ? 1 : 0);
1091 if (d_size < T1_sizeneeded) {
1094 T2* T2_data_ptr =
reinterpret_cast<T2*
>(data+index_T);
1095 std::copy(read_from.
Raw(), read_from.
Raw()+read_from.
size(), T2_data_ptr);
1104 static const size_t npos = size_t(-1);
1113 for (i=0; i<d.
size(); i++) {
1125 if (d.
size() == 0) {
1129 out <<
"{ " <<
u16(d[0]);
1130 for (i=1; i<d.
size(); i++) {
1131 out <<
", " <<
u16(d[i]);
1145 if (d.
size() == 0) {
1149 out <<
"{ " <<
i16(d[0]);
1150 for (i=1; i<d.
size(); i++) {
1151 out <<
", " <<
i16(d[i]);
1167 if (d.
size() == 0) {
1171 out <<
"{ " << d[0];
1172 for (i=1; i<d.size(); i++) {
1173 out <<
", " << d[i];
Provides informative exception handling.
#define Throw_RC_Type(Type, err)
Use this to throw an RC:ErrorMsg subtype exception.
Definition: Errors.h:282
Provides a bounds-checked iterator that knows when its target was deleted.
Provides a set of convenience macros for metaprogramming and debugging.
#define RC_DEFAULT_COMPARISON()
Given == and <, generates !=, >, <=, and >=.
Definition: Macros.h:246
The version information and configuration settings for RC Lib.
Provides typedefs and routines for working with primitives.
uint64_t u64
64-bit unsigned integer.
Definition: Types.h:31
uint16_t u16
16-bit unsigned integer.
Definition: Types.h:27
int16_t i16
16-bit signed integer.
Definition: Types.h:26
A bounds-safe one-dimensional vector-like structure.
Definition: Data1D.h:49
Data1D< T2 > Reinterpret() const
Returns a new array with the raw data of this Data1D reinterpreted as type T2.
Definition: Data1D.h:600
void CopyAt(const size_t pos, const Data1D< T2 > &other, const size_t other_start, const size_t amnt=npos)
Overwrite a range of data from any compatible type, expanding if necessary.
Definition: Data1D.h:493
friend void swap(Data1D< T2 > &a, Data1D< T2 > &b)
Efficiently swap all the contents of a and b.
void SetRange(const size_t new_offset, const size_t new_size)
Set a new offset and data size, resizing if necessary.
Definition: Data1D.h:338
void Append(const T &newT)
Add an element to the end, expanding if necessary.
Definition: Data1D.h:811
T * Extract()
Removes ownership of the contained data from the Data1D object.
Definition: Data1D.h:753
void ZeroRange(const size_t start, const size_t end=npos)
Like Zero() but operating only between index start and end, inclusive.
Definition: Data1D.h:689
T & At(size_t x)
Identical to Data1D::operator[].
Definition: Data1D.h:659
void ToBigEndian()
Convert endianness of all elements if needed, for supported types.
Definition: Data1D.h:936
T & operator()(size_t x)
Identical to Data1D::operator[].
Definition: Data1D.h:653
void Append(const Data1D &other)
Appends all elements in other to the end, expanding if necessary.
Definition: Data1D.h:844
void Clear()
Identical to Delete().
Definition: Data1D.h:801
void Crop()
Reduces memory consumption to only that necessary for size() elements.
Definition: Data1D.h:769
bool Check(const size_t x) const
Check if index x is in bounds.
Definition: Data1D.h:240
const T & Last() const
Const version of last()
Definition: Data1D.h:669
Data1D(size_t d_size, T *new_data, bool auto_delete=false)
Efficiently wraps in-place C-pointer data in a bounds-safe container.
Definition: Data1D.h:174
size_t TypeSize() const
Returns the size of this Data1D's type.
Definition: Data1D.h:361
Data1D< T > operator+(const Data1D &other) const
Create a new array from this Data1D concatenated with other after it.
Definition: Data1D.h:916
size_t GetOffset() const
Returns the current offset for index 0.
Definition: Data1D.h:372
bool operator==(const Data1D< AnyValidType > &other) const
Comparison operator for all elements.
Definition: Data1D.h:954
void CopyAt(const size_t pos, const Data1D< T2 > &other)
Overwrite a range of data using all data from any compatible type, expanding if necessary.
Definition: Data1D.h:468
void URandShuffle()
Randomizes the order of all the elements using /dev/urandom.
Definition: Data1D.h:737
bool IsEmpty() const
Returns true if there are no elements / the size is 0.
Definition: Data1D.h:207
void Get(Data1D< T2 > &store_at, size_t index_T=0) const
Fills the array store_at to its current size with raw assigned data of type T2 from this Data1D.
Definition: Data1D.h:1048
RAIter< Data1D< T >, T > end()
Return a bounds-checked random-access iterator starting just past the last element.
Definition: Data1D.h:636
void Delete()
Delete all the elements and free all allocated memory.
Definition: Data1D.h:188
void Zero()
Sets all elements equal to 0.
Definition: Data1D.h:677
Data1D< T > & Put(const T2 &read_from, size_t index_T)
Direct raw data insertion of type T2 at index.
Definition: Data1D.h:1070
void AppendFrom(const Data1D< T2 > &other)
Append data from any type with a compatible assignment operator.
Definition: Data1D.h:831
Data1D Copy(const size_t pos=0, const size_t amnt=npos) const
Creates a duplicate copy of the contents, with up to amnt elements from pos.
Definition: Data1D.h:377
size_t ByteReserved() const
Returns the current allocated storage in bytes.
Definition: Data1D.h:367
void Sort()
Sorts the elements according to T::operator< in N*log2(N) time.
Definition: Data1D.h:707
size_t ByteSize() const
Returns the current size in bytes.
Definition: Data1D.h:363
void Insert(size_t pos, const T &newT)
Inserts newT at position pos, shifting the other elements.
Definition: Data1D.h:866
Data1D< T2 > Cast()
Returns a new array with all the elements of this array assigned to type T2.
Definition: Data1D.h:571
void Shuffle()
Randomizes the order of all the elements.
Definition: Data1D.h:725
Data1D< T > & Put(const Data1D< T2 > &read_from, size_t index_T=0)
Like Get for a T2 type, but places sequential packed data.
Definition: Data1D.h:1087
auto CastWith(Conv converter) -> Data1D< decltype(converter(*data))>
Returns a new array with all the elements of this array converted to another type by converter.
Definition: Data1D.h:580
~Data1D()
Deletes all contents upon destruction.
Definition: Data1D.h:200
T * Raw() const
Access a raw unprotected C-pointer to the enclosed data.
Definition: Data1D.h:356
const RAIter< Data1D< T >, T > end() const
Const version end.
Definition: Data1D.h:640
T & operator[](size_t x)
Bounds-checked access of the element at index x from the offset (default 0).
Definition: Data1D.h:651
static const size_t npos
The largest possible value of size_t.
Definition: Data1D.h:1104
Data1D & operator=(const Data1D &other)
Assignment operator which copies all contents from other, respecting offsets.
Definition: Data1D.h:547
Data1D & CopyFrom(const Data1D< T2 > &other, size_t pos, size_t num_elem=npos)
assignment operator.
Definition: Data1D.h:420
void Reserve(const size_t reserve_size)
Reserve storage without resizing the array.
Definition: Data1D.h:271
void SetOffset(const size_t new_offset)
Set a new offset position for index 0.
Definition: Data1D.h:314
Data1D(size_t d_size)
Constructor which sets the initial size to d_size.
Definition: Data1D.h:111
size_t size() const
Returns the current number of elements.
Definition: Data1D.h:359
const RAIter< Data1D< T >, T > begin() const
Const version of begin.
Definition: Data1D.h:624
void Assert(const size_t x) const
Throws an ErrorMsgBounds exception if x is out of bounds.
Definition: Data1D.h:262
T & Last()
Provides the last element.
Definition: Data1D.h:667
void ExpandSet(size_t pos, const T &newT)
Assign newT to index pos, expanding if necessary to reach that index.
Definition: Data1D.h:853
size_t Find(const T2 &elem, size_t start_at=0) const
Returns the first index at or after start_at for which the data equals elem.
Definition: Data1D.h:220
void Sort(Comparator comp)
Sorts the elements according to the binary comparitor comp.
Definition: Data1D.h:716
Data1D< T > & operator+=(const T &newT)
Add an element to the end, expanding if necessary.
Definition: Data1D.h:899
Data1D(Data1D< T > &&other)
Move constructor that reassigns all the data to this Data1D.
Definition: Data1D.h:146
void Resize(const size_t resize_size)
Resize the array, reallocating if necessary.
Definition: Data1D.h:302
Data1D(const Data1D< T > ©)
Copy constructor that copies all elements.
Definition: Data1D.h:118
void FromLilEndian()
Convert endianness of all elements if needed, for supported types.
Definition: Data1D.h:933
T2 Get(size_t index_T=0) const
Identical to the Get which receives store_at, but this returns the extracted value.
Definition: Data1D.h:1036
size_t reserved() const
Returns the number of elements for which space is reserved.
Definition: Data1D.h:365
const T & At(size_t x) const
Const version of Data1D::operator[].
Definition: Data1D.h:661
void Remove(size_t pos)
Removes the element at pos from the array, shrinking the size.
Definition: Data1D.h:880
bool Contains(const T2 &elem) const
Returns true if at least one entry equals elem.
Definition: Data1D.h:231
void FromBigEndian()
Convert endianness of all elements if needed, for supported types.
Definition: Data1D.h:944
Data1D(const std::initializer_list< T > &new_data)
Initializer list constructor, for initializing with bracketed data.
Definition: Data1D.h:132
Data1D & CopyFrom(const Data1D< T2 > &other)
Copy data from any type with a compatible assignment operator.
Definition: Data1D.h:389
void CopyData(const size_t dest, const size_t source, const size_t amnt=npos)
Copy data from any location in this Data1D to another location, handling overlap automatically.
Definition: Data1D.h:536
void ToLilEndian()
Convert endianness of all elements if needed, for supported types.
Definition: Data1D.h:925
bool operator<(const Data1D< AnyValidType > &other) const
Returns true if the first different element for this is less than for other.
Definition: Data1D.h:985
RAIter< Data1D< T >, T > begin()
Copy data from any other object of a type with a compatible.
Definition: Data1D.h:620
void Get(T2 &store_at, size_t index_T) const
Direct raw data extraction of type T2 at index.
Definition: Data1D.h:1026
static bool IsLittle()
True if this system is little-endian.
Definition: Types.h:335
static bool IsBig()
True if this system is big-endian.
Definition: Types.h:341
static T ToBig(const T &x)
Converts x to big-endian.
Definition: Types.h:319
static T ToLittle(const T &x)
Converts x to little-endian.
Definition: Types.h:302
A bounds-checked iterator for random-access containers that knows when its target was deleted.
Definition: Iter.h:27
A reference counting pointer that revokes (NULLs) all copies when one set to AutoRevoke(true) leaves ...
Definition: RevPtr.h:45
void AutoRevoke(bool new_auto_revoke=true)
Set this RevPtr to revoke the pointer upon deletion or leaving scope.
Definition: RevPtr.h:142
std::ostream & operator<<(std::ostream &out, APtr< T > obj)
A convenience stream output for displaying the enclosed object.
Definition: APtr.h:120
RND & RND_Gen()
This returns a singleton of RND .
Definition: RND.h:594
u64 RND_Get_Range(u64 range)
Uses RND as a RandomNumberGenerator, e.g. for random_shuffle.
Definition: RND.h:542
void swap(RC::Data1D< T > &a, RC::Data1D< T > &b)
Efficiently swap all the contents of a and b.
Definition: Data1D.h:1184
u64 URand_Get_Range(u64 range)
Uses URand as a RandomNumberGenerator, e.g. for random_shuffle.
Definition: RND.h:580
URand & URand_Gen()
This returns a singleton of URand .
Definition: RND.h:597
auto MakeData1D(T(&arr)[N]) -> RC::Data1D< T >
Convenience generator for safely converting C-style arrays.
Definition: Data1D.h:1195