File array.hxx#

Functions

template<typename T, typename Backing>
Array<T, Backing> copy(const Array<T, Backing> &other)#

Create a copy of an Array, which does not share data

template<typename T, typename B1, typename B2>
bool operator==(const Array<T, B1> &lhs, const Array<T, B2> &rhs)#

Compare arrays, which may have different backing.

template<typename T>
struct ArrayData#
#include <array.hxx>

ArrayData holds the actual data Handles the allocation and deletion of data

Public Functions

inline ArrayData(int size)#
inline ArrayData(ArrayData &&in) noexcept#

Move constructor.

ArrayData(const ArrayData &in) = delete#

Disable copy, since ArrayData takes ownership of data.

inline ~ArrayData()#
inline iterator<T> begin() const#
inline iterator<T> end() const#
inline int size() const#
inline ArrayData<T> &operator=(const ArrayData<T> &in)#

Copy assignment Copy the underlying data from one array to the other

Parameters:

inArrayData with the same len as this.

inline ArrayData<T> &operator=(ArrayData<T> &&in) noexcept#

Move assignment.

inline T &operator[](int ind)#
inline const T &operator[](int ind) const#

Private Members

int len#

Size of the array.

T *data#

Array of data.

template<typename T, typename Backing = ArrayData<T>>
class Array#
#include <array.hxx>

Data array type with automatic memory management

This implements a container similar to std::vector but with reference counting like a smart pointer and custom memory management to minimise new and delete calls

This can be used as an alternative to static arrays

Array<dcomplex> vals(100); // 100 complex numbers

vals[10] = 1.0; // ok

When an Array goes out of scope or is deleted, the underlying memory (dataBlock/Backing) is put into a map, rather than being freed. If the same size arrays are used repeatedly then this avoids the need to use new and delete.

This behaviour can be disabled by calling the static function useStore:

Array<dcomplex>::useStore(false); // Disables memory store

The second template argument determines what type of container to use to store data. This defaults to a custom struct but can be std::valarray ( provided T is a compatible type), std::vector etc. Must provide the following : size, operator=, operator[], begin, end

Notes:

  • Arrays can’t be used in GPU code. To access Array data inside a RAJA loop, first extract the raw pointer

Public Types

using data_type = T#
using backing_type = Backing#
using size_type = int#

Public Functions

inline Array() noexcept#

Create an empty array

Array a(); a.empty(); // True

inline Array(size_type len)#

Create an array of given length

inline ~Array() noexcept#

Destructor. Releases the underlying dataBlock

inline Array(const Array &other) noexcept#

Copy constructor

inline Array &operator=(Array other) noexcept#

Assignment operator After this both Arrays share the same dataBlock

Uses copy-and-swap idiom

inline Array(Array &&other) noexcept#

Move constructor

inline void reallocate(size_type new_size)#

Reallocate the array with size = new_size

Note that this invalidates the existing data!

inline void clear() noexcept#

Release data. After this the Array is empty and any data access will be invalid

inline bool empty() const noexcept#

Returns true if the Array is empty

inline size_type size() const noexcept#

Return size of the array. Zero if the array is empty.

inline bool unique() const noexcept#

Returns true if the data is unique to this Array.

inline void ensureUnique()#

Ensures that this Array does not share data with another This should be called before performing any write operations on the data.

inline iterator<T> begin() noexcept#
inline iterator<T> end() noexcept#
inline const_iterator<T> begin() const noexcept#
inline const_iterator<T> end() const noexcept#
inline T &operator[](size_type ind)#

Access a data element. This will fail if the Array is empty (so ptr is null), or if ind is out of bounds. For efficiency no checking is performed, so the user should perform checks.

inline const T &operator[](size_type ind) const#

Public Static Functions

static inline bool useStore(bool keep_using = true) noexcept#

Holds a static variable which controls whether memory blocks (dataBlock) are put into a store or new/deleted each time.

The variable is initialised to true on first use, but can be set to false by passing “false” as input. Once set to false it can’t be changed back to true.

static inline void cleanup()#

Delete all data from the store and disable the store

Note: After this is called the store cannot be re-enabled

Private Types

using dataBlock = Backing#
using dataPtrType = std::shared_ptr<dataBlock>#
using storeType = std::map<size_type, std::vector<dataPtrType>>#
using arenaType = std::vector<storeType>#

Private Functions

inline dataPtrType get(size_type len)#

Returns a pointer to a dataBlock object of size len with no references. This is either from the store, or newly allocated

Expects len >= 0

inline void release(dataPtrType &d) noexcept#

Release an dataBlock object, reducing its reference count by one. If no more references, then put back into the store. It’s important to pass a reference to the pointer, otherwise we get a copy of the shared_ptr, which therefore increases the use count and doesn’t allow us to free the pass pointer directly

Note that this is noexcept only because we’ve ensure that both a) store()[<size>] already exists, and b) it has space for at least one data block. Of course, store() could throw &#8212; in which case we’re doomed anyway, so the only thing we can do is abort

Private Members

dataPtrType ptr#

Pointer to the data container object owned by this Array. May be null

Private Static Functions

static inline storeType &store(bool cleanup = false)#

This maps from array size (size_type) to vectors of pointers to dataBlock objects

By putting the static store inside a function it is initialised on first use, and doesn’t need to be separately declared for each type T

Inputs

Parameters:

cleanup[in] If set to true, deletes all dataBlock and clears the store

Friends

inline friend void swap(Array<T, Backing> &first, Array<T, Backing> &second) noexcept#

Exchange contents with another Array of the same type. Sizes of the arrays may differ.