Array
An Array
object owns a single block of memory, allocated on the heap, that contains an array of
typed items. The items are destructed and freed when the Array
is destroyed.
When an Array
is const
, the items it owns are immutable.
The array items must be relocatable; that is, it must always be possible to move items to a new
address by calling memmove
on the memory that contains them. Most Plywood containers, including
Array
, Owned
, HashMap
and BTree
, are relocatable, so it's OK to create an Array
of such
types or structures of such types.
Array
is implicitly convertible to ArrayView
and can be passed directly to any function that
expects an ArrayView
.
Header File
#include <ply-runtime/container/Array.h>
Also included from <ply-runtime/Base.h>
.
Constructors
-
Constructs an empty
Array
.Array<u32> arr;
-
Copy constructor. This constructor is always defined because, in C++14, there is no way to conditionally disable it if
T
itself is not copy constructible. Instead, a runtime error occurs if this constructor is called whenT
is not copy constructible.Array<u32> arr = other;
-
Move constructor.
other
is reset to an emptyArray
.Array<u32> arr = std::move(other);
-
Constructs an
Array
from a braced initializer list.Array<u32> arr = {4, 5, 6};
template <typename Other, typename U = details::ArrayViewType<Other>>
Array::Array(Other&& other)
[code]-
Construct an
Array
from any array-like object (ie.Array
,ArrayView
,FixedArray
, etc.) of any type from whichT
can be constructed. The other object must have a member function namedview()
that returns anArrayView
.FixedArray<u16, 3> fixed = {4, 5, 6}; Array<u32> arr = fixed;
Move semantics are used when the source object owns its items and can be moved from. In the following example, the right-hand side is a temporary
Array<String>
that can be moved from, so eachHybridString
in the result is constructed by moving from eachString
in the temporary object.Array<HybridString> arr = Array<String>{"hello", "there"};
Array::~Array()
[code]-
Destructor. Destructs all items and frees the memory associated with the
Array
. void Array::operator=(const Array& other)
[code]-
Copy assignment operator. This operator is always defined because, in C++14, there is no way to conditionally disable it if
T
itself is not copy assignable. Instead, a runtime error occurs if this operator is called whenT
is not copy assignable.arr = other;
void Array::operator=(Array&& other)
[code]-
Move assignment operator.
other
is reset to an emptyArray
.arr = std::move(other);
void Array::operator=(InitList<T> init)
[code]-
Assignment from a braced initializer list.
Array<u32> arr; arr = {4, 5, 6};
template <typename Other, typename U = details::ArrayViewType<Other>>
void Array::operator=(Other&& other)
[code]-
Construct an
Array
from any array-like object (ie.Array
,ArrayView
,FixedArray
, etc.) of any type from whichT
can be constructed. The other object must have a member function namedview()
that returns anArrayView
.Array<u32> arr; FixedArray<u16, 3> fixed = {4, 5, 6}; arr = fixed;
Move semantics are used when the source object owns its items and can be moved from. In the following example, the right-hand side is a temporary
Array<String>
that can be moved from, so eachHybridString
in the result is constructed by moving from eachString
in the temporary object.Array<HybridString> arr; arr = Array<String>{"hello", "there"}; // uses move semantics
T& Array::operator[](u32 index)
[code]const T& Array::operator[](u32 index) const
[code]-
Subscript operator with runtime bounds checking.
Array<u32> arr = {4, 5, 6}; arr[1]; // 5
-
Reverse subscript operator with runtime bound checking. Expects a negative index.
-1
returns the last item in the array;-2
returns the second-last item, etc.Array<u32> arr = {4, 5, 6}; arr.back(); // 6
-
Required functions to support range-for syntax. Allows you to iterate over all the items in the array.
for (const T& item : arr) { ... }
explicit Array::operator bool() const
[code]-
Explicit conversion to
bool
. Returnstrue
if the array is not empty. Allows you to use anArray
object inside anif
condition.if (arr) { ... }
-
Returns
true
if the array is empty. -
Returns the number of items in the array.
-
Returns the total size, in bytes, of the items in the array. Equivalent to
this->numItems() * sizeof(T)
. -
Destructs all items in the array and frees the internal memory block.
-
Ensures the underlying memory block is large enough to accomodate the given number of items. If
numItems
is greater than the current capacity, the memory block is reallocated. No items are constructed or destructed by this function. This function can help avoid repeated memory reallocation as the array grows in size. -
Resizes the array to the given number of items. If
numItems
is greater that the current array size, new items are constructed. IfnumItems
is smaller than the current array size, existing items are destructed. -
Shrinks the size of the underlying memory block to exactly fit the current number of array items.
-
Appends a single item to the array and returns a reference to it. The arguments are forwarded directly to the item's constructor. The returned reference remains valid until the array is resized or reallocated.
-
template <typename Other, typename U = details::ArrayViewType<Other>>
void Array::extend(Other&& other)
[code] -
Appends multiple items to the array. The argument can be a braced initializer list or an array-like object (ie.
Array
,ArrayView
,FixedArray
, etc.) of any type from whichT
can be constructed.Array<String> arr; arr.extend({"hello", "there"}); arr.extend(ArrayView<const StringView>{"my", "friend"});
Move semantics are used when the source object owns its items and can be moved from. In the following example, the argument to
extend
is a temporaryArray<String>
that can be moved from, so eachHybridString
in the result is appended by moving from eachString
in the temporary object.Array<HybridString> arr; arr.extend(Array<String>{"hello", "there"}); // uses move semantics
-
Appends multiple items to the
Array
from anArrayView
. The new array items are move constructed from the items inother
. -
Shrinks the array by
count
items. Equivalent toresize(numItems() - count)
. -
Inserts
count
new items into the array at offsetpos
. The new items are default constructed. All existing items afterpos
are shifted upward to accomodate the new items. -
Destructs
count
array items starting at offsetpos
. Any remaining items starting at index(count + pos)
are shifted downward to replace the erased items. The size of the array then shrinks bycount
. -
Destructs
count
array items starting at offsetpos
. The lastcount
items in the array are moved to the space previously occupied by the erased items. The size of the array then shrinks bycount
.When the array is large and number of erased items is small,
eraseQuick()
is typically faster thanerase()
. template <typename Arr0, typename Arr1, typename T0 = details::ArrayViewType<Arr0>, typename T1 = details::ArrayViewType<Arr1>>
auto operator+(Arr0&& a, Arr1&& b)
[code]-
Returns the concatenation of two array-like objects
a
andb
. The arguments can be instances ofArray
,ArrayView
,FixedArray
or any class that has a member function namedview()
returning anArrayView
. The returnedArray
has the same item type asa
, andb
's items must be convertible to this type.Move semantics are used when either operand owns its items and can be moved from.
-
Explicitly create an
ArrayView
into the array. Array::operator ArrayView<T>()
[code]Array::operator ArrayView<const T>() const
[code]-
Implicit conversion to
ArrayView
. Makes is possible to passArray
to any function that expects anArrayView
. -
Explicitly creeate a
StringView
orMutableStringView
into the array. -
Returns a subview that starts at the offset given by
start
. The optionalnumItems
argument determines the number of items in the subview. IfnumItems
is not specified, the subview continues to the end of the view. The subview items areconst
or non-const
depending on whether theArray
itself is const.