Skip to content

Commit

Permalink
[mdarray] Add constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Apr 26, 2024
1 parent 568beac commit af460ef
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 67 deletions.
6 changes: 6 additions & 0 deletions include/etl/_array/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,12 @@ template <typename T, size_t N>
}(etl::make_index_sequence<N>{});
}

template <typename T>
inline constexpr auto is_etl_array = false;

template <typename T, size_t Size>
inline constexpr auto is_etl_array<array<T, Size>> = true;

} // namespace etl

#endif // TETL_ARRAY_ARRAY_HPP
88 changes: 41 additions & 47 deletions include/etl/_mdarray/mdarray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@

#include <etl/_mdspan/mdspan.hpp>
#include <etl/_memory/to_address.hpp>
#include <etl/_span/span.hpp>
#include <etl/_type_traits/declval.hpp>
#include <etl/_type_traits/is_constructible.hpp>
#include <etl/_type_traits/is_convertible.hpp>
#include <etl/_type_traits/is_nothrow_constructible.hpp>

namespace etl {

/// \ingroup mdarray
template <typename ElementType, typename Extents, typename LayoutPolicy, typename Container>
struct mdarray {
private:
template <typename C, typename... Args>
static constexpr auto array_or_constructible_from = is_etl_array<C> or is_constructible_v<C, Args...>;

public:
using extents_type = Extents;
using layout_type = LayoutPolicy;
using container_type = Container;
Expand All @@ -29,14 +38,11 @@ struct mdarray {
using const_reference = typename container_type::const_reference;

[[nodiscard]] static constexpr auto rank() noexcept -> rank_type { return Extents::rank(); }

[[nodiscard]] static constexpr auto rank_dynamic() noexcept -> rank_type { return Extents::rank_dynamic(); }

[[nodiscard]] static constexpr auto static_extent(rank_type r) noexcept -> size_t
{
return Extents::static_extent(r);
}

[[nodiscard]] constexpr auto extent(rank_type r) const noexcept -> index_type { return extents().extent(r); }

// [mdarray.ctors], mdarray constructors
Expand All @@ -46,10 +52,36 @@ struct mdarray {
constexpr mdarray(mdarray const& rhs) = default;
constexpr mdarray(mdarray&& rhs) = default;

// template <typename... OtherIndexTypes>
// explicit constexpr mdarray(OtherIndexTypes... exts);
// explicit constexpr mdarray(extents_type const& ext);
// explicit constexpr mdarray(mapping_type const& m);
template <typename... OtherIndexTypes>
requires(
(is_convertible_v<OtherIndexTypes, index_type> and ...)
and (is_nothrow_constructible_v<index_type, OtherIndexTypes> and ...)
and (is_constructible_v<extents_type, OtherIndexTypes...>)
and (is_constructible_v<mapping_type, extents_type>) and (array_or_constructible_from<Container, size_t>)
)
explicit constexpr mdarray(OtherIndexTypes... exts)
: mdarray(extents_type(static_cast<index_type>(etl::move(exts))...))
{
}

explicit constexpr mdarray(extents_type const& ext)
requires(is_constructible_v<mapping_type, extents_type const&> and array_or_constructible_from<Container, size_t>)
: mdarray(mapping_type(ext))
{
}

explicit constexpr mdarray(mapping_type const& m)
requires(array_or_constructible_from<Container, size_t>)
: _map(m)
, _ctr([&]() -> container_type {
if constexpr (is_constructible_v<Container, size_t>) {
return container_type(static_cast<size_t>(_map.required_span_size()));
} else {
return {};
}
}())
{
}

// constexpr mdarray(extents_type const& ext, value_type const& val);
// constexpr mdarray(mapping_type const& m, value_type const& val);
Expand All @@ -68,41 +100,6 @@ struct mdarray {
// typename Accessor> explicit(see below) constexpr mdarray(
// mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, Accessor> const& other);

// // [mdarray.ctors.alloc], mdarray constructors with allocators
// template <typename Alloc>
// constexpr mdarray(extents_type const& ext, Alloc const& a);
// template <typename Alloc>
// constexpr mdarray(mapping_type const& m, Alloc const& a);

// template <typename Alloc>
// constexpr mdarray(extents_type const& ext, value_type const& val, Alloc const& a);
// template <typename Alloc>
// constexpr mdarray(mapping_type const& m, value_type const& val, Alloc const& a);

// template <typename Alloc>
// constexpr mdarray(extents_type const& ext, container_type const& c, Alloc const& a);
// template <typename Alloc>
// constexpr mdarray(mapping_type const& m, container_type const& c, Alloc const& a);

// template <typename Alloc>
// constexpr mdarray(extents_type const& ext, container_type&& c, Alloc const& a);
// template <typename Alloc>
// constexpr mdarray(mapping_type const& m, container_type&& c, Alloc const& a);

// template <typename OtherElementType, typename OtherExtents, typename OtherLayoutPolicy,
// typename OtherContainer,
// typename Alloc>
// explicit(see below) constexpr mdarray(
// mdarray<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherContainer> const& other,
// Alloc const& a);

// template <typename OtherElementType, typename OtherExtents, typename OtherLayoutPolicy,
// typename Accessor,
// typename Alloc>
// explicit(see below) constexpr mdarray(
// mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, Accessor> const& other, Alloc
// const& a);

// constexpr mdarray& operator=(mdarray const& rhs) = default;
// constexpr mdarray& operator=(mdarray&& rhs) = default;

Expand All @@ -113,6 +110,7 @@ struct mdarray {
// constexpr reference operator[](span<OtherIndexType, rank()> indices);
// template <typename OtherIndexType>
// constexpr reference operator[](array<OtherIndexType, rank()> const& indices);

// template <typename... OtherIndexTypes>
// constexpr const_reference operator[](OtherIndexTypes... indices) const;
// template <typename OtherIndexType>
Expand Down Expand Up @@ -147,22 +145,18 @@ struct mdarray {
[[nodiscard]] auto extract_container() && -> container_type&& { return etl::move(_ctr); }

[[nodiscard]] static constexpr auto is_always_unique() -> bool { return mapping_type::is_always_unique(); }

[[nodiscard]] static constexpr auto is_always_exhaustive() -> bool { return mapping_type::is_always_exhaustive(); }

[[nodiscard]] static constexpr auto is_always_strided() -> bool { return mapping_type::is_always_strided(); }

[[nodiscard]] constexpr auto is_unique() const -> bool { return _map.is_unique(); }

[[nodiscard]] constexpr auto is_exhaustive() const -> bool { return _map.is_exhaustive(); }

[[nodiscard]] constexpr auto is_strided() const -> bool { return _map.is_strided(); }

[[nodiscard]] constexpr auto stride(etl::size_t r) const -> index_type { return _map.stride(r); }

private:
container_type _ctr;
mapping_type _map;
container_type _ctr;
};

} // namespace etl
Expand Down
14 changes: 4 additions & 10 deletions include/etl/_span/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,10 @@ struct span;
namespace detail {

template <typename T>
inline constexpr auto is_etl_span = false;
inline constexpr auto is_span = false;

template <typename T, size_t Size>
inline constexpr auto is_etl_span<etl::span<T, Size>> = true;

template <typename T>
inline constexpr auto is_etl_array = false;

template <typename T, size_t Size>
inline constexpr auto is_etl_array<etl::array<T, Size>> = true;
inline constexpr auto is_span<etl::span<T, Size>> = true;

template <typename From, typename To>
concept span_convertible_from = is_convertible_v<From (*)[], To (*)[]>;
Expand Down Expand Up @@ -151,8 +145,8 @@ struct span {
ranges::sized_range<R>
and (ranges::borrowed_range<R> or is_const_v<T>)
and not is_array_v<remove_cvref_t<R>>
and not detail::is_etl_array<R>
and not detail::is_etl_span<R>
and not is_etl_array<R>
and not detail::is_span<R>
and detail::span_convertible_from<remove_reference_t<ranges::range_reference_t<R>>, T>
)
// clang-format on
Expand Down
39 changes: 29 additions & 10 deletions tests/mdarray/mdarray.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,40 @@
#include <etl/array.hpp>
#include <etl/concepts.hpp>
#include <etl/cstdint.hpp>
#include <etl/vector.hpp>

#include "testing/testing.hpp"

template <typename Value, typename Index>
template <typename T, typename Index>
[[nodiscard]] constexpr auto test_mdarray() -> bool
{
using matrix = etl::mdarray<Value, etl::extents<Index, 2, 3>, etl::layout_left, etl::array<Value, 6>>;
CHECK_SAME_TYPE(typename matrix::value_type, Value);
CHECK_SAME_TYPE(typename matrix::element_type, Value);
CHECK_SAME_TYPE(typename matrix::container_type, etl::array<Value, 6>);

CHECK(matrix::rank() == 2);
CHECK(matrix::rank_dynamic() == 0);
CHECK(matrix::static_extent(0) == 2);
CHECK(matrix::static_extent(1) == 3);
// traits
{
using matrix = etl::mdarray<T, etl::extents<Index, 2, 3>, etl::layout_left, etl::array<T, 6>>;
CHECK_SAME_TYPE(typename matrix::value_type, T);
CHECK_SAME_TYPE(typename matrix::element_type, T);
CHECK_SAME_TYPE(typename matrix::container_type, etl::array<T, 6>);

CHECK(matrix::rank() == 2);
CHECK(matrix::rank_dynamic() == 0);
CHECK(matrix::static_extent(0) == 2);
CHECK(matrix::static_extent(1) == 3);
}

// ctor(index...)
{
using extents = etl::dextents<Index, 2>;
using array_matrix = etl::mdarray<T, extents, etl::layout_left, etl::array<T, 6>>;
using vector_matrix = etl::mdarray<T, extents, etl::layout_left, etl::static_vector<T, 6>>;

auto am = array_matrix{2, 3};
CHECK(am.extents().extent(0) == Index(2));
CHECK(am.extents().extent(1) == Index(3));

auto vm = vector_matrix{2, 3};
CHECK(vm.extents().extent(0) == Index(2));
CHECK(vm.extents().extent(1) == Index(3));
}

return true;
}
Expand Down

0 comments on commit af460ef

Please sign in to comment.