# soa1d_container

Template class for "Structure of Arrays" memory layout of a one-dimensional container of Primitives. `#include <sdlt/soa1d_container.h>`

## Syntax

    template<typename PrimitiveT,
             int AlignD1OnIndexT = 0,
             class AllocatorT = allocator::default_alloc>
    class soa1d_container;

## Arguments

`typename PrimitiveT` | The type that each element in the array will store
`int AlignD1OnIndexT = 0` | [Optional] The index on which the data access will be aligned (useful for stencils)
`class AllocatorT = allocator::default_alloc` | [Optional] Specify type of allocator to be used. `allocator::default_alloc` is currently the only allocator supported.

## Description

Dynamically sized container of Primitive elements with memory layout as a Structure of Arrays internally providing:

- Dynamic resizing with interface similar to `std::vector`
- Accessor objects suitable for efficient data access inside SIMD loops

Member | Description
--- | ---
    typedef size_t size_type;
| Type to use when specifying sizes to methods of the container.
    template <typename OffsetT = no_offset>
    using accessor;
| Template alias to an accessor for this container
    template <typename OffsetT = no_offset >
    using const_accessor;
| Template alias to an const_accessor for this container

Member Type | Description
--- | ---
    soa1d_container(
        size_type size_d1 = 0u,
        buffer_offset_in_cachelines buffer_offset
            = buffer_offset_in_cachelines(0),
        const allocator_type & an_allocator = allocator_type());
| Constructs an uninitialized container of size_d1 elements, using optionally specified allocator instance, using optionally specified number of cache lines to offset the start of the buffer in memory to allow management of 4k cache aliasing.
    soa1d_container(
        size_type size_d1,
        const PrimitiveT &a_value,
        buffer_offset_in_cachelines buffer_offset
            = buffer_offset_in_cachelines(0),
        const allocator_type & an_allocator
            = allocator_type());
| Constructs a container of size_d1 elements initializing each with a_value, using optionally specified allocator instance, using optionally specified number of cache lines to offset the start of the buffer in memory to allow management of 4k cache aliasing.
    template<typename StlAllocatorT>
    soa1d_container(
        const std::vector<PrimitiveT, StlAllocatorT> &other,
        buffer_offset_in_cachelines buffer_offset
            = buffer_offset_in_cachelines(0),
        const allocator_type & an_allocator
            = allocator_type());
| Constructs a container with a copy of each of the elements in other, in the same order, using optionally specified allocator instance, using optionally specified number of cache lines to offset the start of the buffer in memory to allow management of 4k cache aliasing.
    soa1d_container(
        const PrimitiveT *other_array,
        size_type number_of_elements,
        buffer_offset_in_cachelines buffer_offset
            = buffer_offset_in_cachelines(0),
        const allocator_type & an_allocator
            = allocator_type());
| Constructs a container with a copy of number_of_elements elements from the array other_array, in the same order, using optionally specified allocator instance, using optionally specified number of cache lines to offset the start of the buffer in memory to allow management of 4k cache aliasing.
    template< typename IteratorT >
    soa1d_container(
        IteratorT a_begin,
        IteratorT an_end,
        buffer_offset_in_cachelines buffer_offset
            = buffer_offset_in_cachelines(0),
        const allocator_type & an_allocator
            = allocator_type());
| Constructs a container with as many elements as the range [a_begin - an_end), each with a copy of the value from its corresponding element in that range, in the same order, using optionally specified allocator instance, using optionally specified number of cache lines to offset the start of the buffer in memory to allow management of 4k cache aliasing.
    soa1d_container clone() const;
| Returns: a new soa1d_container instance with its own copy of the elements
    void resize(size_type new_size_d1);
| Resize the container so that it contains new_size_d1 elements. If the new size is greater than the current container size, the new elements are unitialized.
    accessor<> access();
| Returns: accessor with no embedded index offset.
    accessor<int> access(int offset);
| Returns: accessor with an integer based embedded index offset.
    template<int IndexAlignmentT>
    accessor<aligned_offset<IndexAlignmentT> >
        access(aligned_offset<IndexAlignmentT>);
| Returns: accessor with an aligned_offset<IndexAlignmentT> based embedded index offset.
    template<int OffsetT>
    accessor<fixed_offset<OffsetT> >
        access(fixed_offset<OffsetT>);
| Returns: accessor with a fixed_offset<OffsetT> based embedded index offset.
    const_accessor<> const_access() const;
| Returns: const_accessor with no embedded index offset.
    const_accessor<int>
        const_access(int offset) const;
| Returns: const_accessor with an integer based embedded index offset.
    const_accessor<aligned_offset<IndexAlignmentT>>
        const_access(aligned_offset<IndexAlignmentT> offset) const;
| Returns: const_accessor with an aligned_offset<IndexAlignmentT> based embedded index offset.
    template<int OffsetT>
    const_accessor<fixed_offset<OffsetT> >
        const_access(fixed_offset<OffsetT>) const;
| Returns: const_accessor with a fixed_offset<OffsetT> based embedded index offset.

STL Compatibility

In addition to the performance oriented interface explained in the table above, soa1d_container implements a subset of the `std::vector` interface that is intended for ease of integration, not high performance. Due to the import/export only requirement we can’t return a reference to the object, instead `iterators` and `operator[]` return a Proxy object while other "const' methods return a "value_type const". Futhermore, iterators do not support the `->` operator. Despite that limitation the iterators can be passed to any STL algorithm. Also for performance reasons, resize does not initialize new elements. The following `std::vector` interface methods are implemented:

- size, max_size, capacity, empty, reserve, shrink_to_fit

- assign, push_back, pop_back, clear, insert, emplace, erase

- cbegin, cend, begin, end, begin, end, crbegin, crend, rbegin, rend, rbegin, rend

- operator[], front() const, back() const, at() const

- swap, ==, !=

- swap, soa1d_container(soa1d_container&& donor), soa1d_container & operator=(soa1d_container&& donor)

Parent topic: User-Level Interface