• Docs >
  • Program Listing for File contiguous_storage_view.hpp
Shortcuts

Program Listing for File contiguous_storage_view.hpp

Return to documentation for file (include/ripple/storage/contiguous_storage_view.hpp)

#ifndef RIPPLE_STORAGE_CONTIGUOUS_STORAGE_VIEW_HPP
#define RIPPLE_STORAGE_CONTIGUOUS_STORAGE_VIEW_HPP

#include "owned_storage.hpp"
#include "storage_element_traits.hpp"
#include "storage_traits.hpp"
#include "storage_accessor.hpp"

namespace ripple {

template <typename... Ts>
class ContiguousStorageView
: public StorageAccessor<ContiguousStorageView<Ts...>> {
  // clang-format off
  using Ptr          = void*;
  using Storage      = ContiguousStorageView;
  using Helper       = detail::ContigStorageHelper<Ts...>;
  // clang-format on

  template <typename T, bool B>
  friend struct LayoutTraits;

  template <typename T>
  using element_value_t = typename storage_element_traits_t<T>::Value;

  template <size_t I>
  using nth_element_value_t = element_value_t<nth_element_t<I, Ts...>>;

  template <size_t I>
  static constexpr size_t nth_element_components_v =
    storage_element_traits_t<nth_element_t<I, Ts...>>::num_elements;

  /*==--- [constants] ------------------------------------------------------==*/

  // clang-format off
  static constexpr auto   num_types         = sizeof...(Ts);
  static constexpr auto   offsets           = Helper::offsets();
  static constexpr size_t storage_byte_size = Helper::storage_byte_size();
  // clang-format on

  template <typename T>
  static constexpr size_t element_components =
    storage_element_traits_t<T>::num_elements;

  /*==--- [allocator] ------------------------------------------------------==*/

  struct Allocator {
    static constexpr size_t alignment = Helper::max_align;

    ripple_all static constexpr auto
    allocation_size(size_t elements) noexcept -> size_t {
      return storage_byte_size * elements;
    }

    template <size_t Elements>
    ripple_all static constexpr auto
    allocation_size() noexcept -> size_t {
      return storage_byte_size * Elements;
    }

    static constexpr auto strided_types() noexcept -> size_t {
      return 1;
    }

    template <size_t I>
    static constexpr auto num_elements() noexcept -> size_t {
      return 1;
    }

    template <size_t I>
    static constexpr auto element_byte_size() noexcept -> size_t {
      return storage_byte_size;
    }

    template <typename SpaceImpl, typename Dim, diff_enable_t<Dim, int> = 0>
    ripple_all static auto offset(
      const Storage&                  storage,
      const MultidimSpace<SpaceImpl>& space,
      Dim&&                           dim,
      int                             amount) noexcept -> Storage {
      Storage r;
      r.data_ = static_cast<void*>(
        static_cast<char*>(storage.data_) +
        amount * storage_byte_size * space.step(ripple_forward(dim)));
      return r;
    }

    template <typename SpaceImpl, typename Dim>
    ripple_all static auto shift(
      Storage&                        storage,
      const MultidimSpace<SpaceImpl>& space,
      Dim&&                           dim,
      int                             amount) noexcept -> void {
      storage.data_ = static_cast<void*>(
        static_cast<char*>(storage.data_) +
        amount * storage_byte_size * space.step(ripple_forward(dim)));
    }

    template <typename SpaceImpl>
    ripple_all static auto
    create(void* ptr, const MultidimSpace<SpaceImpl>& space) noexcept
      -> Storage {
      Storage r;
      r.data_ = ptr;
      return r;
    }
  };

  /*==--- [members] --------------------------------------------------------==*/

  Ptr data_ = nullptr;

 public:
  template <size_t I>
  static constexpr auto nth_element_components =
    element_components<nth_element_t<I, Ts...>>;

  /*==--- [construction] ---------------------------------------------------==*/

  ContiguousStorageView() noexcept = default;

  template <typename Impl>
  ripple_all
  ContiguousStorageView(const StorageAccessor<Impl>& other) noexcept {
    copy(static_cast<const Impl&>(other));
  }

  ContiguousStorageView(const ContiguousStorageView& other) noexcept = default;

  ContiguousStorageView(ContiguousStorageView&& other) noexcept = default;

  /*==--- [operator overloads] ---------------------------------------------==*/

  template <typename Impl>
  ripple_all auto operator=(const StorageAccessor<Impl>& other) noexcept
    -> ContiguousStorageView& {
    copy(static_cast<const Impl&>(other));
    return *this;
  }

  ripple_all auto operator=(const ContiguousStorageView& other) noexcept
    -> ContiguousStorageView& {
    copy(other);
    return *this;
  }

  ripple_all auto
  operator=(ContiguousStorageView&& other) noexcept -> ContiguousStorageView& {
    data_       = other.data_;
    other.data_ = nullptr;
    return *this;
  }

  /*==--- [interface] ------------------------------------------------------==*/

  ripple_all auto data() noexcept -> void* {
    return data_;
  }

  ripple_all auto data() const noexcept -> const void* {
    return data_;
  }

  ripple_all auto data_ptrs() noexcept -> std::vector<Ptr> {
    return {data_};
  }

  template <typename Other>
  ripple_all auto copy(const Other& other) noexcept -> void {
    static_assert(
      is_storage_accessor_v<Other>, "Argument type isn't a StorageAccessor!");

    unrolled_for<num_types>([&](auto i) {
      constexpr size_t type_idx = i;
      using Type                = nth_element_t<type_idx, Ts...>;
      constexpr auto values     = element_components<Type>;

      copy_from_to<type_idx, values, Type>(other, *this);
    });
  }

  template <size_t I>
  ripple_all constexpr auto components_of() const noexcept -> size_t {
    return Helper::components[I];
  }

  template <
    size_t I,
    typename T                  = nth_element_t<I, Ts...>,
    non_vec_element_enable_t<T> = 0>
  ripple_all auto get() noexcept -> element_value_t<T>& {
    constexpr size_t offset = offsets[I];
    return *static_cast<element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset));
  }

  template <
    size_t I,
    typename T                  = nth_element_t<I, Ts...>,
    non_vec_element_enable_t<T> = 0>
  ripple_all auto get() const noexcept -> const element_value_t<T>& {
    constexpr size_t offset = offsets[I];
    return *static_cast<const element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset));
  }

  template <
    size_t I,
    size_t J,
    typename T              = nth_element_t<I, Ts...>,
    vec_element_enable_t<T> = 0>
  ripple_all auto get() noexcept -> element_value_t<T>& {
    constexpr size_t elements = element_components<T>;
    static_assert(J < elements, "Out of range acess for storage element!");
    constexpr size_t offset = offsets[I];
    return static_cast<element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset))[J];
  }

  template <
    size_t I,
    size_t J,
    typename T              = nth_element_t<I, Ts...>,
    vec_element_enable_t<T> = 0>
  ripple_all auto get() const noexcept -> const element_value_t<T>& {
    static_assert(
      J < element_components<T>, "Out of range acess for storage element!");
    constexpr size_t offset = offsets[I];
    return static_cast<const element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset))[J];
  }

  template <
    size_t I,
    typename T              = nth_element_t<I, Ts...>,
    vec_element_enable_t<T> = 0>
  ripple_all auto get(size_t j) noexcept -> element_value_t<T>& {
    constexpr size_t offset = offsets[I];
    return static_cast<element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset))[j];
  }

  template <
    size_t I,
    typename T              = nth_element_t<I, Ts...>,
    vec_element_enable_t<T> = 0>
  ripple_all auto
  get(size_t j) const noexcept -> const element_value_t<T>& {
    constexpr size_t offset = offsets[I];
    return static_cast<const element_value_t<T>*>(
      static_cast<void*>(static_cast<char*>(data_) + offset))[j];
  }
};

} // namespace ripple

#endif // RIPPLE_STORAGE_CONTIGUOUS_STORAGE_VIEW_HPP

Docs

Access comprehensive developer documentation for Ripple

View Docs

Tutorials

Get tutorials to help with understand all features

View Tutorials

Examples

Find examples to help get started

View Examples