From 71538da6257aec901e0ca60951a477d85a872062 Mon Sep 17 00:00:00 2001 From: Christian Trott Date: Tue, 12 Mar 2024 06:16:28 -0600 Subject: [PATCH 1/3] Fix size() function, add some ctors --- include/experimental/__p1684_bits/mdarray.hpp | 63 ++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/include/experimental/__p1684_bits/mdarray.hpp b/include/experimental/__p1684_bits/mdarray.hpp index bdc5925f..44368051 100644 --- a/include/experimental/__p1684_bits/mdarray.hpp +++ b/include/experimental/__p1684_bits/mdarray.hpp @@ -43,11 +43,15 @@ namespace { struct container_is_array : std::false_type { template static constexpr C construct(const M& m) { return C(m.required_span_size()); } + template + static constexpr C construct(const M& m, typename C::value_type value) { return C(m.required_span_size(), value); } }; template struct container_is_array> : std::true_type { template static constexpr std::array construct(const M&) { return std::array(); } + template + static constexpr std::array construct(const M&, T value) { std::array a; for(size_t i=0; i::construct(map_)) { } + MDSPAN_FUNCTION_REQUIRES( + (MDSPAN_INLINE_FUNCTION constexpr), + mdarray, (const extents_type& exts, element_type value), , + /* requires */ ((_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, element_type) || + container_is_array::value) && + _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) + ) : map_(exts), ctr_(container_is_array::construct(map_, value)) + { } + + MDSPAN_FUNCTION_REQUIRES( + (MDSPAN_INLINE_FUNCTION constexpr), + mdarray, (const mapping_type& m, element_type value), , + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, element_type) || + container_is_array::value) + ) : map_(m), ctr_(container_is_array::construct(map_, value)) + { } + MDSPAN_FUNCTION_REQUIRES( (MDSPAN_INLINE_FUNCTION constexpr), mdarray, (const extents_type& exts, const container_type& ctr), , @@ -190,6 +211,25 @@ class mdarray { : map_(map), ctr_(map_.required_span_size(), a) { } +MDSPAN_TEMPLATE_REQUIRES( + class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, element_type, Alloc) && + _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const extents_type& exts, element_type v, const Alloc& a) + : map_(exts), ctr_(map_.required_span_size(), v, a) + { } + + MDSPAN_TEMPLATE_REQUIRES( + class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, element_type, Alloc)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mapping_type& map, element_type v, const Alloc& a) + : map_(map), ctr_(map_.required_span_size(), v, a) + { } + // Constructors for container types constructible from a container and allocator MDSPAN_TEMPLATE_REQUIRES( class Alloc, @@ -243,6 +283,23 @@ class mdarray { static_assert( std::is_constructible::value, ""); } + // construction from mdspan + // TODO: needs proper fill operation not just assuming contiguous and construction from iterators + MDSPAN_TEMPLATE_REQUIRES( + class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessor, + /* requires */ ( + _MDSPAN_TRAIT( std::is_constructible, mapping_type, typename OtherLayoutPolicy::template mapping) && + _MDSPAN_TRAIT( std::is_constructible, container_type, size_t) + ) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mdspan& other) + : map_(other.mapping()), ctr_(other.data_handle(), other.data_handle() + other.mapping().required_span_size()) + { + static_assert( std::is_constructible::value, ""); + assert(other.is_exhaustive()); + } + MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (const mdarray&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (mdarray&&) = default; MDSPAN_INLINE_FUNCTION_DEFAULTED @@ -378,7 +435,11 @@ class mdarray { MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return map_.extents(); }; MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return map_.extents().extent(r); }; MDSPAN_INLINE_FUNCTION constexpr index_type size() const noexcept { -// return __impl::__size(*this); + index_type extents_prd = 1; + for(rank_type r = 0; r < rank(); r++) extents_prd *= map_.extents().extent(r); + return extents_prd; + }; + MDSPAN_INLINE_FUNCTION constexpr index_type container_size() const noexcept { return ctr_.size(); }; From b9e42b9cd84c97b96a3ad00738100c172bca670d Mon Sep 17 00:00:00 2001 From: Christian Trott Date: Tue, 12 Mar 2024 06:16:56 -0600 Subject: [PATCH 2/3] Add mdarray ctors example --- examples/CMakeLists.txt | 1 + examples/mdarray_ctors/CMakeLists.txt | 1 + examples/mdarray_ctors/mdarray_ctors.cpp | 266 +++++++++++++++++++++++ 3 files changed, 268 insertions(+) create mode 100644 examples/mdarray_ctors/CMakeLists.txt create mode 100644 examples/mdarray_ctors/mdarray_ctors.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 32981b6c..d829743d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,3 +16,4 @@ add_subdirectory(dot_product) add_subdirectory(tiled_layout) add_subdirectory(restrict_accessor) add_subdirectory(aligned_accessor) +add_subdirectory(mdarray_ctors) diff --git a/examples/mdarray_ctors/CMakeLists.txt b/examples/mdarray_ctors/CMakeLists.txt new file mode 100644 index 00000000..f565a1a3 --- /dev/null +++ b/examples/mdarray_ctors/CMakeLists.txt @@ -0,0 +1 @@ +mdspan_add_example(mdarray_ctors) diff --git a/examples/mdarray_ctors/mdarray_ctors.cpp b/examples/mdarray_ctors/mdarray_ctors.cpp new file mode 100644 index 00000000..72287348 --- /dev/null +++ b/examples/mdarray_ctors/mdarray_ctors.cpp @@ -0,0 +1,266 @@ +//@HEADER +// ************************************************************************ +// +// Kokkos v. 4.0 +// Copyright (2022) National Technology & Engineering +// Solutions of Sandia, LLC (NTESS). +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. +// See https://kokkos.org/LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//@HEADER + +#include +#include + +#include + +#define SUPPORT_ALLOC + +template +void check(mda_t& a, ext_t ext, map_t map, Container& c) { + assert(a.extents() == ext); + assert(a.mapping() == map); + assert(a.container_size() == c.size()); +} + +// 11 ctors +template +void test_minimal_set() { + using ext_t = typename mda_t::extents_type; + using map_t = typename mda_t::mapping_type; + ext_t ext(10, 15); + map_t map(ext); + Container c(map.required_span_size()); + + { // default construction + mda_t a; + assert(a.extents() == ext_t()); + assert(a.container_size() == map_t(ext_t()).required_span_size()); + } + { // copy constructor + mda_t a(10, 15); + auto ptr = a.data(); + mda_t b(a); + check(b, ext, map, c); + assert(b.data() != a.data()); + assert(a.data() == ptr); + } + { // move constructor + mda_t a(10, 15); + auto ptr = a.data(); + mda_t b(std::move(a)); + check(b, ext, map, c); + assert(b.data() == ptr); + } + { // integrals + mda_t a(10, 15); + check(a, ext, map, c); + } + { // extents + mda_t a(ext); + check(a, ext, map, c); + } + { // mapping + mda_t a(map); + check(a, ext, map, c); + } + { // extents + container + mda_t a(ext, c); + check(a, ext, map, c); + } + { // mapping + container + mda_t a(map, c); + check(a, ext, map, c); + } + { // extents + move(container) + auto c2 = c; + double* ptr = c2.data(); + mda_t a(ext, std::move(c2)); + check(a, ext, map, c); + assert(a.data() == ptr); + } + { // mapping + move(container) + auto c2 = c; + double* ptr = c2.data(); + mda_t a(map, std::move(c2)); + check(a, ext, map, c); + assert(a.data() == ptr); + } + { // mdspan + mda_t a(10, 15); + a(0,0) = 99; + mda_t b(a.to_mdspan()); + check(b, ext, map, c); + assert(b(0,0) == 99); + } +} + +// baseline allocator support adds 6 ctors +template +void test_alloc_set() { + using ext_t = typename mda_t::extents_type; + using map_t = typename mda_t::mapping_type; + ext_t ext(10, 15); + map_t map(ext); + Container c(map.required_span_size()); + auto alloc = std::allocator(); + + { // default construction + mda_t a; + assert(a.extents() == ext_t()); + assert(a.container_size() == map_t(ext_t()).required_span_size()); + } + { // integrals -> never directly supported + #ifdef SUPPORT_ALLOC + mda_t a(ext_t(10, 15), alloc); + check(a, ext, map, c); + #endif + } + { // extents + #ifdef SUPPORT_ALLOC + mda_t a(ext, alloc); + check(a, ext, map, c); + #endif + } + { // mapping + #ifdef SUPPORT_ALLOC + mda_t a(map, alloc); + check(a, ext, map, c); + #endif + } + { // extents + container + #ifdef SUPPORT_ALLOC + mda_t a(ext, c, alloc); + #else + mda_t a(ext, std::move(Container(c,alloc))); + #endif + check(a, ext, map, c); + } + { // mapping + container + #ifdef SUPPORT_ALLOC + mda_t a(map, c, alloc); + #else + mda_t a(map, std::move(Container(c,alloc))); + #endif + check(a, ext, map, c); + } + { // extents + move(container) + auto c2 = c; + double* ptr = c2.data(); + #ifdef SUPPORT_ALLOC + mda_t a(ext, std::move(c2), alloc); + #else + mda_t a(ext, std::move(Container(std::move(c2),alloc))); + #endif + check(a, ext, map, c); + assert(a.data() == ptr); + } + { // mapping + move(container) + auto c2 = c; + double* ptr = c2.data(); + #ifdef SUPPORT_ALLOC + mda_t a(map, std::move(c2), alloc); + #else + mda_t a(map, std::move(Container(std::move(c2),alloc))); + #endif + check(a, ext, map, c); + assert(a.data() == ptr); + } +} + +// construct with fill value adds 2+2(alloc) ctors +template +void test_value_set() { + using ext_t = typename mda_t::extents_type; + using map_t = typename mda_t::mapping_type; + ext_t ext(10, 15); + map_t map(ext); + Container c(map.required_span_size()); + auto alloc = std::allocator(); + + { // default construction + mda_t a; + assert(a.extents() == ext_t()); + assert(a.container_size() == map_t(ext_t()).required_span_size()); + } + { // integrals -> never directly supported + mda_t a(ext_t(10, 15), 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents + mda_t a(ext, 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping + mda_t a(map, 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents + mda_t a(ext, 99, alloc); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping + mda_t a(map, 99, alloc); + check(a, ext, map, c); + assert(a(0,0)==99); + } +} + +template +void test_value_set() { + using ext_t = typename mda_t::extents_type; + using map_t = typename mda_t::mapping_type; + ext_t ext(10, 15); + map_t map(ext); + Container c(map.required_span_size()); + auto alloc = std::allocator(); + + { // default construction + mda_t a; + assert(a.extents() == ext_t()); + assert(a.container_size() == map_t(ext_t()).required_span_size()); + } + { // integrals -> never directly supported + mda_t a(ext_t(10, 15), 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents + mda_t a(ext, 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping + mda_t a(map, 99); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents + mda_t a(ext, 99, alloc); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping + mda_t a(map, 99, alloc); + check(a, ext, map, c); + assert(a(0,0)==99); + } +} + + + +int main(int argc, char* argv[]) { + test_minimal_set>, std::vector>(); + test_alloc_set>, std::vector>(); + test_value_set>, std::vector>(); + return 0; +} From c6a94062cb1a417c44e3bc4b0ae9531c2bbf2164 Mon Sep 17 00:00:00 2001 From: Christian Trott Date: Fri, 15 Mar 2024 15:17:45 -0600 Subject: [PATCH 3/3] Add more constructors for mdarray --- examples/mdarray_ctors/mdarray_ctors.cpp | 116 ++++++++++++++---- include/experimental/__p1684_bits/mdarray.hpp | 113 +++++++++++++++++ 2 files changed, 207 insertions(+), 22 deletions(-) diff --git a/examples/mdarray_ctors/mdarray_ctors.cpp b/examples/mdarray_ctors/mdarray_ctors.cpp index 72287348..40f13277 100644 --- a/examples/mdarray_ctors/mdarray_ctors.cpp +++ b/examples/mdarray_ctors/mdarray_ctors.cpp @@ -14,12 +14,15 @@ // //@HEADER +#define MDARRAY_SUPPORT_ALLOC +#define MDARRAY_SUPPORT_ITERATOR +#define MDARRAY_SUPPORT_INITLIST + #include #include #include -#define SUPPORT_ALLOC template void check(mda_t& a, ext_t ext, map_t map, Container& c) { @@ -116,25 +119,25 @@ void test_alloc_set() { assert(a.container_size() == map_t(ext_t()).required_span_size()); } { // integrals -> never directly supported - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(ext_t(10, 15), alloc); check(a, ext, map, c); #endif } { // extents - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(ext, alloc); check(a, ext, map, c); #endif } { // mapping - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(map, alloc); check(a, ext, map, c); #endif } { // extents + container - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(ext, c, alloc); #else mda_t a(ext, std::move(Container(c,alloc))); @@ -142,7 +145,7 @@ void test_alloc_set() { check(a, ext, map, c); } { // mapping + container - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(map, c, alloc); #else mda_t a(map, std::move(Container(c,alloc))); @@ -152,7 +155,7 @@ void test_alloc_set() { { // extents + move(container) auto c2 = c; double* ptr = c2.data(); - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(ext, std::move(c2), alloc); #else mda_t a(ext, std::move(Container(std::move(c2),alloc))); @@ -163,7 +166,7 @@ void test_alloc_set() { { // mapping + move(container) auto c2 = c; double* ptr = c2.data(); - #ifdef SUPPORT_ALLOC + #ifdef MDARRAY_SUPPORT_ALLOC mda_t a(map, std::move(c2), alloc); #else mda_t a(map, std::move(Container(std::move(c2),alloc))); @@ -204,63 +207,132 @@ void test_value_set() { assert(a(0,0)==99); } { // extents +#ifdef MDARRAY_SUPPORT_ALLOC mda_t a(ext, 99, alloc); +#else + mda_t a(ext, std::move(Container(99, alloc))); +#endif check(a, ext, map, c); assert(a(0,0)==99); } { // mapping +#ifdef MDARRAY_SUPPORT_ALLOC mda_t a(map, 99, alloc); +#else + mda_t a(map, std::move(Container(99, alloc))); +#endif check(a, ext, map, c); assert(a(0,0)==99); } } +#ifdef MDARRAY_SUPPORT_ITERATOR +// ctors from iterator 2+2 +// requires container constructible from iterators +// precondition: Container(begin, end).size() >= map.required_span_size() template -void test_value_set() { +void test_iterator_set() { using ext_t = typename mda_t::extents_type; using map_t = typename mda_t::mapping_type; ext_t ext(10, 15); map_t map(ext); Container c(map.required_span_size()); + c[0] = 99; auto alloc = std::allocator(); - { // default construction - mda_t a; - assert(a.extents() == ext_t()); - assert(a.container_size() == map_t(ext_t()).required_span_size()); - } { // integrals -> never directly supported - mda_t a(ext_t(10, 15), 99); + mda_t a(ext_t(10, 15), c.begin(), c.end()); check(a, ext, map, c); assert(a(0,0)==99); } { // extents - mda_t a(ext, 99); + mda_t a(ext, c.begin(), c.end()); check(a, ext, map, c); assert(a(0,0)==99); } { // mapping - mda_t a(map, 99); + mda_t a(map, c.begin(), c.end()); check(a, ext, map, c); assert(a(0,0)==99); } { // extents - mda_t a(ext, 99, alloc); +#ifdef MDSPAN_SUPPORT_ALLOC + mda_t a(ext, c.begin(), c.end(), alloc); +#else + mda_t a(ext, std::move(Container(c.begin(), c.end(), alloc))); +#endif check(a, ext, map, c); assert(a(0,0)==99); } { // mapping - mda_t a(map, 99, alloc); +#ifdef MDSPAN_SUPPORT_ALLOC + mda_t a(map, c.begin(), c.end(), alloc); +#else + mda_t a(map, std::move(Container(c.begin(), c.end(), alloc))); +#endif check(a, ext, map, c); assert(a(0,0)==99); } } +#endif + +#ifdef MDARRAY_SUPPORT_INITLIST +// ctors from iterator 2+2 +template +void test_initlist_set() { + using ext_t = typename mda_t::extents_type; + using map_t = typename mda_t::mapping_type; + ext_t ext(2, 3); + map_t map(ext); + Container c({99,2,3,4,5,6}); + auto alloc = std::allocator(); + { // integrals -> never directly supported + mda_t a(ext_t(2, 3), {99,2,3,4,5,6}); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents + mda_t a(ext, {99,2,3,4,5,6}); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping + mda_t a(map, {99,2,3,4,5,6}); + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // extents +#ifdef MDARRAY_SUPPORT_ALLOC + mda_t a(ext, {99,2,3,4,5,6}, alloc); +#else + mda_t a(ext, std::move(Container({99,2,3,4,5,6}, alloc))); +#endif + check(a, ext, map, c); + assert(a(0,0)==99); + } + { // mapping +#ifdef MDARRAY_SUPPORT_ALLOC + mda_t a(map, {99,2,3,4,5,6}, alloc); +#else + mda_t a(map, std::move(Container({99,2,3,4,5,6}, alloc))); +#endif + check(a, ext, map, c); + assert(a(0,0)==99); + } +} +#endif int main(int argc, char* argv[]) { - test_minimal_set>, std::vector>(); - test_alloc_set>, std::vector>(); - test_value_set>, std::vector>(); + test_minimal_set>, std::vector>(); + test_alloc_set>, std::vector>(); + test_value_set>, std::vector>(); +#ifdef MDARRAY_SUPPORT_ITERATOR + test_iterator_set>, std::vector>(); +#endif +#ifdef MDARRAY_SUPPORT_INITLIST + test_initlist_set>, std::vector>(); +#endif return 0; } diff --git a/include/experimental/__p1684_bits/mdarray.hpp b/include/experimental/__p1684_bits/mdarray.hpp index 44368051..269d21e5 100644 --- a/include/experimental/__p1684_bits/mdarray.hpp +++ b/include/experimental/__p1684_bits/mdarray.hpp @@ -19,6 +19,7 @@ #include "../mdspan" #include #include +#include namespace MDSPAN_IMPL_STANDARD_NAMESPACE { namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { @@ -191,6 +192,7 @@ class mdarray { static_assert( std::is_constructible::value, ""); } +#ifdef MDARRAY_SUPPORT_ALLOC // Constructors for container types constructible from a size and allocator MDSPAN_TEMPLATE_REQUIRES( class Alloc, @@ -282,6 +284,117 @@ MDSPAN_TEMPLATE_REQUIRES( { static_assert( std::is_constructible::value, ""); } +#endif + +#ifdef MDARRAY_SUPPORT_ITERATOR + // Constructors for container types constructible from a size and allocator + MDSPAN_TEMPLATE_REQUIRES( + class BeginIter, class EndIter, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, BeginIter, EndIter) && + _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const extents_type& exts, BeginIter b, EndIter e) + : map_(exts), ctr_(b, e) + { + assert(ctr_.size() >= map_.required_span_size()); + } + + MDSPAN_TEMPLATE_REQUIRES( + class BeginIter, class EndIter, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, BeginIter, EndIter) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mapping_type& map, BeginIter b, EndIter e) + : map_(map), ctr_(b, e) + { + assert(ctr_.size() >= map_.required_span_size()); + } + +#ifdef MDARRAY_SUPPORT_ALLOC + // Constructors for container types constructible from a size and allocator + MDSPAN_TEMPLATE_REQUIRES( + class BeginIter, class EndIter, class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, BeginIter, EndIter, Alloc) && + _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const extents_type& exts, BeginIter b, EndIter e, const Alloc& alloc) + : map_(exts), ctr_(b, e, alloc) + { + assert(ctr_.size() >= map_.required_span_size()); + } + + MDSPAN_TEMPLATE_REQUIRES( + class BeginIter, class EndIter, class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, BeginIter, EndIter, Alloc) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void) && + !_MDSPAN_TRAIT( std::is_same, typename std::iterator_traits::iterator_category, void)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mapping_type& map, BeginIter b, EndIter e, const Alloc& alloc) + : map_(map), ctr_(b, e, alloc) + { + assert(ctr_.size() >= map_.required_span_size()); + } +#endif +#endif + +#ifdef MDARRAY_SUPPORT_INITLIST + // Constructors for container types constructible from a size and allocator +// MDSPAN_TEMPLATE_REQUIRES( +// /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, std::initializer_list) && +// _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) +// ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const extents_type& exts, std::initializer_list il) + : map_(exts), ctr_(il) + { + assert(ctr_.size() >= map_.required_span_size()); + } + +// MDSPAN_TEMPLATE_REQUIRES( +// /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, std::initializer_list)) +// ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mapping_type& map, std::initializer_list il) + : map_(map), ctr_(il) + { + assert(ctr_.size() >= map_.required_span_size()); + } + +#ifdef MDARRAY_SUPPORT_ALLOC + // Constructors for container types constructible from a size and allocator + MDSPAN_TEMPLATE_REQUIRES( + class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, std::initializer_list, Alloc) && + _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const extents_type& exts, std::initializer_list il, const Alloc& alloc) + : map_(exts), ctr_(il, alloc) + { + assert(ctr_.size() >= map_.required_span_size()); + } + + MDSPAN_TEMPLATE_REQUIRES( + class Alloc, + /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, std::initializer_list, Alloc)) + ) + MDSPAN_INLINE_FUNCTION + constexpr mdarray(const mapping_type& map, std::initializer_list il, const Alloc& alloc) + : map_(map), ctr_(il, alloc) + { + assert(ctr_.size() >= map_.required_span_size()); + } +#endif +#endif // construction from mdspan // TODO: needs proper fill operation not just assuming contiguous and construction from iterators