summaryrefslogtreecommitdiff
path: root/ext/mdspan/include/experimental/__p0009_bits
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-02-05 19:09:43 +0200
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-03-26 15:44:00 +0200
commit6c49fe5b811464f59e3a31b869734071da0ec7c1 (patch)
tree3fb287472a670b1efe1866906db1ac67229d6d96 /ext/mdspan/include/experimental/__p0009_bits
parent9b2a7728b2b0b26065ba79cfbbd20f783f4a9988 (diff)
Add mdspan includes
From https://github.com/kokkos/mdspan Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Diffstat (limited to 'ext/mdspan/include/experimental/__p0009_bits')
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp195
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/config.hpp290
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/default_accessor.hpp56
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp35
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/extents.hpp693
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp26
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/layout_left.hpp269
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/layout_right.hpp265
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/layout_stride.hpp667
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/macros.hpp699
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/mdspan.hpp432
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp97
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/trait_backports.hpp132
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/type_list.hpp87
-rw-r--r--ext/mdspan/include/experimental/__p0009_bits/utility.hpp172
15 files changed, 4115 insertions, 0 deletions
diff --git a/ext/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp b/ext/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp
new file mode 100644
index 0000000..25389a2
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp
@@ -0,0 +1,195 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+#include "trait_backports.hpp"
+
+#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+# include "no_unique_address.hpp"
+#endif
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+// For no unique address emulation, this is the case taken when neither are empty.
+// For real `[[no_unique_address]]`, this case is always taken.
+template <class _T1, class _T2, class _Enable = void> struct __compressed_pair {
+ _MDSPAN_NO_UNIQUE_ADDRESS _T1 __t1_val{};
+ _MDSPAN_NO_UNIQUE_ADDRESS _T2 __t2_val{};
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { return __t1_val; }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept {
+ return __t1_val;
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { return __t2_val; }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept {
+ return __t2_val;
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair() = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~__compressed_pair() = default;
+ template <class _T1Like, class _T2Like>
+ MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2)
+ : __t1_val((_T1Like &&) __t1), __t2_val((_T2Like &&) __t2) {}
+};
+
+#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+
+// First empty.
+template <class _T1, class _T2>
+struct __compressed_pair<
+ _T1, _T2,
+ std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T1) && !_MDSPAN_TRAIT(std::is_empty, _T2)>>
+ : private _T1 {
+ _T2 __t2_val{};
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept {
+ return *static_cast<_T1 *>(this);
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept {
+ return *static_cast<_T1 const *>(this);
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { return __t2_val; }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept {
+ return __t2_val;
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair() = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~__compressed_pair() = default;
+ template <class _T1Like, class _T2Like>
+ MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2)
+ : _T1((_T1Like &&) __t1), __t2_val((_T2Like &&) __t2) {}
+};
+
+// Second empty.
+template <class _T1, class _T2>
+struct __compressed_pair<
+ _T1, _T2,
+ std::enable_if_t<!_MDSPAN_TRAIT(std::is_empty, _T1) && _MDSPAN_TRAIT(std::is_empty, _T2)>>
+ : private _T2 {
+ _T1 __t1_val{};
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { return __t1_val; }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept {
+ return __t1_val;
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept {
+ return *static_cast<_T2 *>(this);
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept {
+ return *static_cast<_T2 const *>(this);
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair() = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~__compressed_pair() = default;
+
+ template <class _T1Like, class _T2Like>
+ MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2)
+ : _T2((_T2Like &&) __t2), __t1_val((_T1Like &&) __t1) {}
+};
+
+// Both empty.
+template <class _T1, class _T2>
+struct __compressed_pair<
+ _T1, _T2,
+ std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T1) && _MDSPAN_TRAIT(std::is_empty, _T2)>>
+ // We need to use the __no_unique_address_emulation wrapper here to avoid
+ // base class ambiguities.
+#ifdef _MDSPAN_COMPILER_MSVC
+// MSVC doesn't allow you to access public static member functions of a type
+// when you *happen* to privately inherit from that type.
+ : protected __no_unique_address_emulation<_T1, 0>,
+ protected __no_unique_address_emulation<_T2, 1>
+#else
+ : private __no_unique_address_emulation<_T1, 0>,
+ private __no_unique_address_emulation<_T2, 1>
+#endif
+{
+ using __first_base_t = __no_unique_address_emulation<_T1, 0>;
+ using __second_base_t = __no_unique_address_emulation<_T2, 1>;
+
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept {
+ return this->__first_base_t::__ref();
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept {
+ return this->__first_base_t::__ref();
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept {
+ return this->__second_base_t::__ref();
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept {
+ return this->__second_base_t::__ref();
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair() = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __compressed_pair(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair const &) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair &
+ operator=(__compressed_pair &&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~__compressed_pair() = default;
+ template <class _T1Like, class _T2Like>
+ MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2) noexcept
+ : __first_base_t(_T1((_T1Like &&) __t1)),
+ __second_base_t(_T2((_T2Like &&) __t2))
+ { }
+};
+
+#endif // !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+
+} // end namespace detail
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/config.hpp b/ext/mdspan/include/experimental/__p0009_bits/config.hpp
new file mode 100644
index 0000000..a23d013
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/config.hpp
@@ -0,0 +1,290 @@
+//@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
+#pragma once
+
+#ifndef __has_include
+# define __has_include(x) 0
+#endif
+
+#if __has_include(<version>)
+# include <version>
+#else
+# include <type_traits>
+# include <utility>
+#endif
+
+#ifdef _MSVC_LANG
+#define _MDSPAN_CPLUSPLUS _MSVC_LANG
+#else
+#define _MDSPAN_CPLUSPLUS __cplusplus
+#endif
+
+#define MDSPAN_CXX_STD_14 201402L
+#define MDSPAN_CXX_STD_17 201703L
+#define MDSPAN_CXX_STD_20 202002L
+// Note GCC has not updated this in version 13
+#ifdef __clang__
+#define MDSPAN_CXX_STD_23 202302L
+#else
+#define MDSPAN_CXX_STD_23 202100L
+#endif
+
+#define MDSPAN_HAS_CXX_14 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_14)
+#define MDSPAN_HAS_CXX_17 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_17)
+#define MDSPAN_HAS_CXX_20 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_20)
+#define MDSPAN_HAS_CXX_23 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_23)
+
+static_assert(_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_14, "mdspan requires C++14 or later.");
+
+#ifndef _MDSPAN_COMPILER_CLANG
+# if defined(__clang__)
+# define _MDSPAN_COMPILER_CLANG __clang__
+# endif
+#endif
+
+#if !defined(_MDSPAN_COMPILER_MSVC) && !defined(_MDSPAN_COMPILER_MSVC_CLANG)
+# if defined(_MSC_VER)
+# if !defined(_MDSPAN_COMPILER_CLANG)
+# define _MDSPAN_COMPILER_MSVC _MSC_VER
+# else
+# define _MDSPAN_COMPILER_MSVC_CLANG _MSC_VER
+# endif
+# endif
+#endif
+
+#ifndef _MDSPAN_COMPILER_INTEL
+# ifdef __INTEL_COMPILER
+# define _MDSPAN_COMPILER_INTEL __INTEL_COMPILER
+# endif
+#endif
+
+#ifndef _MDSPAN_COMPILER_APPLECLANG
+# ifdef __apple_build_version__
+# define _MDSPAN_COMPILER_APPLECLANG __apple_build_version__
+# endif
+#endif
+
+#ifndef _MDSPAN_HAS_CUDA
+# if defined(__CUDACC__)
+# define _MDSPAN_HAS_CUDA __CUDACC__
+# endif
+#endif
+
+#ifndef _MDSPAN_HAS_HIP
+# if defined(__HIPCC__)
+# define _MDSPAN_HAS_HIP __HIPCC__
+# endif
+#endif
+
+#ifndef _MDSPAN_HAS_SYCL
+# if defined(SYCL_LANGUAGE_VERSION)
+# define _MDSPAN_HAS_SYCL SYCL_LANGUAGE_VERSION
+# endif
+#endif
+
+#ifndef __has_cpp_attribute
+# define __has_cpp_attribute(x) 0
+#endif
+
+#ifndef _MDSPAN_PRESERVE_STANDARD_LAYOUT
+// Preserve standard layout by default, but we're not removing the old version
+// that turns this off until we're sure this doesn't have an unreasonable cost
+// to the compiler or optimizer.
+# define _MDSPAN_PRESERVE_STANDARD_LAYOUT 1
+#endif
+
+#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+# if ((__has_cpp_attribute(no_unique_address) >= 201803L) && \
+ (!defined(__NVCC__) || MDSPAN_HAS_CXX_20) && \
+ (!defined(_MDSPAN_COMPILER_MSVC) || MDSPAN_HAS_CXX_20))
+# define _MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1
+# define _MDSPAN_NO_UNIQUE_ADDRESS [[no_unique_address]]
+# else
+# define _MDSPAN_NO_UNIQUE_ADDRESS
+# endif
+#endif
+
+// NVCC older than 11.6 chokes on the no-unique-address-emulation
+// so just pretend to use it (to avoid the full blown EBO workaround
+// which NVCC also doesn't like ...), and leave the macro empty
+#ifndef _MDSPAN_NO_UNIQUE_ADDRESS
+# if defined(__NVCC__)
+# define _MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1
+# define _MDSPAN_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS
+# endif
+# define _MDSPAN_NO_UNIQUE_ADDRESS
+#endif
+
+// AMDs HIP compiler seems to have issues with concepts
+// it pretends concepts exist, but doesn't ship <concept>
+#ifndef __HIPCC__
+#ifndef _MDSPAN_USE_CONCEPTS
+# if defined(__cpp_concepts) && __cpp_concepts >= 201507L
+# define _MDSPAN_USE_CONCEPTS 1
+# endif
+#endif
+#endif
+
+#ifndef _MDSPAN_USE_FOLD_EXPRESSIONS
+# if (defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603L) \
+ || (!defined(__cpp_fold_expressions) && MDSPAN_HAS_CXX_17)
+# define _MDSPAN_USE_FOLD_EXPRESSIONS 1
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_INLINE_VARIABLES
+# if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L \
+ || (!defined(__cpp_inline_variables) && MDSPAN_HAS_CXX_17)
+# define _MDSPAN_USE_INLINE_VARIABLES 1
+# endif
+#endif
+
+#ifndef _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS
+# if (!(defined(__cpp_lib_type_trait_variable_templates) && __cpp_lib_type_trait_variable_templates >= 201510L) \
+ || !MDSPAN_HAS_CXX_17)
+# if !(defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_17)
+# define _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS 1
+# endif
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_VARIABLE_TEMPLATES
+# if (defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 && MDSPAN_HAS_CXX_17) \
+ || (!defined(__cpp_variable_templates) && MDSPAN_HAS_CXX_17)
+# define _MDSPAN_USE_VARIABLE_TEMPLATES 1
+# endif
+#endif // _MDSPAN_USE_VARIABLE_TEMPLATES
+
+#ifndef _MDSPAN_USE_CONSTEXPR_14
+# if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) \
+ || (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_14) \
+ && (!(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 1700))
+# define _MDSPAN_USE_CONSTEXPR_14 1
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_INTEGER_SEQUENCE
+# if defined(_MDSPAN_COMPILER_MSVC)
+# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304)
+# define _MDSPAN_USE_INTEGER_SEQUENCE 1
+# endif
+# endif
+#endif
+#ifndef _MDSPAN_USE_INTEGER_SEQUENCE
+# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304) \
+ || (!defined(__cpp_lib_integer_sequence) && MDSPAN_HAS_CXX_14) \
+ /* as far as I can tell, libc++ seems to think this is a C++11 feature... */ \
+ || (defined(__GLIBCXX__) && __GLIBCXX__ > 20150422 && __GNUC__ < 5 && !defined(__INTEL_CXX11_MODE__))
+ // several compilers lie about integer_sequence working properly unless the C++14 standard is used
+# define _MDSPAN_USE_INTEGER_SEQUENCE 1
+# elif defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14
+ // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14 making
+ // integer_sequence work
+# define _MDSPAN_USE_INTEGER_SEQUENCE 1
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_RETURN_TYPE_DEDUCTION
+# if (defined(__cpp_return_type_deduction) && __cpp_return_type_deduction >= 201304) \
+ || (!defined(__cpp_return_type_deduction) && MDSPAN_HAS_CXX_14)
+# define _MDSPAN_USE_RETURN_TYPE_DEDUCTION 1
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
+# if (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10 >= 1170)) && \
+ ((defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201703) || \
+ (!defined(__cpp_deduction_guides) && MDSPAN_HAS_CXX_17))
+# define _MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1
+# endif
+#endif
+
+#ifndef _MDSPAN_USE_STANDARD_TRAIT_ALIASES
+# if (defined(__cpp_lib_transformation_trait_aliases) && __cpp_lib_transformation_trait_aliases >= 201304) \
+ || (!defined(__cpp_lib_transformation_trait_aliases) && MDSPAN_HAS_CXX_14)
+# define _MDSPAN_USE_STANDARD_TRAIT_ALIASES 1
+# elif defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14
+ // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14
+# define _MDSPAN_USE_STANDARD_TRAIT_ALIASES 1
+# endif
+#endif
+
+#ifndef _MDSPAN_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND
+# ifdef __GNUC__
+# if __GNUC__ < 9
+# define _MDSPAN_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND 1
+# endif
+# endif
+#endif
+
+#ifndef MDSPAN_CONDITIONAL_EXPLICIT
+# if MDSPAN_HAS_CXX_20
+# define MDSPAN_CONDITIONAL_EXPLICIT(COND) explicit(COND)
+# else
+# define MDSPAN_CONDITIONAL_EXPLICIT(COND)
+# endif
+#endif
+
+#ifndef MDSPAN_USE_BRACKET_OPERATOR
+# if defined(__cpp_multidimensional_subscript)
+// The following if/else is necessary to workaround a clang issue
+// relative to using a parameter pack inside a bracket operator in C++2b/C++23 mode
+# if defined(_MDSPAN_COMPILER_CLANG) && \
+ ((__clang_major__ < 17) || \
+ (__clang_major__ == 17 && __clang_minor__ == 0 && \
+ __clang_patchlevel__ == 0))
+# define MDSPAN_USE_BRACKET_OPERATOR 0
+# else
+# define MDSPAN_USE_BRACKET_OPERATOR 1
+# endif
+# else
+# define MDSPAN_USE_BRACKET_OPERATOR 0
+# endif
+#endif
+
+#ifndef MDSPAN_USE_PAREN_OPERATOR
+# if !MDSPAN_USE_BRACKET_OPERATOR
+# define MDSPAN_USE_PAREN_OPERATOR 1
+# else
+# define MDSPAN_USE_PAREN_OPERATOR 0
+# endif
+#endif
+
+#if MDSPAN_USE_BRACKET_OPERATOR
+# define __MDSPAN_OP(mds,...) mds[__VA_ARGS__]
+// Corentins demo compiler for subscript chokes on empty [] call,
+// though I believe the proposal supports it?
+#ifdef MDSPAN_NO_EMPTY_BRACKET_OPERATOR
+# define __MDSPAN_OP0(mds) mds.accessor().access(mds.data_handle(),0)
+#else
+# define __MDSPAN_OP0(mds) mds[]
+#endif
+# define __MDSPAN_OP1(mds, a) mds[a]
+# define __MDSPAN_OP2(mds, a, b) mds[a,b]
+# define __MDSPAN_OP3(mds, a, b, c) mds[a,b,c]
+# define __MDSPAN_OP4(mds, a, b, c, d) mds[a,b,c,d]
+# define __MDSPAN_OP5(mds, a, b, c, d, e) mds[a,b,c,d,e]
+# define __MDSPAN_OP6(mds, a, b, c, d, e, f) mds[a,b,c,d,e,f]
+#else
+# define __MDSPAN_OP(mds,...) mds(__VA_ARGS__)
+# define __MDSPAN_OP0(mds) mds()
+# define __MDSPAN_OP1(mds, a) mds(a)
+# define __MDSPAN_OP2(mds, a, b) mds(a,b)
+# define __MDSPAN_OP3(mds, a, b, c) mds(a,b,c)
+# define __MDSPAN_OP4(mds, a, b, c, d) mds(a,b,c,d)
+# define __MDSPAN_OP5(mds, a, b, c, d, e) mds(a,b,c,d,e)
+# define __MDSPAN_OP6(mds, a, b, c, d, e, f) mds(a,b,c,d,e,f)
+#endif
diff --git a/ext/mdspan/include/experimental/__p0009_bits/default_accessor.hpp b/ext/mdspan/include/experimental/__p0009_bits/default_accessor.hpp
new file mode 100644
index 0000000..ea0f537
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/default_accessor.hpp
@@ -0,0 +1,56 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+
+#include <cstddef> // size_t
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+template <class ElementType>
+struct default_accessor {
+
+ using offset_policy = default_accessor;
+ using element_type = ElementType;
+ using reference = ElementType&;
+ using data_handle_type = ElementType*;
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr default_accessor() noexcept = default;
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherElementType,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, OtherElementType(*)[], element_type(*)[])
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr data_handle_type
+ offset(data_handle_type p, size_t i) const noexcept {
+ return p + i;
+ }
+
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference access(data_handle_type p, size_t i) const noexcept {
+ return p[i];
+ }
+
+};
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp b/ext/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp
new file mode 100644
index 0000000..2e29da1
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp
@@ -0,0 +1,35 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+
+#if defined(__cpp_lib_span)
+#include <span>
+#endif
+
+#include <cstddef> // size_t
+#include <limits> // numeric_limits
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+#if defined(__cpp_lib_span)
+using std::dynamic_extent;
+#else
+_MDSPAN_INLINE_VARIABLE constexpr auto dynamic_extent = std::numeric_limits<size_t>::max();
+#endif
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+//==============================================================================================================
diff --git a/ext/mdspan/include/experimental/__p0009_bits/extents.hpp b/ext/mdspan/include/experimental/__p0009_bits/extents.hpp
new file mode 100644
index 0000000..d58d377
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/extents.hpp
@@ -0,0 +1,693 @@
+//@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
+
+#pragma once
+#include "dynamic_extent.hpp"
+#include "utility.hpp"
+
+#ifdef __cpp_lib_span
+#include <span>
+#endif
+#include <array>
+#include <type_traits>
+
+#include <cassert>
+#include <cinttypes>
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+// Function used to check compatibility of extents in converting constructor
+// can't be a private member function for some reason.
+template <size_t... Extents, size_t... OtherExtents>
+MDSPAN_INLINE_FUNCTION
+static constexpr std::integral_constant<bool, false> __check_compatible_extents(
+ std::integral_constant<bool, false>,
+ std::integer_sequence<size_t, Extents...>,
+ std::integer_sequence<size_t, OtherExtents...>) noexcept {
+ return {};
+}
+
+// This helper prevents ICE's on MSVC.
+template <size_t Lhs, size_t Rhs>
+struct __compare_extent_compatible : std::integral_constant<bool,
+ Lhs == dynamic_extent ||
+ Rhs == dynamic_extent ||
+ Lhs == Rhs>
+{};
+
+template <size_t... Extents, size_t... OtherExtents>
+MDSPAN_INLINE_FUNCTION
+static constexpr std::integral_constant<
+ bool, _MDSPAN_FOLD_AND(__compare_extent_compatible<Extents, OtherExtents>::value)>
+__check_compatible_extents(
+ std::integral_constant<bool, true>,
+ std::integer_sequence<size_t, Extents...>,
+ std::integer_sequence<size_t, OtherExtents...>) noexcept {
+ return {};
+}
+
+template<class IndexType, class ... Arguments>
+MDSPAN_INLINE_FUNCTION
+static constexpr bool are_valid_indices() {
+ return
+ _MDSPAN_FOLD_AND(std::is_convertible<Arguments, IndexType>::value) &&
+ _MDSPAN_FOLD_AND(std::is_nothrow_constructible<IndexType, Arguments>::value);
+}
+
+// ------------------------------------------------------------------
+// ------------ static_array ----------------------------------------
+// ------------------------------------------------------------------
+
+// array like class which provides an array of static values with get
+// function and operator [].
+
+// Implementation of Static Array with recursive implementation of get.
+template <size_t R, class T, T... Extents> struct static_array_impl;
+
+template <size_t R, class T, T FirstExt, T... Extents>
+struct static_array_impl<R, T, FirstExt, Extents...> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr static T get(size_t r) {
+ if (r == R)
+ return FirstExt;
+ else
+ return static_array_impl<R + 1, T, Extents...>::get(r);
+ }
+ template <size_t r> MDSPAN_INLINE_FUNCTION constexpr static T get() {
+#if MDSPAN_HAS_CXX_17
+ if constexpr (r == R)
+ return FirstExt;
+ else
+ return static_array_impl<R + 1, T, Extents...>::template get<r>();
+#else
+ get(r);
+#endif
+ }
+};
+
+// End the recursion
+template <size_t R, class T, T FirstExt>
+struct static_array_impl<R, T, FirstExt> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr static T get(size_t) { return FirstExt; }
+ template <size_t> MDSPAN_INLINE_FUNCTION constexpr static T get() {
+ return FirstExt;
+ }
+};
+
+// Don't start recursion if size 0
+template <class T> struct static_array_impl<0, T> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr static T get(size_t) { return T(); }
+ template <size_t> MDSPAN_INLINE_FUNCTION constexpr static T get() {
+ return T();
+ }
+};
+
+// Static array, provides get<r>(), get(r) and operator[r]
+template <class T, T... Values> struct static_array:
+ public static_array_impl<0, T, Values...> {
+
+public:
+ using value_type = T;
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t size() { return sizeof...(Values); }
+};
+
+
+// ------------------------------------------------------------------
+// ------------ index_sequence_scan ---------------------------------
+// ------------------------------------------------------------------
+
+// index_sequence_scan takes compile time values and provides get(r)
+// and get<r>() which return the sum of the first r-1 values.
+
+// Recursive implementation for get
+template <size_t R, size_t... Values> struct index_sequence_scan_impl;
+
+template <size_t R, size_t FirstVal, size_t... Values>
+struct index_sequence_scan_impl<R, FirstVal, Values...> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t get(size_t r) {
+ if (r > R)
+ return FirstVal + index_sequence_scan_impl<R + 1, Values...>::get(r);
+ else
+ return 0;
+ }
+};
+
+template <size_t R, size_t FirstVal>
+struct index_sequence_scan_impl<R, FirstVal> {
+#if defined(__NVCC__) || defined(__NVCOMPILER) || \
+ defined(_MDSPAN_COMPILER_INTEL)
+ // NVCC warns about pointless comparison with 0 for R==0 and r being const
+ // evaluatable and also 0.
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t get(size_t r) {
+ return static_cast<int64_t>(R) > static_cast<int64_t>(r) ? FirstVal : 0;
+ }
+#else
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t get(size_t r) { return R > r ? FirstVal : 0; }
+#endif
+};
+template <> struct index_sequence_scan_impl<0> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t get(size_t) { return 0; }
+};
+
+// ------------------------------------------------------------------
+// ------------ possibly_empty_array -------------------------------
+// ------------------------------------------------------------------
+
+// array like class which provides get function and operator [], and
+// has a specialization for the size 0 case.
+// This is needed to make the maybe_static_array be truly empty, for
+// all static values.
+
+template <class T, size_t N> struct possibly_empty_array {
+ T vals[N]{};
+ MDSPAN_INLINE_FUNCTION
+ constexpr T &operator[](size_t r) { return vals[r]; }
+ MDSPAN_INLINE_FUNCTION
+ constexpr const T &operator[](size_t r) const { return vals[r]; }
+};
+
+template <class T> struct possibly_empty_array<T, 0> {
+ MDSPAN_INLINE_FUNCTION
+ constexpr T operator[](size_t) { return T(); }
+ MDSPAN_INLINE_FUNCTION
+ constexpr const T operator[](size_t) const { return T(); }
+};
+
+// ------------------------------------------------------------------
+// ------------ maybe_static_array ----------------------------------
+// ------------------------------------------------------------------
+
+// array like class which has a mix of static and runtime values but
+// only stores the runtime values.
+// The type of the static and the runtime values can be different.
+// The position of a dynamic value is indicated through a tag value.
+template <class TDynamic, class TStatic, TStatic dyn_tag, TStatic... Values>
+struct maybe_static_array {
+
+ static_assert(std::is_convertible<TStatic, TDynamic>::value, "maybe_static_array: TStatic must be convertible to TDynamic");
+ static_assert(std::is_convertible<TDynamic, TStatic>::value, "maybe_static_array: TDynamic must be convertible to TStatic");
+
+private:
+ // Static values member
+ using static_vals_t = static_array<TStatic, Values...>;
+ constexpr static size_t m_size = sizeof...(Values);
+ constexpr static size_t m_size_dynamic =
+ _MDSPAN_FOLD_PLUS_RIGHT((Values == dyn_tag), 0);
+
+ // Dynamic values member
+ _MDSPAN_NO_UNIQUE_ADDRESS possibly_empty_array<TDynamic, m_size_dynamic>
+ m_dyn_vals;
+
+ // static mapping of indices to the position in the dynamic values array
+ using dyn_map_t = index_sequence_scan_impl<0, static_cast<size_t>(Values == dyn_tag)...>;
+public:
+
+ // two types for static and dynamic values
+ using value_type = TDynamic;
+ using static_value_type = TStatic;
+ // tag value indicating dynamic value
+ constexpr static static_value_type tag_value = dyn_tag;
+
+ constexpr maybe_static_array() = default;
+
+ // constructor for all static values
+ // TODO: add precondition check?
+ MDSPAN_TEMPLATE_REQUIRES(class... Vals,
+ /* requires */ ((m_size_dynamic == 0) &&
+ (sizeof...(Vals) > 0)))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(Vals...) : m_dyn_vals{} {}
+
+ // constructors from dynamic values only
+ MDSPAN_TEMPLATE_REQUIRES(class... DynVals,
+ /* requires */ (sizeof...(DynVals) ==
+ m_size_dynamic &&
+ m_size_dynamic > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(DynVals... vals)
+ : m_dyn_vals{static_cast<TDynamic>(vals)...} {}
+
+
+ MDSPAN_TEMPLATE_REQUIRES(class T, size_t N,
+ /* requires */ (N == m_size_dynamic && N > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::array<T, N> &vals) {
+ for (size_t r = 0; r < N; r++)
+ m_dyn_vals[r] = static_cast<TDynamic>(vals[r]);
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(class T, size_t N,
+ /* requires */ (N == m_size_dynamic && N == 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::array<T, N> &) : m_dyn_vals{} {}
+
+#ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(class T, size_t N,
+ /* requires */ (N == m_size_dynamic && N > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::span<T, N> &vals) {
+ for (size_t r = 0; r < N; r++)
+ m_dyn_vals[r] = static_cast<TDynamic>(vals[r]);
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(class T, size_t N,
+ /* requires */ (N == m_size_dynamic && N == 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::span<T, N> &) : m_dyn_vals{} {}
+#endif
+
+ // constructors from all values
+ MDSPAN_TEMPLATE_REQUIRES(class... DynVals,
+ /* requires */ (sizeof...(DynVals) !=
+ m_size_dynamic &&
+ m_size_dynamic > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(DynVals... vals)
+ : m_dyn_vals{} {
+ static_assert((sizeof...(DynVals) == m_size), "Invalid number of values.");
+ TDynamic values[m_size]{static_cast<TDynamic>(vals)...};
+ for (size_t r = 0; r < m_size; r++) {
+ TStatic static_val = static_vals_t::get(r);
+ if (static_val == dyn_tag) {
+ m_dyn_vals[dyn_map_t::get(r)] = values[r];
+ }
+// Precondition check
+#ifdef _MDSPAN_DEBUG
+ else {
+ assert(values[r] == static_cast<TDynamic>(static_val));
+ }
+#endif
+ }
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class T, size_t N,
+ /* requires */ (N != m_size_dynamic && m_size_dynamic > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::array<T, N> &vals) {
+ static_assert((N == m_size), "Invalid number of values.");
+// Precondition check
+#ifdef _MDSPAN_DEBUG
+ assert(N == m_size);
+#endif
+ for (size_t r = 0; r < m_size; r++) {
+ TStatic static_val = static_vals_t::get(r);
+ if (static_val == dyn_tag) {
+ m_dyn_vals[dyn_map_t::get(r)] = static_cast<TDynamic>(vals[r]);
+ }
+// Precondition check
+#ifdef _MDSPAN_DEBUG
+ else {
+ assert(static_cast<TDynamic>(vals[r]) ==
+ static_cast<TDynamic>(static_val));
+ }
+#endif
+ }
+ }
+
+#ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class T, size_t N,
+ /* requires */ (N != m_size_dynamic && m_size_dynamic > 0))
+ MDSPAN_INLINE_FUNCTION
+ constexpr maybe_static_array(const std::span<T, N> &vals) {
+ static_assert((N == m_size) || (m_size == dynamic_extent));
+#ifdef _MDSPAN_DEBUG
+ assert(N == m_size);
+#endif
+ for (size_t r = 0; r < m_size; r++) {
+ TStatic static_val = static_vals_t::get(r);
+ if (static_val == dyn_tag) {
+ m_dyn_vals[dyn_map_t::get(r)] = static_cast<TDynamic>(vals[r]);
+ }
+#ifdef _MDSPAN_DEBUG
+ else {
+ assert(static_cast<TDynamic>(vals[r]) ==
+ static_cast<TDynamic>(static_val));
+ }
+#endif
+ }
+ }
+#endif
+
+ // access functions
+ MDSPAN_INLINE_FUNCTION
+ constexpr static TStatic static_value(size_t r) { return static_vals_t::get(r); }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr TDynamic value(size_t r) const {
+ TStatic static_val = static_vals_t::get(r);
+ return static_val == dyn_tag ? m_dyn_vals[dyn_map_t::get(r)]
+ : static_cast<TDynamic>(static_val);
+ }
+ MDSPAN_INLINE_FUNCTION
+ constexpr TDynamic operator[](size_t r) const { return value(r); }
+
+
+ // observers
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t size() { return m_size; }
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t size_dynamic() { return m_size_dynamic; }
+};
+
+} // namespace detail
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+// ------------------------------------------------------------------
+// ------------ extents ---------------------------------------------
+// ------------------------------------------------------------------
+
+// Class to describe the extents of a multi dimensional array.
+// Used by mdspan, mdarray and layout mappings.
+// See ISO C++ standard [mdspan.extents]
+
+template <class IndexType, size_t... Extents> class extents {
+public:
+ // typedefs for integral types used
+ using index_type = IndexType;
+ using size_type = std::make_unsigned_t<index_type>;
+ using rank_type = size_t;
+
+ static_assert(std::is_integral<index_type>::value && !std::is_same<index_type, bool>::value,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents::index_type must be a signed or unsigned integer type");
+private:
+ constexpr static rank_type m_rank = sizeof...(Extents);
+ constexpr static rank_type m_rank_dynamic =
+ _MDSPAN_FOLD_PLUS_RIGHT((Extents == dynamic_extent), /* + ... + */ 0);
+
+ // internal storage type using maybe_static_array
+ using vals_t =
+ detail::maybe_static_array<IndexType, size_t, dynamic_extent, Extents...>;
+ _MDSPAN_NO_UNIQUE_ADDRESS vals_t m_vals;
+
+public:
+ // [mdspan.extents.obs], observers of multidimensional index space
+ MDSPAN_INLINE_FUNCTION
+ constexpr static rank_type rank() noexcept { return m_rank; }
+ MDSPAN_INLINE_FUNCTION
+ constexpr static rank_type rank_dynamic() noexcept { return m_rank_dynamic; }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type extent(rank_type r) const noexcept { return m_vals.value(r); }
+ MDSPAN_INLINE_FUNCTION
+ constexpr static size_t static_extent(rank_type r) noexcept {
+ return vals_t::static_value(r);
+ }
+
+ // [mdspan.extents.cons], constructors
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr extents() noexcept = default;
+
+ // Construction from just dynamic or all values.
+ // Precondition check is deferred to maybe_static_array constructor
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... OtherIndexTypes,
+ /* requires */ (
+ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, OtherIndexTypes,
+ index_type) /* && ... */) &&
+ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_nothrow_constructible, index_type,
+ OtherIndexTypes) /* && ... */) &&
+ (sizeof...(OtherIndexTypes) == m_rank ||
+ sizeof...(OtherIndexTypes) == m_rank_dynamic)))
+ MDSPAN_INLINE_FUNCTION
+ constexpr explicit extents(OtherIndexTypes... dynvals) noexcept
+ : m_vals(static_cast<index_type>(dynvals)...) {}
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherIndexType, size_t N,
+ /* requires */
+ (
+ _MDSPAN_TRAIT(std::is_convertible, const OtherIndexType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type,
+ const OtherIndexType&) &&
+ (N == m_rank || N == m_rank_dynamic)))
+ MDSPAN_INLINE_FUNCTION
+ MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic)
+ constexpr extents(const std::array<OtherIndexType, N> &exts) noexcept
+ : m_vals(std::move(exts)) {}
+
+#ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherIndexType, size_t N,
+ /* requires */
+ (_MDSPAN_TRAIT(std::is_convertible, const OtherIndexType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const OtherIndexType&) &&
+ (N == m_rank || N == m_rank_dynamic)))
+ MDSPAN_INLINE_FUNCTION
+ MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic)
+ constexpr extents(const std::span<OtherIndexType, N> &exts) noexcept
+ : m_vals(std::move(exts)) {}
+#endif
+
+private:
+ // Function to construct extents storage from other extents.
+ // With C++ 17 the first two variants could be collapsed using if constexpr
+ // in which case you don't need all the requires clauses.
+ // in C++ 14 mode that doesn't work due to infinite recursion
+ MDSPAN_TEMPLATE_REQUIRES(
+ size_t DynCount, size_t R, class OtherExtents, class... DynamicValues,
+ /* requires */ ((R < m_rank) && (static_extent(R) == dynamic_extent)))
+ MDSPAN_INLINE_FUNCTION
+ constexpr
+ vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
+ std::integral_constant<size_t, R>,
+ const OtherExtents &exts,
+ DynamicValues... dynamic_values) noexcept {
+ return __construct_vals_from_extents(
+ std::integral_constant<size_t, DynCount + 1>(),
+ std::integral_constant<size_t, R + 1>(), exts, dynamic_values...,
+ exts.extent(R));
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ size_t DynCount, size_t R, class OtherExtents, class... DynamicValues,
+ /* requires */ ((R < m_rank) && (static_extent(R) != dynamic_extent)))
+ MDSPAN_INLINE_FUNCTION
+ constexpr
+ vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
+ std::integral_constant<size_t, R>,
+ const OtherExtents &exts,
+ DynamicValues... dynamic_values) noexcept {
+ return __construct_vals_from_extents(
+ std::integral_constant<size_t, DynCount>(),
+ std::integral_constant<size_t, R + 1>(), exts, dynamic_values...);
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ size_t DynCount, size_t R, class OtherExtents, class... DynamicValues,
+ /* requires */ ((R == m_rank) && (DynCount == m_rank_dynamic)))
+ MDSPAN_INLINE_FUNCTION
+ constexpr
+ vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>,
+ std::integral_constant<size_t, R>,
+ const OtherExtents &,
+ DynamicValues... dynamic_values) noexcept {
+ return vals_t{static_cast<index_type>(dynamic_values)...};
+ }
+
+public:
+
+ // Converting constructor from other extents specializations
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherIndexType, size_t... OtherExtents,
+ /* requires */
+ (
+ /* multi-stage check to protect from invalid pack expansion when sizes
+ don't match? */
+ decltype(detail::__check_compatible_extents(
+ // using: sizeof...(Extents) == sizeof...(OtherExtents) as the second argument fails with MSVC+NVCC with some obscure expansion error
+ // MSVC: 19.38.33133 NVCC: 12.0
+ std::integral_constant<bool, extents<int, Extents...>::rank() == extents<int, OtherExtents...>::rank()>{},
+ std::integer_sequence<size_t, Extents...>{},
+ std::integer_sequence<size_t, OtherExtents...>{}))::value
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ MDSPAN_CONDITIONAL_EXPLICIT((((Extents != dynamic_extent) &&
+ (OtherExtents == dynamic_extent)) ||
+ ...) ||
+ (std::numeric_limits<index_type>::max() <
+ std::numeric_limits<OtherIndexType>::max()))
+ constexpr extents(const extents<OtherIndexType, OtherExtents...> &other) noexcept
+ : m_vals(__construct_vals_from_extents(
+ std::integral_constant<size_t, 0>(),
+ std::integral_constant<size_t, 0>(), other)) {}
+
+ // Comparison operator
+ template <class OtherIndexType, size_t... OtherExtents>
+ MDSPAN_INLINE_FUNCTION friend constexpr bool
+ operator==(const extents &lhs,
+ const extents<OtherIndexType, OtherExtents...> &rhs) noexcept {
+ return
+ rank() == extents<OtherIndexType, OtherExtents...>::rank() &&
+ detail::rankwise_equal(detail::with_rank<rank()>{}, rhs, lhs, detail::extent);
+ }
+
+#if !(MDSPAN_HAS_CXX_20)
+ template <class OtherIndexType, size_t... OtherExtents>
+ MDSPAN_INLINE_FUNCTION friend constexpr bool
+ operator!=(extents const &lhs,
+ extents<OtherIndexType, OtherExtents...> const &rhs) noexcept {
+ return !(lhs == rhs);
+ }
+#endif
+};
+
+// Recursive helper classes to implement dextents alias for extents
+namespace detail {
+
+template <class IndexType, size_t Rank,
+ class Extents = ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType>>
+struct __make_dextents;
+
+template <class IndexType, size_t Rank, size_t... ExtentsPack>
+struct __make_dextents<
+ IndexType, Rank, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>>
+{
+ using type = typename __make_dextents<
+ IndexType, Rank - 1,
+ ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType,
+ ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent,
+ ExtentsPack...>>::type;
+};
+
+template <class IndexType, size_t... ExtentsPack>
+struct __make_dextents<
+ IndexType, 0, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>>
+{
+ using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>;
+};
+
+} // end namespace detail
+
+// [mdspan.extents.dextents], alias template
+template <class IndexType, size_t Rank>
+using dextents = typename detail::__make_dextents<IndexType, Rank>::type;
+
+// Deduction guide for extents
+#if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION)
+template <class... IndexTypes>
+extents(IndexTypes...)
+ -> extents<size_t,
+ ((void) sizeof(IndexTypes), ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent)...>;
+#endif
+
+// Helper type traits for identifying a class as extents.
+namespace detail {
+
+template <class T> struct __is_extents : ::std::false_type {};
+
+template <class IndexType, size_t... ExtentsPack>
+struct __is_extents<::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>>
+ : ::std::true_type {};
+
+template <class T>
+#if MDSPAN_HAS_CXX_17
+inline
+#else
+static
+#endif
+constexpr bool __is_extents_v = __is_extents<T>::value;
+
+template<class InputIndexType, class ExtentsIndexType>
+MDSPAN_INLINE_FUNCTION
+constexpr void
+check_lower_bound(InputIndexType user_index,
+ ExtentsIndexType /* current_extent */,
+ std::true_type /* is_signed */)
+{
+ (void) user_index; // prevent unused variable warning
+#ifdef _MDSPAN_DEBUG
+ assert(static_cast<ExtentsIndexType>(user_index) >= 0);
+#endif
+}
+
+template<class InputIndexType, class ExtentsIndexType>
+MDSPAN_INLINE_FUNCTION
+constexpr void
+check_lower_bound(InputIndexType /* user_index */,
+ ExtentsIndexType /* current_extent */,
+ std::false_type /* is_signed */)
+{}
+
+template<class InputIndexType, class ExtentsIndexType>
+MDSPAN_INLINE_FUNCTION
+constexpr void
+check_upper_bound(InputIndexType user_index,
+ ExtentsIndexType current_extent)
+{
+ (void) user_index; // prevent unused variable warnings
+ (void) current_extent;
+#ifdef _MDSPAN_DEBUG
+ assert(static_cast<ExtentsIndexType>(user_index) < current_extent);
+#endif
+}
+
+// Returning true to use AND fold instead of comma
+// CPP14 mode doesn't like the use of void expressions
+// with the way the _MDSPAN_FOLD_AND is set up
+template<class InputIndex, class ExtentsIndexType>
+MDSPAN_INLINE_FUNCTION
+constexpr bool
+check_one_index(InputIndex user_index,
+ ExtentsIndexType current_extent)
+{
+ check_lower_bound(user_index, current_extent,
+ std::integral_constant<bool, std::is_signed<ExtentsIndexType>::value>{});
+ check_upper_bound(user_index, current_extent);
+ return true;
+}
+
+template<size_t ... RankIndices,
+ class ExtentsIndexType, size_t ... Exts,
+ class ... Indices>
+MDSPAN_INLINE_FUNCTION
+constexpr void
+check_all_indices_helper(std::index_sequence<RankIndices...>,
+ const extents<ExtentsIndexType, Exts...>& exts,
+ Indices... indices)
+{
+ // Suppress warning about statement has no effect
+ (void) _MDSPAN_FOLD_AND(
+ (check_one_index(indices, exts.extent(RankIndices)))
+ );
+}
+
+template<class ExtentsIndexType, size_t ... Exts,
+ class ... Indices>
+MDSPAN_INLINE_FUNCTION
+constexpr void
+check_all_indices(const extents<ExtentsIndexType, Exts...>& exts,
+ Indices... indices)
+{
+ check_all_indices_helper(std::make_index_sequence<sizeof...(Indices)>(),
+ exts, indices...);
+}
+
+} // namespace detail
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp b/ext/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp
new file mode 100644
index 0000000..bd4b5c6
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp
@@ -0,0 +1,26 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+struct full_extent_t { explicit full_extent_t() = default; };
+
+_MDSPAN_INLINE_VARIABLE constexpr auto full_extent = full_extent_t{ };
+
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/layout_left.hpp b/ext/mdspan/include/experimental/__p0009_bits/layout_left.hpp
new file mode 100644
index 0000000..ed8aae0
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/layout_left.hpp
@@ -0,0 +1,269 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+#include "trait_backports.hpp"
+#include "extents.hpp"
+#include "layout_stride.hpp"
+#include "utility.hpp"
+#if MDSPAN_HAS_CXX_17
+#include "../__p2642_bits/layout_padded_fwd.hpp"
+#endif
+#include <type_traits>
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+//==============================================================================
+
+template <class Extents>
+class layout_left::mapping {
+ public:
+ using extents_type = Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_left;
+ private:
+
+ static_assert(detail::__is_extents_v<extents_type>,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_left::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents.");
+
+ template <class>
+ friend class mapping;
+
+ // i0+(i1 + E(1)*(i2 + E(2)*i3))
+ template <size_t r, size_t Rank>
+ struct __rank_count {};
+
+ template <size_t r, size_t Rank, class I, class... Indices>
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(
+ __rank_count<r,Rank>, const I& i, Indices... idx) const {
+ return __compute_offset(__rank_count<r+1,Rank>(), idx...) *
+ __extents.extent(r) + i;
+ }
+
+ template<class I>
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(
+ __rank_count<extents_type::rank()-1,extents_type::rank()>, const I& i) const {
+ return i;
+ }
+
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(__rank_count<0,0>) const { return 0; }
+
+ public:
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default;
+
+ _MDSPAN_HOST_DEVICE
+ constexpr mapping(extents_type const& __exts) noexcept
+ :__extents(__exts)
+ { }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) &&
+ (extents_type::rank() <= 1)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(layout_right::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ }
+
+#if MDSPAN_HAS_CXX_17
+ /**
+ * Converting constructor from `layout_left_padded::mapping`.
+ *
+ * This overload participates in overload resolution only if _Mapping is a layout_left_padded mapping and
+ * extents_type is constructible from _Mapping::extents_type.
+ *
+ * \note There is currently a difference from p2642r2, where this function is specified as taking
+ * `layout_left_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible.
+ */
+ MDSPAN_TEMPLATE_REQUIRES(
+ class _Mapping,
+ /* requires */ (
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_left_padded_mapping<_Mapping>::value
+ && std::is_constructible_v<extents_type, typename _Mapping::extents_type>
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v<typename _Mapping::extents_type, extents_type>))
+ mapping(const _Mapping& __other) noexcept
+ : __extents(__other.extents())
+ {
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::
+ check_padded_layout_converting_constructor_mandates<
+ extents_type, _Mapping>(detail::with_rank<extents_type::rank()>{});
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::
+ check_padded_layout_converting_constructor_preconditions<
+ extents_type>(detail::with_rank<extents_type::rank()>{}, __other);
+ }
+#endif
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0))
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(layout_stride::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ detail::validate_strides(detail::with_rank<extents_type::rank()>{}, layout_left{}, __extents, other);
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default;
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr const extents_type& extents() const noexcept {
+ return __extents;
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type required_span_size() const noexcept {
+ index_type value = 1;
+ for(rank_type r=0; r<extents_type::rank(); r++) value*=__extents.extent(r);
+ return value;
+ }
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... Indices,
+ /* requires */ (
+ (sizeof...(Indices) == extents_type::rank()) &&
+ (detail::are_valid_indices<index_type, Indices...>())
+ )
+ )
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type operator()(Indices... idxs) const noexcept {
+#if ! defined(NDEBUG)
+ detail::check_all_indices(this->extents(), idxs...);
+#endif // ! NDEBUG
+ return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(idxs)...);
+ }
+
+
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; }
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type stride(rank_type i) const noexcept
+#if MDSPAN_HAS_CXX_20
+ requires ( Extents::rank() > 0 )
+#endif
+ {
+ index_type value = 1;
+ for(rank_type r=0; r<i; r++) value*=__extents.extent(r);
+ return value;
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ ( Extents::rank() == OtherExtents::rank())
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return lhs.extents() == rhs.extents();
+ }
+
+ // In C++ 20 the not equal exists if equal is found
+#if !(MDSPAN_HAS_CXX_20)
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ ( Extents::rank() == OtherExtents::rank())
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return lhs.extents() != rhs.extents();
+ }
+#endif
+
+ // Not really public, but currently needed to implement fully constexpr useable submdspan:
+ template<size_t N, class SizeType, size_t ... E, size_t ... Idx>
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type __get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, E...>,std::integer_sequence<size_t, Idx...>) const {
+ return _MDSPAN_FOLD_TIMES_RIGHT((Idx<N? __extents.template __extent<Idx>():1),1);
+ }
+ template<size_t N>
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type __stride() const noexcept {
+ return __get_stride<N>(__extents, std::make_index_sequence<extents_type::rank()>());
+ }
+
+private:
+ _MDSPAN_NO_UNIQUE_ADDRESS extents_type __extents{};
+
+ // [mdspan.submdspan.mapping], submdspan mapping specialization
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ constexpr auto submdspan_mapping_impl(
+ SliceSpecifiers... slices) const;
+
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr auto submdspan_mapping(
+ const mapping& src, SliceSpecifiers... slices) {
+ return src.submdspan_mapping_impl(slices...);
+ }
+};
+
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
diff --git a/ext/mdspan/include/experimental/__p0009_bits/layout_right.hpp b/ext/mdspan/include/experimental/__p0009_bits/layout_right.hpp
new file mode 100644
index 0000000..26115e7
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/layout_right.hpp
@@ -0,0 +1,265 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+#include "trait_backports.hpp"
+#include "extents.hpp"
+#include "layout_stride.hpp"
+#include "utility.hpp"
+#if MDSPAN_HAS_CXX_17
+#include "../__p2642_bits/layout_padded_fwd.hpp"
+#endif
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+//==============================================================================
+template <class Extents>
+class layout_right::mapping {
+ public:
+ using extents_type = Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_right;
+ private:
+
+ static_assert(detail::__is_extents_v<extents_type>,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_right::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents.");
+
+ template <class>
+ friend class mapping;
+
+ // i0+(i1 + E(1)*(i2 + E(2)*i3))
+ template <size_t r, size_t Rank>
+ struct __rank_count {};
+
+ template <size_t r, size_t Rank, class I, class... Indices>
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(
+ index_type offset, __rank_count<r,Rank>, const I& i, Indices... idx) const {
+ return __compute_offset(offset * __extents.extent(r) + i,__rank_count<r+1,Rank>(), idx...);
+ }
+
+ template<class I, class ... Indices>
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(
+ __rank_count<0,extents_type::rank()>, const I& i, Indices... idx) const {
+ return __compute_offset(i,__rank_count<1,extents_type::rank()>(),idx...);
+ }
+
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(size_t offset, __rank_count<extents_type::rank(), extents_type::rank()>) const {
+ return static_cast<index_type>(offset);
+ }
+
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __compute_offset(__rank_count<0,0>) const { return 0; }
+
+ public:
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default;
+
+ _MDSPAN_HOST_DEVICE
+ constexpr mapping(extents_type const& __exts) noexcept
+ :__extents(__exts)
+ { }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) &&
+ (extents_type::rank() <= 1)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(layout_left::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ }
+
+ /**
+ * Converting constructor from `layout_right_padded::mapping`.
+ *
+ * This overload participates in overload resolution only if _Mapping is a layout_right_padded mapping and
+ * extents_type is constructible from _Mapping::extents_type.
+ *
+ * \note There is currently a difference from p2642r2, where this function is specified as taking
+ * `layout_right_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible.
+ */
+#if MDSPAN_HAS_CXX_17
+ MDSPAN_TEMPLATE_REQUIRES(
+ class _Mapping,
+ /* requires */ (
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_right_padded_mapping<_Mapping>::value
+ && std::is_constructible_v<extents_type, typename _Mapping::extents_type>))
+ MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v<typename _Mapping::extents_type, extents_type>))
+ mapping(const _Mapping &__other) noexcept
+ : __extents(__other.extents())
+ {
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::
+ check_padded_layout_converting_constructor_mandates<
+ extents_type, _Mapping>(detail::with_rank<extents_type::rank()>{});
+ MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::
+ check_padded_layout_converting_constructor_preconditions<
+ extents_type>(detail::with_rank<extents_type::rank()>{}, __other);
+ }
+#endif
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0))
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(layout_stride::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor)
+ :__extents(other.extents())
+ {
+ /*
+ * TODO: check precondition
+ * other.required_span_size() is a representable value of type index_type
+ */
+ detail::validate_strides(detail::with_rank<extents_type::rank()>{}, layout_right{}, __extents, other);
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default;
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr const extents_type& extents() const noexcept {
+ return __extents;
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type required_span_size() const noexcept {
+ index_type value = 1;
+ for(rank_type r=0; r != extents_type::rank(); ++r) value*=__extents.extent(r);
+ return value;
+ }
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class ... Indices,
+ /* requires */ (
+ (sizeof...(Indices) == extents_type::rank()) &&
+ (detail::are_valid_indices<index_type, Indices...>())
+ )
+ )
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type operator()(Indices... idxs) const noexcept {
+#if ! defined(NDEBUG)
+ detail::check_all_indices(this->extents(), idxs...);
+#endif // ! NDEBUG
+ return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(idxs)...);
+ }
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type stride(rank_type i) const noexcept
+#if MDSPAN_HAS_CXX_20
+ requires ( Extents::rank() > 0 )
+#endif
+ {
+ index_type value = 1;
+ for(rank_type r=extents_type::rank()-1; r>i; r--) value*=__extents.extent(r);
+ return value;
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ ( Extents::rank() == OtherExtents::rank())
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return lhs.extents() == rhs.extents();
+ }
+
+ // In C++ 20 the not equal exists if equal is found
+#if !(MDSPAN_HAS_CXX_20)
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (Extents::rank() == OtherExtents::rank())
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return lhs.extents() != rhs.extents();
+ }
+#endif
+
+ // Not really public, but currently needed to implement fully constexpr useable submdspan:
+ template<size_t N, class SizeType, size_t ... E, size_t ... Idx>
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type __get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, E...>,std::integer_sequence<size_t, Idx...>) const {
+ return _MDSPAN_FOLD_TIMES_RIGHT((Idx>N? __extents.template __extent<Idx>():1),1);
+ }
+ template<size_t N>
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type __stride() const noexcept {
+ return __get_stride<N>(__extents, std::make_index_sequence<extents_type::rank()>());
+ }
+
+private:
+ _MDSPAN_NO_UNIQUE_ADDRESS extents_type __extents{};
+
+ // [mdspan.submdspan.mapping], submdspan mapping specialization
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ constexpr auto submdspan_mapping_impl(
+ SliceSpecifiers... slices) const;
+
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr auto submdspan_mapping(
+ const mapping& src, SliceSpecifiers... slices) {
+ return src.submdspan_mapping_impl(slices...);
+ }
+};
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
diff --git a/ext/mdspan/include/experimental/__p0009_bits/layout_stride.hpp b/ext/mdspan/include/experimental/__p0009_bits/layout_stride.hpp
new file mode 100644
index 0000000..47ef268
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/layout_stride.hpp
@@ -0,0 +1,667 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+#include "extents.hpp"
+#include "trait_backports.hpp"
+#include "compressed_pair.hpp"
+#include "utility.hpp"
+
+#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+# include "no_unique_address.hpp"
+#endif
+
+#include <array>
+#include <type_traits>
+#include <utility>
+
+#ifdef __cpp_lib_span
+#include <span>
+#endif
+#if defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 && defined(__cpp_lib_concepts)
+# include <concepts>
+#endif
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+struct layout_left {
+ template<class Extents>
+ class mapping;
+};
+struct layout_right {
+ template<class Extents>
+ class mapping;
+};
+
+namespace detail {
+ template<class Layout, class Mapping>
+ constexpr bool __is_mapping_of =
+ std::is_same<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>::value;
+
+#if defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20
+# if !defined(__cpp_lib_concepts)
+ namespace internal {
+ namespace detail {
+ template <typename _Tp, typename _Up>
+ concept __same_as = std::is_same_v<_Tp, _Up>;
+ } // namespace detail
+ template <class T, class U>
+ concept __same_as = detail::__same_as<T, U> && detail::__same_as<U, T>;
+ } // namespace internal
+# endif
+
+ template<class M>
+ concept __layout_mapping_alike = requires {
+ requires __is_extents<typename M::extents_type>::value;
+#if defined(__cpp_lib_concepts)
+ { M::is_always_strided() } -> std::same_as<bool>;
+ { M::is_always_exhaustive() } -> std::same_as<bool>;
+ { M::is_always_unique() } -> std::same_as<bool>;
+#else
+ { M::is_always_strided() } -> internal::__same_as<bool>;
+ { M::is_always_exhaustive() } -> internal::__same_as<bool>;
+ { M::is_always_unique() } -> internal::__same_as<bool>;
+#endif
+ std::bool_constant<M::is_always_strided()>::value;
+ std::bool_constant<M::is_always_exhaustive()>::value;
+ std::bool_constant<M::is_always_unique()>::value;
+ };
+#endif
+
+} // namespace detail
+
+struct layout_stride {
+ template <class Extents>
+ class mapping
+#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : private detail::__no_unique_address_emulation<
+ detail::__compressed_pair<
+ Extents,
+ detail::possibly_empty_array<typename Extents::index_type, Extents::rank()>
+ >
+ >
+#endif
+ {
+ public:
+ using extents_type = Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_stride;
+
+ // This could be a `requires`, but I think it's better and clearer as a `static_assert`.
+ static_assert(detail::__is_extents_v<Extents>,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_stride::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents.");
+
+
+ private:
+
+ //----------------------------------------------------------------------------
+
+ using __strides_storage_t = detail::possibly_empty_array<index_type, extents_type::rank()>;
+ using __member_pair_t = detail::__compressed_pair<extents_type, __strides_storage_t>;
+
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ _MDSPAN_NO_UNIQUE_ADDRESS __member_pair_t __members;
+#else
+ using __base_t = detail::__no_unique_address_emulation<__member_pair_t>;
+#endif
+
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr __strides_storage_t const&
+ __strides_storage() const noexcept {
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ return __members.__second();
+#else
+ return this->__base_t::__ref().__second();
+#endif
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 __strides_storage_t&
+ __strides_storage() noexcept {
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ return __members.__second();
+#else
+ return this->__base_t::__ref().__second();
+#endif
+ }
+
+ template<class SizeType, size_t ... Ep, size_t ... Idx>
+ _MDSPAN_HOST_DEVICE
+ constexpr index_type __get_size(::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, Ep...>,std::integer_sequence<size_t, Idx...>) const {
+ return _MDSPAN_FOLD_TIMES_RIGHT( static_cast<index_type>(extents().extent(Idx)), 1 );
+ }
+
+ //----------------------------------------------------------------------------
+
+ template <class>
+ friend class mapping;
+
+ //----------------------------------------------------------------------------
+
+ // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level
+ template <class>
+ struct __deduction_workaround;
+
+ template <size_t... Idxs>
+ struct __deduction_workaround<std::index_sequence<Idxs...>>
+ {
+ template <class OtherExtents>
+ MDSPAN_INLINE_FUNCTION
+ static constexpr bool _eq_impl(mapping const& self, mapping<OtherExtents> const& other) noexcept {
+ using common_t = std::common_type_t<index_type, typename OtherExtents::index_type>;
+ return _MDSPAN_FOLD_AND((static_cast<common_t>(self.stride(Idxs)) == static_cast<common_t>(other.stride(Idxs))) /* && ... */)
+ && _MDSPAN_FOLD_AND((static_cast<common_t>(self.extents().extent(Idxs)) == static_cast<common_t>(other.extents().extent(Idxs))) /* || ... */);
+ }
+ template <class OtherExtents>
+ MDSPAN_INLINE_FUNCTION
+ static constexpr bool _not_eq_impl(mapping const& self, mapping<OtherExtents> const& other) noexcept {
+ using common_t = std::common_type_t<index_type, typename OtherExtents::index_type>;
+ return _MDSPAN_FOLD_OR((static_cast<common_t>(self.stride(Idxs)) != static_cast<common_t>(other.stride(Idxs))) /* || ... */)
+ || _MDSPAN_FOLD_OR((static_cast<common_t>(self.extents().extent(Idxs)) != static_cast<common_t>(other.extents().extent(Idxs))) /* || ... */);
+ }
+
+ template <class... Integral>
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr size_t _call_op_impl(mapping const& self, Integral... idxs) noexcept {
+ return _MDSPAN_FOLD_PLUS_RIGHT((idxs * self.stride(Idxs)), /* + ... + */ 0);
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ static constexpr size_t _req_span_size_impl(mapping const& self) noexcept {
+ // assumes no negative strides; not sure if I'm allowed to assume that or not
+ return __impl::_call_op_impl(self, (self.extents().template __extent<Idxs>() - 1)...) + 1;
+ }
+
+ template<class OtherMapping>
+ MDSPAN_INLINE_FUNCTION
+ static constexpr const __strides_storage_t fill_strides(const OtherMapping& map) {
+ return __strides_storage_t{static_cast<index_type>(map.stride(Idxs))...};
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ static constexpr const __strides_storage_t& fill_strides(const __strides_storage_t& s) {
+ return s;
+ }
+
+ template<class IntegralType>
+ static constexpr const __strides_storage_t fill_strides(const std::array<IntegralType,extents_type::rank()>& s) {
+ return __strides_storage_t{static_cast<index_type>(s[Idxs])...};
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class IntegralType,
+ (std::is_convertible<IntegralType, typename extents_type::index_type>::value)
+ )
+ MDSPAN_INLINE_FUNCTION
+ // Need to avoid zero length c-array
+ static constexpr const __strides_storage_t fill_strides(mdspan_non_standard_tag, const IntegralType (&s)[extents_type::rank()>0?extents_type::rank():1]) {
+ return __strides_storage_t{static_cast<index_type>(s[Idxs])...};
+ }
+
+#ifdef __cpp_lib_span
+ template<class IntegralType>
+ static constexpr const __strides_storage_t fill_strides(const std::span<IntegralType,extents_type::rank()>& s) {
+ return __strides_storage_t{static_cast<index_type>(s[Idxs])...};
+ }
+#endif
+
+ MDSPAN_INLINE_FUNCTION
+ static constexpr std::array<index_type, extents_type::rank()> return_strides(const __strides_storage_t& s) {
+ return std::array<index_type, extents_type::rank()>{s[Idxs]...};
+ }
+
+ template<size_t K>
+ MDSPAN_INLINE_FUNCTION
+ static constexpr size_t __return_zero() { return 0; }
+
+ template<class Mapping>
+ MDSPAN_INLINE_FUNCTION
+ static constexpr typename Mapping::index_type
+ __OFFSET(const Mapping& m) { return m(__return_zero<Idxs>()...); }
+ };
+
+ // Can't use defaulted parameter in the __deduction_workaround template because of a bug in MSVC warning C4348.
+ using __impl = __deduction_workaround<std::make_index_sequence<Extents::rank()>>;
+
+ MDSPAN_FUNCTION
+ static constexpr __strides_storage_t strides_storage(detail::with_rank<0>) {
+ return {};
+ }
+
+ template <std::size_t N>
+ MDSPAN_FUNCTION
+ static constexpr __strides_storage_t strides_storage(detail::with_rank<N>) {
+ __strides_storage_t s{};
+
+ extents_type e;
+ index_type stride = 1;
+ for(int r = static_cast<int>(extents_type::rank() - 1); r >= 0; r--) {
+ s[r] = stride;
+ stride *= e.extent(r);
+ }
+
+ return s;
+ }
+
+ //----------------------------------------------------------------------------
+
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ MDSPAN_INLINE_FUNCTION constexpr explicit
+ mapping(__member_pair_t&& __m) : __members(::std::move(__m)) {}
+#else
+ MDSPAN_INLINE_FUNCTION constexpr explicit
+ mapping(__base_t&& __b) : __base_t(::std::move(__b)) {}
+#endif
+
+ public:
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_INLINE_FUNCTION constexpr mapping() noexcept
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : __members{
+#else
+ : __base_t(__base_t{__member_pair_t(
+#endif
+ extents_type(),
+ __strides_storage_t(strides_storage(detail::with_rank<extents_type::rank()>{}))
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ }
+#else
+ )})
+#endif
+ {}
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default;
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class IntegralTypes,
+ /* requires */ (
+ // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type
+ // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping'
+ _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&)
+ )
+ )
+ constexpr
+ mapping(
+ extents_type const& e,
+ std::array<IntegralTypes, extents_type::rank()> const& s
+ ) noexcept
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : __members{
+#else
+ : __base_t(__base_t{__member_pair_t(
+#endif
+ e, __strides_storage_t(__impl::fill_strides(s))
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ }
+#else
+ )})
+#endif
+ {
+ /*
+ * TODO: check preconditions
+ * - s[i] > 0 is true for all i in the range [0, rank_ ).
+ * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]).
+ * - If rank_ is greater than 0, then there exists a permutation P of the integers in the
+ * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for
+ * all i in the range [1, rank_ ), where pi is the ith element of P.
+ */
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class IntegralTypes,
+ /* requires */ (
+ // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type
+ // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping'
+ _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&)
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ constexpr
+ mapping(
+ mdspan_non_standard_tag,
+ extents_type const& e,
+ // Need to avoid zero-length c-array
+ const IntegralTypes (&s)[extents_type::rank()>0?extents_type::rank():1]
+ ) noexcept
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : __members{
+#else
+ : __base_t(__base_t{__member_pair_t(
+#endif
+ e, __strides_storage_t(__impl::fill_strides(mdspan_non_standard, s))
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ }
+#else
+ )})
+#endif
+ {
+ /*
+ * TODO: check preconditions
+ * - s[i] > 0 is true for all i in the range [0, rank_ ).
+ * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]).
+ * - If rank_ is greater than 0, then there exists a permutation P of the integers in the
+ * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for
+ * all i in the range [1, rank_ ), where pi is the ith element of P.
+ */
+ }
+
+#ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class IntegralTypes,
+ /* requires */ (
+ // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type
+ // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping'
+ _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&)
+ )
+ )
+ constexpr
+ mapping(
+ extents_type const& e,
+ std::span<IntegralTypes, extents_type::rank()> const& s
+ ) noexcept
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : __members{
+#else
+ : __base_t(__base_t{__member_pair_t(
+#endif
+ e, __strides_storage_t(__impl::fill_strides(s))
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ }
+#else
+ )})
+#endif
+ {
+ /*
+ * TODO: check preconditions
+ * - s[i] > 0 is true for all i in the range [0, rank_ ).
+ * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]).
+ * - If rank_ is greater than 0, then there exists a permutation P of the integers in the
+ * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for
+ * all i in the range [1, rank_ ), where pi is the ith element of P.
+ */
+ }
+#endif // __cpp_lib_span
+
+#if !(defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20)
+ MDSPAN_TEMPLATE_REQUIRES(
+ class StridedLayoutMapping,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) &&
+ detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> &&
+ StridedLayoutMapping::is_always_unique() &&
+ StridedLayoutMapping::is_always_strided()
+ )
+ )
+#else
+ template<class StridedLayoutMapping>
+ requires(
+ detail::__layout_mapping_alike<StridedLayoutMapping> &&
+ _MDSPAN_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) &&
+ StridedLayoutMapping::is_always_unique() &&
+ StridedLayoutMapping::is_always_strided()
+ )
+#endif
+ MDSPAN_CONDITIONAL_EXPLICIT(
+ !(std::is_convertible<typename StridedLayoutMapping::extents_type, extents_type>::value &&
+ (detail::__is_mapping_of<layout_left, StridedLayoutMapping> ||
+ detail::__is_mapping_of<layout_right, StridedLayoutMapping> ||
+ detail::__is_mapping_of<layout_stride, StridedLayoutMapping>))
+ ) // needs two () due to comma
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14
+ mapping(StridedLayoutMapping const& other) noexcept // NOLINT(google-explicit-constructor)
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ : __members{
+#else
+ : __base_t(__base_t{__member_pair_t(
+#endif
+ other.extents(), __strides_storage_t(__impl::fill_strides(other))
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ }
+#else
+ )})
+#endif
+ {
+ /*
+ * TODO: check preconditions
+ * - other.stride(i) > 0 is true for all i in the range [0, rank_ ).
+ * - other.required_span_size() is a representable value of type index_type ([basic.fundamental]).
+ * - OFFSET(other) == 0
+ */
+ }
+
+ //--------------------------------------------------------------------------------
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED
+ mapping& operator=(mapping const&) noexcept = default;
+
+ MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept {
+#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS)
+ return __members.__first();
+#else
+ return this->__base_t::__ref().__first();
+#endif
+ };
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr std::array< index_type, extents_type::rank() > strides() const noexcept {
+ return __impl::return_strides(__strides_storage());
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type required_span_size() const noexcept {
+ index_type span_size = 1;
+ // using int here to avoid warning about pointless comparison to 0
+ for(int r = 0; r < static_cast<int>(extents_type::rank()); r++) {
+ // Return early if any of the extents are zero
+ if(extents().extent(r)==0) return 0;
+ span_size += ( static_cast<index_type>(extents().extent(r) - 1 ) * __strides_storage()[r]);
+ }
+ return span_size;
+ }
+
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... Indices,
+ /* requires */ (
+ sizeof...(Indices) == Extents::rank() &&
+ (detail::are_valid_indices<index_type, Indices...>())
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr index_type operator()(Indices... idxs) const noexcept {
+#if ! defined(NDEBUG)
+ detail::check_all_indices(this->extents(), idxs...);
+#endif // ! NDEBUG
+ return static_cast<index_type>(__impl::_call_op_impl(*this, static_cast<index_type>(idxs)...));
+ }
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept {
+ return false;
+ }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; }
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; }
+
+ private:
+ MDSPAN_INLINE_FUNCTION
+ constexpr bool exhaustive_for_nonzero_span_size() const
+ {
+ return required_span_size() == __get_size(extents(), std::make_index_sequence<extents_type::rank()>());
+ }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr bool is_exhaustive_impl(detail::with_rank<0>) const
+ {
+ return true;
+ }
+ MDSPAN_INLINE_FUNCTION
+ constexpr bool is_exhaustive_impl(detail::with_rank<1>) const
+ {
+ if (required_span_size() != static_cast<index_type>(0)) {
+ return exhaustive_for_nonzero_span_size();
+ }
+ return stride(0) == 1;
+ }
+ template <std::size_t N>
+ MDSPAN_INLINE_FUNCTION
+ constexpr bool is_exhaustive_impl(detail::with_rank<N>) const
+ {
+ if (required_span_size() != static_cast<index_type>(0)) {
+ return exhaustive_for_nonzero_span_size();
+ }
+
+ rank_type r_largest = 0;
+ for (rank_type r = 1; r < extents_type::rank(); r++) {
+ if (stride(r) > stride(r_largest)) {
+ r_largest = r;
+ }
+ }
+ for (rank_type r = 0; r < extents_type::rank(); r++) {
+ if (extents().extent(r) == 0 && r != r_largest) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public:
+ MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 bool is_exhaustive() const noexcept {
+ return is_exhaustive_impl(detail::with_rank<extents_type::rank()>{});
+ }
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; }
+
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr index_type stride(rank_type r) const noexcept {
+ return __strides_storage()[r];
+ }
+
+#if !(defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20)
+ MDSPAN_TEMPLATE_REQUIRES(
+ class StridedLayoutMapping,
+ /* requires */ (
+ detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> &&
+ (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) &&
+ StridedLayoutMapping::is_always_strided()
+ )
+ )
+#else
+ template<class StridedLayoutMapping>
+ requires(
+ detail::__layout_mapping_alike<StridedLayoutMapping> &&
+ (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) &&
+ StridedLayoutMapping::is_always_strided()
+ )
+#endif
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator==(const mapping& x, const StridedLayoutMapping& y) noexcept {
+ return (x.extents() == y.extents()) &&
+ (__impl::__OFFSET(y) == static_cast<typename StridedLayoutMapping::index_type>(0)) &&
+ detail::rankwise_equal(detail::with_rank<extents_type::rank()>{}, x, y, detail::stride);
+ }
+
+ // This one is not technically part of the proposal. Just here to make implementation a bit more optimal hopefully
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ (extents_type::rank() == OtherExtents::rank())
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return __impl::_eq_impl(lhs, rhs);
+ }
+
+#if !MDSPAN_HAS_CXX_20
+ MDSPAN_TEMPLATE_REQUIRES(
+ class StridedLayoutMapping,
+ /* requires */ (
+ detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> &&
+ (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) &&
+ StridedLayoutMapping::is_always_strided()
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator!=(const mapping& x, const StridedLayoutMapping& y) noexcept {
+ return !(x == y);
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherExtents,
+ /* requires */ (
+ (extents_type::rank() == OtherExtents::rank())
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept {
+ return __impl::_not_eq_impl(lhs, rhs);
+ }
+#endif
+
+ // [mdspan.submdspan.mapping], submdspan mapping specialization
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ constexpr auto submdspan_mapping_impl(
+ SliceSpecifiers... slices) const;
+
+ template<class... SliceSpecifiers>
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr auto submdspan_mapping(
+ const mapping& src, SliceSpecifiers... slices) {
+ return src.submdspan_mapping_impl(slices...);
+ }
+ };
+};
+
+namespace detail {
+
+template <class Layout, class Extents, class Mapping>
+MDSPAN_INLINE_FUNCTION
+constexpr void validate_strides(with_rank<0>, Layout, const Extents&, const Mapping&)
+{}
+
+template <std::size_t N, class Layout, class Extents, class Mapping>
+MDSPAN_INLINE_FUNCTION
+constexpr void validate_strides(with_rank<N>, Layout, const Extents& ext, const Mapping& other)
+{
+ static_assert(std::is_same<typename Mapping::layout_type, layout_stride>::value &&
+ (std::is_same<Layout, layout_left>::value ||
+ std::is_same<Layout, layout_right>::value)
+ , "This function is only intended to validate construction of "
+ "a layout_left or layout_right mapping from a layout_stride mapping.");
+
+ constexpr auto is_left = std::is_same<Layout, layout_left>::value;
+
+ typename Extents::index_type expected_stride = 1;
+
+ for (std::size_t r = 0; r < N; r++) {
+ const std::size_t s = is_left ? r : N - 1 - r;
+
+ MDSPAN_IMPL_PRECONDITION(common_integral_compare(expected_stride, other.stride(s))
+ && "invalid strides for layout_{left,right}");
+
+ expected_stride *= ext.extent(s);
+ }
+}
+
+} // namespace detail
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/macros.hpp b/ext/mdspan/include/experimental/__p0009_bits/macros.hpp
new file mode 100644
index 0000000..b60c426
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/macros.hpp
@@ -0,0 +1,699 @@
+//@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
+
+#pragma once
+
+#include "config.hpp"
+
+#include <cstdio>
+#include <cstdlib>
+#include <type_traits> // std::is_void
+#if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP) || defined(_MDSPAN_HAS_SYCL)
+#include "assert.h"
+#endif
+
+#ifndef _MDSPAN_HOST_DEVICE
+# if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP)
+# define _MDSPAN_HOST_DEVICE __host__ __device__
+# else
+# define _MDSPAN_HOST_DEVICE
+# endif
+#endif
+
+#ifndef MDSPAN_FORCE_INLINE_FUNCTION
+# ifdef _MDSPAN_COMPILER_MSVC // Microsoft compilers
+# define MDSPAN_FORCE_INLINE_FUNCTION __forceinline _MDSPAN_HOST_DEVICE
+# else
+# define MDSPAN_FORCE_INLINE_FUNCTION __attribute__((always_inline)) _MDSPAN_HOST_DEVICE
+# endif
+#endif
+
+#ifndef MDSPAN_INLINE_FUNCTION
+# define MDSPAN_INLINE_FUNCTION inline _MDSPAN_HOST_DEVICE
+#endif
+
+#ifndef MDSPAN_FUNCTION
+# define MDSPAN_FUNCTION _MDSPAN_HOST_DEVICE
+#endif
+
+#ifdef _MDSPAN_HAS_HIP
+# define MDSPAN_DEDUCTION_GUIDE _MDSPAN_HOST_DEVICE
+#else
+# define MDSPAN_DEDUCTION_GUIDE
+#endif
+
+// In CUDA defaulted functions do not need host device markup
+#ifndef MDSPAN_INLINE_FUNCTION_DEFAULTED
+# define MDSPAN_INLINE_FUNCTION_DEFAULTED
+#endif
+
+//==============================================================================
+// <editor-fold desc="Preprocessor helpers"> {{{1
+
+#define MDSPAN_PP_COUNT(...) \
+ _MDSPAN_PP_INTERNAL_EXPAND_ARGS_PRIVATE( \
+ _MDSPAN_PP_INTERNAL_ARGS_AUGMENTER(__VA_ARGS__) \
+ )
+
+#define _MDSPAN_PP_INTERNAL_ARGS_AUGMENTER(...) unused, __VA_ARGS__
+#define _MDSPAN_PP_INTERNAL_EXPAND(x) x
+#define _MDSPAN_PP_INTERNAL_EXPAND_ARGS_PRIVATE(...) \
+ _MDSPAN_PP_INTERNAL_EXPAND( \
+ _MDSPAN_PP_INTERNAL_COUNT_PRIVATE( \
+ __VA_ARGS__, 69, 68, 67, 66, 65, 64, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
+ 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, \
+ 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, \
+ 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
+ 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 \
+ ) \
+ )
+# define _MDSPAN_PP_INTERNAL_COUNT_PRIVATE( \
+ _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, \
+ _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
+ _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
+ _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
+ _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
+ _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
+ _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, \
+ _70, count, ...) count \
+ /**/
+
+#define MDSPAN_PP_STRINGIFY_IMPL(x) #x
+#define MDSPAN_PP_STRINGIFY(x) MDSPAN_PP_STRINGIFY_IMPL(x)
+
+#define MDSPAN_PP_CAT_IMPL(x, y) x ## y
+#define MDSPAN_PP_CAT(x, y) MDSPAN_PP_CAT_IMPL(x, y)
+
+#define MDSPAN_PP_EVAL(X, ...) X(__VA_ARGS__)
+
+#define MDSPAN_PP_REMOVE_PARENS_IMPL(...) __VA_ARGS__
+#define MDSPAN_PP_REMOVE_PARENS(...) MDSPAN_PP_REMOVE_PARENS_IMPL __VA_ARGS__
+
+#define MDSPAN_IMPL_STANDARD_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE)
+#define MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) "::" MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_PROPOSED_NAMESPACE)
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+#if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP)
+MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line)
+{
+ printf("%s:%u: precondition failure: `%s`\n", file, line, cond);
+ assert(0);
+}
+#elif defined(_MDSPAN_HAS_SYCL)
+MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line)
+{
+ sycl::ext::oneapi::experimental::printf("%s:%u: precondition failure: `%s`\n", file, line, cond);
+ assert(0);
+}
+#else
+MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line)
+{
+ std::fprintf(stderr, "%s:%u: precondition failure: `%s`\n", file, line, cond);
+ std::abort();
+}
+#endif
+
+} // namespace detail
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+#ifndef MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER
+#define MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line) \
+ MDSPAN_IMPL_STANDARD_NAMESPACE::detail::default_precondition_violation_handler(cond, file, line)
+#endif
+
+#ifndef MDSPAN_IMPL_CHECK_PRECONDITION
+ #ifndef NDEBUG
+ #define MDSPAN_IMPL_CHECK_PRECONDITION 0
+ #else
+ #define MDSPAN_IMPL_CHECK_PRECONDITION 1
+ #endif
+#endif
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+template <bool check = MDSPAN_IMPL_CHECK_PRECONDITION>
+MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, unsigned line)
+{
+ if (!check) { return; }
+ // in case the macro doesn't use the arguments for custom macros
+ (void) cond;
+ (void) file;
+ (void) line;
+ MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line);
+}
+
+} // namespace detail
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+#define MDSPAN_IMPL_PRECONDITION(...) \
+ do { \
+ if (!(__VA_ARGS__)) { \
+ MDSPAN_IMPL_STANDARD_NAMESPACE::detail::precondition(#__VA_ARGS__, __FILE__, __LINE__); \
+ } \
+ } while (0)
+
+// </editor-fold> end Preprocessor helpers }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="Concept emulation"> {{{1
+
+// These compatibility macros don't help with partial ordering, but they should do the trick
+// for what we need to do with concepts in mdspan
+#ifdef _MDSPAN_USE_CONCEPTS
+# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) > requires REQ
+# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \
+ MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS requires REQ \
+ /**/
+#else
+# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) , typename ::std::enable_if<(REQ), int>::type = 0>
+# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \
+ MDSPAN_TEMPLATE_REQUIRES( \
+ class __function_requires_ignored=void, \
+ (std::is_void<__function_requires_ignored>::value && REQ) \
+ ) MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS \
+ /**/
+#endif
+
+#if defined(_MDSPAN_COMPILER_MSVC) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
+# define MDSPAN_TEMPLATE_REQUIRES(...) \
+ MDSPAN_PP_CAT( \
+ MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__))\
+ (__VA_ARGS__), \
+ ) \
+ /**/
+#else
+# define MDSPAN_TEMPLATE_REQUIRES(...) \
+ MDSPAN_PP_EVAL( \
+ MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__)), \
+ __VA_ARGS__ \
+ ) \
+ /**/
+#endif
+
+#define MDSPAN_TEMPLATE_REQUIRES_2(TP1, REQ) \
+ template<TP1 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_3(TP1, TP2, REQ) \
+ template<TP1, TP2 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_4(TP1, TP2, TP3, REQ) \
+ template<TP1, TP2, TP3 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_5(TP1, TP2, TP3, TP4, REQ) \
+ template<TP1, TP2, TP3, TP4 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_6(TP1, TP2, TP3, TP4, TP5, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_7(TP1, TP2, TP3, TP4, TP5, TP6, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_8(TP1, TP2, TP3, TP4, TP5, TP6, TP7, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_9(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_10(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_11(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_12(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_13(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_14(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_15(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_16(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_17(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_18(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_19(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+#define MDSPAN_TEMPLATE_REQUIRES_20(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, TP19, REQ) \
+ template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, TP19 \
+ MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \
+ /**/
+
+#define MDSPAN_INSTANTIATE_ONLY_IF_USED \
+ MDSPAN_TEMPLATE_REQUIRES( \
+ class __instantiate_only_if_used_tparam=void, \
+ ( _MDSPAN_TRAIT(std::is_void, __instantiate_only_if_used_tparam) ) \
+ ) \
+ /**/
+
+// </editor-fold> end Concept emulation }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="inline variables"> {{{1
+
+#ifdef _MDSPAN_USE_INLINE_VARIABLES
+# define _MDSPAN_INLINE_VARIABLE inline
+#else
+# define _MDSPAN_INLINE_VARIABLE
+#endif
+
+// </editor-fold> end inline variables }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="Return type deduction"> {{{1
+
+#if _MDSPAN_USE_RETURN_TYPE_DEDUCTION
+# define _MDSPAN_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \
+ auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); }
+# define _MDSPAN_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \
+ decltype(auto) MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); }
+#else
+# define _MDSPAN_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \
+ auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \
+ -> std::remove_cv_t<std::remove_reference_t<decltype(BODY)>> \
+ { return MDSPAN_PP_REMOVE_PARENS(BODY); }
+# define _MDSPAN_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \
+ auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \
+ -> decltype(BODY) \
+ { return MDSPAN_PP_REMOVE_PARENS(BODY); }
+
+#endif
+
+// </editor-fold> end Return type deduction }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="fold expressions"> {{{1
+
+struct __mdspan_enable_fold_comma { };
+
+#ifdef _MDSPAN_USE_FOLD_EXPRESSIONS
+# define _MDSPAN_FOLD_AND(...) ((__VA_ARGS__) && ...)
+# define _MDSPAN_FOLD_AND_TEMPLATE(...) ((__VA_ARGS__) && ...)
+# define _MDSPAN_FOLD_OR(...) ((__VA_ARGS__) || ...)
+# define _MDSPAN_FOLD_ASSIGN_LEFT(INIT, ...) (INIT = ... = (__VA_ARGS__))
+# define _MDSPAN_FOLD_ASSIGN_RIGHT(PACK, ...) (PACK = ... = (__VA_ARGS__))
+# define _MDSPAN_FOLD_TIMES_RIGHT(PACK, ...) (PACK * ... * (__VA_ARGS__))
+# define _MDSPAN_FOLD_PLUS_RIGHT(PACK, ...) (PACK + ... + (__VA_ARGS__))
+# define _MDSPAN_FOLD_COMMA(...) ((__VA_ARGS__), ...)
+#else
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+namespace __fold_compatibility_impl {
+
+// We could probably be more clever here, but at the (small) risk of losing some compiler understanding. For the
+// few operations we need, it's not worth generalizing over the operation
+
+#if _MDSPAN_USE_RETURN_TYPE_DEDUCTION
+
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr decltype(auto) __fold_right_and_impl() {
+ return true;
+}
+
+template <class Arg, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr decltype(auto) __fold_right_and_impl(Arg&& arg, Args&&... args) {
+ return ((Arg&&)arg) && __fold_compatibility_impl::__fold_right_and_impl((Args&&)args...);
+}
+
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr decltype(auto) __fold_right_or_impl() {
+ return false;
+}
+
+template <class Arg, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_or_impl(Arg&& arg, Args&&... args) {
+ return ((Arg&&)arg) || __fold_compatibility_impl::__fold_right_or_impl((Args&&)args...);
+}
+
+template <class Arg1>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_left_assign_impl(Arg1&& arg1) {
+ return (Arg1&&)arg1;
+}
+
+template <class Arg1, class Arg2, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_left_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) {
+ return __fold_compatibility_impl::__fold_left_assign_impl((((Arg1&&)arg1) = ((Arg2&&)arg2)), (Args&&)args...);
+}
+
+template <class Arg1>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_assign_impl(Arg1&& arg1) {
+ return (Arg1&&)arg1;
+}
+
+template <class Arg1, class Arg2, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) {
+ return ((Arg1&&)arg1) = __fold_compatibility_impl::__fold_right_assign_impl((Arg2&&)arg2, (Args&&)args...);
+}
+
+template <class Arg1>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_plus_impl(Arg1&& arg1) {
+ return (Arg1&&)arg1;
+}
+
+template <class Arg1, class Arg2, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_plus_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) {
+ return ((Arg1&&)arg1) + __fold_compatibility_impl::__fold_right_plus_impl((Arg2&&)arg2, (Args&&)args...);
+}
+
+template <class Arg1>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_times_impl(Arg1&& arg1) {
+ return (Arg1&&)arg1;
+}
+
+template <class Arg1, class Arg2, class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr auto __fold_right_times_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) {
+ return ((Arg1&&)arg1) * __fold_compatibility_impl::__fold_right_times_impl((Arg2&&)arg2, (Args&&)args...);
+}
+
+#else
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="right and"> {{{2
+
+template <class... Args>
+struct __fold_right_and_impl_;
+template <>
+struct __fold_right_and_impl_<> {
+ using __rv = bool;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl() noexcept {
+ return true;
+ }
+};
+template <class Arg, class... Args>
+struct __fold_right_and_impl_<Arg, Args...> {
+ using __next_t = __fold_right_and_impl_<Args...>;
+ using __rv = decltype(std::declval<Arg>() && std::declval<typename __next_t::__rv>());
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg, Args&&... args) noexcept {
+ return ((Arg&&)arg) && __next_t::__impl((Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_right_and_impl_<Args...>::__rv
+__fold_right_and_impl(Args&&... args) {
+ return __fold_right_and_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end right and }}}2
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="right or"> {{{2
+
+template <class... Args>
+struct __fold_right_or_impl_;
+template <>
+struct __fold_right_or_impl_<> {
+ using __rv = bool;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl() noexcept {
+ return false;
+ }
+};
+template <class Arg, class... Args>
+struct __fold_right_or_impl_<Arg, Args...> {
+ using __next_t = __fold_right_or_impl_<Args...>;
+ using __rv = decltype(std::declval<Arg>() || std::declval<typename __next_t::__rv>());
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg, Args&&... args) noexcept {
+ return ((Arg&&)arg) || __next_t::__impl((Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_right_or_impl_<Args...>::__rv
+__fold_right_or_impl(Args&&... args) {
+ return __fold_right_or_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end right or }}}2
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="right plus"> {{{2
+
+template <class... Args>
+struct __fold_right_plus_impl_;
+template <class Arg>
+struct __fold_right_plus_impl_<Arg> {
+ using __rv = Arg&&;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg) noexcept {
+ return (Arg&&)arg;
+ }
+};
+template <class Arg1, class Arg2, class... Args>
+struct __fold_right_plus_impl_<Arg1, Arg2, Args...> {
+ using __next_t = __fold_right_plus_impl_<Arg2, Args...>;
+ using __rv = decltype(std::declval<Arg1>() + std::declval<typename __next_t::__rv>());
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept {
+ return ((Arg1&&)arg) + __next_t::__impl((Arg2&&)arg2, (Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_right_plus_impl_<Args...>::__rv
+__fold_right_plus_impl(Args&&... args) {
+ return __fold_right_plus_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end right plus }}}2
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="right times"> {{{2
+
+template <class... Args>
+struct __fold_right_times_impl_;
+template <class Arg>
+struct __fold_right_times_impl_<Arg> {
+ using __rv = Arg&&;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg) noexcept {
+ return (Arg&&)arg;
+ }
+};
+template <class Arg1, class Arg2, class... Args>
+struct __fold_right_times_impl_<Arg1, Arg2, Args...> {
+ using __next_t = __fold_right_times_impl_<Arg2, Args...>;
+ using __rv = decltype(std::declval<Arg1>() * std::declval<typename __next_t::__rv>());
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept {
+ return ((Arg1&&)arg) * __next_t::__impl((Arg2&&)arg2, (Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_right_times_impl_<Args...>::__rv
+__fold_right_times_impl(Args&&... args) {
+ return __fold_right_times_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end right times }}}2
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="right assign"> {{{2
+
+template <class... Args>
+struct __fold_right_assign_impl_;
+template <class Arg>
+struct __fold_right_assign_impl_<Arg> {
+ using __rv = Arg&&;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg) noexcept {
+ return (Arg&&)arg;
+ }
+};
+template <class Arg1, class Arg2, class... Args>
+struct __fold_right_assign_impl_<Arg1, Arg2, Args...> {
+ using __next_t = __fold_right_assign_impl_<Arg2, Args...>;
+ using __rv = decltype(std::declval<Arg1>() = std::declval<typename __next_t::__rv>());
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept {
+ return ((Arg1&&)arg) = __next_t::__impl((Arg2&&)arg2, (Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_right_assign_impl_<Args...>::__rv
+__fold_right_assign_impl(Args&&... args) {
+ return __fold_right_assign_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end right assign }}}2
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// <editor-fold desc="left assign"> {{{2
+
+template <class... Args>
+struct __fold_left_assign_impl_;
+template <class Arg>
+struct __fold_left_assign_impl_<Arg> {
+ using __rv = Arg&&;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg&& arg) noexcept {
+ return (Arg&&)arg;
+ }
+};
+template <class Arg1, class Arg2, class... Args>
+struct __fold_left_assign_impl_<Arg1, Arg2, Args...> {
+ using __assign_result_t = decltype(std::declval<Arg1>() = std::declval<Arg2>());
+ using __next_t = __fold_left_assign_impl_<__assign_result_t, Args...>;
+ using __rv = typename __next_t::__rv;
+ MDSPAN_FORCE_INLINE_FUNCTION
+ static constexpr __rv
+ __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept {
+ return __next_t::__impl(((Arg1&&)arg) = (Arg2&&)arg2, (Args&&)args...);
+ }
+};
+
+template <class... Args>
+MDSPAN_FORCE_INLINE_FUNCTION
+constexpr typename __fold_left_assign_impl_<Args...>::__rv
+__fold_left_assign_impl(Args&&... args) {
+ return __fold_left_assign_impl_<Args...>::__impl((Args&&)args...);
+}
+
+// </editor-fold> end left assign }}}2
+//------------------------------------------------------------------------------
+
+#endif
+
+
+template <class... Args>
+constexpr __mdspan_enable_fold_comma __fold_comma_impl(Args&&...) noexcept { return { }; }
+
+template <bool... Bs>
+struct __bools;
+
+} // __fold_compatibility_impl
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+# define _MDSPAN_FOLD_AND(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_and_impl((__VA_ARGS__)...)
+# define _MDSPAN_FOLD_OR(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_or_impl((__VA_ARGS__)...)
+# define _MDSPAN_FOLD_ASSIGN_LEFT(INIT, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_left_assign_impl(INIT, (__VA_ARGS__)...)
+# define _MDSPAN_FOLD_ASSIGN_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_assign_impl((PACK)..., __VA_ARGS__)
+# define _MDSPAN_FOLD_TIMES_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_times_impl((PACK)..., __VA_ARGS__)
+# define _MDSPAN_FOLD_PLUS_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_plus_impl((PACK)..., __VA_ARGS__)
+# define _MDSPAN_FOLD_COMMA(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_comma_impl((__VA_ARGS__)...)
+
+# define _MDSPAN_FOLD_AND_TEMPLATE(...) \
+ _MDSPAN_TRAIT(std::is_same, __fold_compatibility_impl::__bools<(__VA_ARGS__)..., true>, __fold_compatibility_impl::__bools<true, (__VA_ARGS__)...>)
+
+#endif
+
+// </editor-fold> end fold expressions }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="Variable template compatibility"> {{{1
+
+#if _MDSPAN_USE_VARIABLE_TEMPLATES
+# define _MDSPAN_TRAIT(TRAIT, ...) TRAIT##_v<__VA_ARGS__>
+#else
+# define _MDSPAN_TRAIT(TRAIT, ...) TRAIT<__VA_ARGS__>::value
+#endif
+
+// </editor-fold> end Variable template compatibility }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="Pre-C++14 constexpr"> {{{1
+
+#if _MDSPAN_USE_CONSTEXPR_14
+# define _MDSPAN_CONSTEXPR_14 constexpr
+// Workaround for a bug (I think?) in EDG frontends
+# ifdef __EDG__
+# define _MDSPAN_CONSTEXPR_14_DEFAULTED
+# else
+# define _MDSPAN_CONSTEXPR_14_DEFAULTED constexpr
+# endif
+#else
+# define _MDSPAN_CONSTEXPR_14
+# define _MDSPAN_CONSTEXPR_14_DEFAULTED
+#endif
+
+// </editor-fold> end Pre-C++14 constexpr }}}1
+//==============================================================================
diff --git a/ext/mdspan/include/experimental/__p0009_bits/mdspan.hpp b/ext/mdspan/include/experimental/__p0009_bits/mdspan.hpp
new file mode 100644
index 0000000..23114aa
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/mdspan.hpp
@@ -0,0 +1,432 @@
+//@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
+
+#pragma once
+
+#include "default_accessor.hpp"
+#include "layout_right.hpp"
+#include "extents.hpp"
+#include "trait_backports.hpp"
+#include "compressed_pair.hpp"
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+template <
+ class ElementType,
+ class Extents,
+ class LayoutPolicy = layout_right,
+ class AccessorPolicy = default_accessor<ElementType>
+>
+class mdspan
+{
+private:
+ static_assert(detail::__is_extents_v<Extents>,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's Extents template parameter must be a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents.");
+ static_assert(std::is_same<ElementType, typename AccessorPolicy::element_type>::value,
+ MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's ElementType template parameter must be the same as its AccessorPolicy::element_type.");
+
+ // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level
+ template <class>
+ struct __deduction_workaround;
+
+ template <size_t... Idxs>
+ struct __deduction_workaround<std::index_sequence<Idxs...>>
+ {
+ MDSPAN_FORCE_INLINE_FUNCTION static constexpr
+ size_t __size(mdspan const& __self) noexcept {
+ return _MDSPAN_FOLD_TIMES_RIGHT((__self.__mapping_ref().extents().extent(Idxs)), /* * ... * */ size_t(1));
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION static constexpr
+ bool __empty(mdspan const& __self) noexcept {
+ return (__self.rank()>0) && _MDSPAN_FOLD_OR((__self.__mapping_ref().extents().extent(Idxs)==index_type(0)));
+ }
+ template <class ReferenceType, class SizeType, size_t N>
+ MDSPAN_FORCE_INLINE_FUNCTION static constexpr
+ ReferenceType __callop(mdspan const& __self, const std::array<SizeType, N>& indices) noexcept {
+ return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...));
+ }
+#ifdef __cpp_lib_span
+ template <class ReferenceType, class SizeType, size_t N>
+ MDSPAN_FORCE_INLINE_FUNCTION static constexpr
+ ReferenceType __callop(mdspan const& __self, const std::span<SizeType, N>& indices) noexcept {
+ return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...));
+ }
+#endif
+ };
+
+public:
+
+ //--------------------------------------------------------------------------------
+ // Domain and codomain types
+
+ using extents_type = Extents;
+ using layout_type = LayoutPolicy;
+ using accessor_type = AccessorPolicy;
+ using mapping_type = typename layout_type::template mapping<extents_type>;
+ using element_type = ElementType;
+ using value_type = std::remove_cv_t<element_type>;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using data_handle_type = typename accessor_type::data_handle_type;
+ using reference = typename accessor_type::reference;
+
+ MDSPAN_INLINE_FUNCTION static constexpr size_t rank() noexcept { return extents_type::rank(); }
+ MDSPAN_INLINE_FUNCTION static constexpr size_t rank_dynamic() noexcept { return extents_type::rank_dynamic(); }
+ MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent(size_t r) noexcept { return extents_type::static_extent(r); }
+ MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return __mapping_ref().extents().extent(r); };
+
+private:
+
+ // Can't use defaulted parameter in the __deduction_workaround template because of a bug in MSVC warning C4348.
+ using __impl = __deduction_workaround<std::make_index_sequence<extents_type::rank()>>;
+
+ using __map_acc_pair_t = detail::__compressed_pair<mapping_type, accessor_type>;
+
+public:
+
+ //--------------------------------------------------------------------------------
+ // [mdspan.basic.cons], mdspan constructors, assignment, and destructor
+
+#if !MDSPAN_HAS_CXX_20
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan() = default;
+#else
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan()
+ requires(
+ // nvhpc has a bug where using just rank_dynamic() here doesn't work ...
+ (extents_type::rank_dynamic() > 0) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, data_handle_type) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, mapping_type) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, accessor_type)
+ ) = default;
+#endif
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(const mdspan&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(mdspan&&) = default;
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... SizeTypes,
+ /* requires */ (
+ ((sizeof...(SizeTypes) == rank()) || (sizeof...(SizeTypes) == rank_dynamic())) &&
+ (detail::are_valid_indices<index_type, SizeTypes...>()) &&
+ _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, accessor_type)
+ )
+ )
+ MDSPAN_INLINE_FUNCTION
+ explicit constexpr mdspan(data_handle_type p, SizeTypes... dynamic_extents)
+ // TODO @proposal-bug shouldn't I be allowed to do `move(p)` here?
+ : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(static_cast<index_type>(std::move(dynamic_extents))...)), accessor_type()))
+ { }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType, size_t N,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) &&
+ ((N == rank()) || (N == rank_dynamic())) &&
+ _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, accessor_type)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic())
+ MDSPAN_INLINE_FUNCTION
+ constexpr mdspan(data_handle_type p, const std::array<SizeType, N>& dynamic_extents)
+ : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(dynamic_extents)), accessor_type()))
+ { }
+
+#ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType, size_t N,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) &&
+ ((N == rank()) || (N == rank_dynamic())) &&
+ _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) &&
+ _MDSPAN_TRAIT(std::is_default_constructible, accessor_type)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic())
+ MDSPAN_INLINE_FUNCTION
+ constexpr mdspan(data_handle_type p, std::span<SizeType, N> dynamic_extents)
+ : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(as_const(dynamic_extents))), accessor_type()))
+ { }
+#endif
+
+ MDSPAN_FUNCTION_REQUIRES(
+ (MDSPAN_INLINE_FUNCTION constexpr),
+ mdspan, (data_handle_type p, const extents_type& exts), ,
+ /* requires */ (_MDSPAN_TRAIT(std::is_default_constructible, accessor_type) &&
+ _MDSPAN_TRAIT(std::is_constructible, mapping_type, const extents_type&))
+ ) : __members(std::move(p), __map_acc_pair_t(mapping_type(exts), accessor_type()))
+ { }
+
+ MDSPAN_FUNCTION_REQUIRES(
+ (MDSPAN_INLINE_FUNCTION constexpr),
+ mdspan, (data_handle_type p, const mapping_type& m), ,
+ /* requires */ (_MDSPAN_TRAIT(std::is_default_constructible, accessor_type))
+ ) : __members(std::move(p), __map_acc_pair_t(m, accessor_type()))
+ { }
+
+ MDSPAN_INLINE_FUNCTION
+ constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a)
+ : __members(std::move(p), __map_acc_pair_t(m, a))
+ { }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessor,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_constructible, mapping_type, const typename OtherLayoutPolicy::template mapping<OtherExtents>&) &&
+ _MDSPAN_TRAIT(std::is_constructible, accessor_type, const OtherAccessor&)
+ )
+ )
+ MDSPAN_CONDITIONAL_EXPLICIT(
+ !_MDSPAN_TRAIT(std::is_convertible, const typename OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type) ||
+ !_MDSPAN_TRAIT(std::is_convertible, const OtherAccessor&, accessor_type)
+ )
+ MDSPAN_INLINE_FUNCTION
+ constexpr mdspan(const mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherAccessor>& other)
+ : __members(other.__ptr_ref(), __map_acc_pair_t(other.__mapping_ref(), other.__accessor_ref()))
+ {
+ static_assert(_MDSPAN_TRAIT(std::is_constructible, data_handle_type, typename OtherAccessor::data_handle_type),"Incompatible data_handle_type for mdspan construction");
+ static_assert(_MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents),"Incompatible extents for mdspan construction");
+ /*
+ * TODO: Check precondition
+ * For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true.
+ */
+ }
+
+ /* Might need this on NVIDIA?
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~mdspan() = default;
+ */
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(const mdspan&) = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(mdspan&&) = default;
+
+
+ //--------------------------------------------------------------------------------
+ // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to access codomain element
+
+ #if MDSPAN_USE_BRACKET_OPERATOR
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... SizeTypes,
+ /* requires */ (
+ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, SizeTypes, index_type) /* && ... */) &&
+ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, SizeTypes) /* && ... */) &&
+ (rank() == sizeof...(SizeTypes))
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator[](SizeTypes... indices) const
+ {
+ return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...));
+ }
+ #endif
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&)
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator[](const std::array< SizeType, rank()>& indices) const
+ {
+ return __impl::template __callop<reference>(*this, indices);
+ }
+
+ #ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&)
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator[](std::span<SizeType, rank()> indices) const
+ {
+ return __impl::template __callop<reference>(*this, indices);
+ }
+ #endif // __cpp_lib_span
+
+ #if !MDSPAN_USE_BRACKET_OPERATOR
+ MDSPAN_TEMPLATE_REQUIRES(
+ class Index,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, Index, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, Index) &&
+ extents_type::rank() == 1
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator[](Index idx) const
+ {
+ return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(idx))));
+ }
+ #endif
+
+ #if MDSPAN_USE_PAREN_OPERATOR
+ MDSPAN_TEMPLATE_REQUIRES(
+ class... SizeTypes,
+ /* requires */ (
+ extents_type::rank() == sizeof...(SizeTypes) &&
+ (detail::are_valid_indices<index_type, SizeTypes...>())
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator()(SizeTypes... indices) const
+ {
+ return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...));
+ }
+
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&)
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator()(const std::array<SizeType, rank()>& indices) const
+ {
+ return __impl::template __callop<reference>(*this, indices);
+ }
+
+ #ifdef __cpp_lib_span
+ MDSPAN_TEMPLATE_REQUIRES(
+ class SizeType,
+ /* requires */ (
+ _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) &&
+ _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&)
+ )
+ )
+ MDSPAN_FORCE_INLINE_FUNCTION
+ constexpr reference operator()(std::span<SizeType, rank()> indices) const
+ {
+ return __impl::template __callop<reference>(*this, indices);
+ }
+ #endif // __cpp_lib_span
+ #endif // MDSPAN_USE_PAREN_OPERATOR
+
+ MDSPAN_INLINE_FUNCTION constexpr size_type size() const noexcept {
+ return static_cast<size_type>(__impl::__size(*this));
+ };
+
+ MDSPAN_INLINE_FUNCTION constexpr bool empty() const noexcept {
+ return __impl::__empty(*this);
+ };
+
+ MDSPAN_INLINE_FUNCTION
+ friend constexpr void swap(mdspan& x, mdspan& y) noexcept {
+ // can't call the std::swap inside on HIP
+ #if !defined(_MDSPAN_HAS_HIP) && !defined(_MDSPAN_HAS_CUDA)
+ using std::swap;
+ swap(x.__ptr_ref(), y.__ptr_ref());
+ swap(x.__mapping_ref(), y.__mapping_ref());
+ swap(x.__accessor_ref(), y.__accessor_ref());
+ #else
+ mdspan tmp = y;
+ y = x;
+ x = tmp;
+ #endif
+ }
+
+ //--------------------------------------------------------------------------------
+ // [mdspan.basic.domobs], mdspan observers of the domain multidimensional index space
+
+
+ MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return __mapping_ref().extents(); };
+ MDSPAN_INLINE_FUNCTION constexpr const data_handle_type& data_handle() const noexcept { return __ptr_ref(); };
+ MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() const noexcept { return __mapping_ref(); };
+ MDSPAN_INLINE_FUNCTION constexpr const accessor_type& accessor() const noexcept { return __accessor_ref(); };
+
+ //--------------------------------------------------------------------------------
+ // [mdspan.basic.obs], mdspan observers of the mapping
+
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); };
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); };
+ MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); };
+
+ MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const { return __mapping_ref().is_unique(); };
+ MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const { return __mapping_ref().is_exhaustive(); };
+ MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const { return __mapping_ref().is_strided(); };
+ MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return __mapping_ref().stride(r); };
+
+private:
+
+ detail::__compressed_pair<data_handle_type, __map_acc_pair_t> __members{};
+
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 data_handle_type& __ptr_ref() noexcept { return __members.__first(); }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr data_handle_type const& __ptr_ref() const noexcept { return __members.__first(); }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 mapping_type& __mapping_ref() noexcept { return __members.__second().__first(); }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const& __mapping_ref() const noexcept { return __members.__second().__first(); }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 accessor_type& __accessor_ref() noexcept { return __members.__second().__second(); }
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type const& __accessor_ref() const noexcept { return __members.__second().__second(); }
+
+ template <class, class, class, class>
+ friend class mdspan;
+
+};
+
+#if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION)
+MDSPAN_TEMPLATE_REQUIRES(
+ class ElementType, class... SizeTypes,
+ /* requires */ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, SizeTypes, size_t) /* && ... */) &&
+ (sizeof...(SizeTypes) > 0)
+)
+MDSPAN_DEDUCTION_GUIDE explicit mdspan(ElementType*, SizeTypes...)
+ -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, sizeof...(SizeTypes)>>;
+
+MDSPAN_TEMPLATE_REQUIRES(
+ class Pointer,
+ (_MDSPAN_TRAIT(std::is_pointer, std::remove_reference_t<Pointer>))
+)
+MDSPAN_DEDUCTION_GUIDE mdspan(Pointer&&) -> mdspan<std::remove_pointer_t<std::remove_reference_t<Pointer>>, extents<size_t>>;
+
+MDSPAN_TEMPLATE_REQUIRES(
+ class CArray,
+ (_MDSPAN_TRAIT(std::is_array, CArray) && (std::rank_v<CArray> == 1))
+)
+MDSPAN_DEDUCTION_GUIDE mdspan(CArray&) -> mdspan<std::remove_all_extents_t<CArray>, extents<size_t, ::std::extent_v<CArray,0>>>;
+
+template <class ElementType, class SizeType, size_t N>
+MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const ::std::array<SizeType, N>&)
+ -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, N>>;
+
+#ifdef __cpp_lib_span
+template <class ElementType, class SizeType, size_t N>
+MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, ::std::span<SizeType, N>)
+ -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, N>>;
+#endif
+
+// This one is necessary because all the constructors take `data_handle_type`s, not
+// `ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which
+// seems to throw off automatic deduction guides.
+template <class ElementType, class SizeType, size_t... ExtentsPack>
+MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const extents<SizeType, ExtentsPack...>&)
+ -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, ExtentsPack...>>;
+
+template <class ElementType, class MappingType>
+MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const MappingType&)
+ -> mdspan<ElementType, typename MappingType::extents_type, typename MappingType::layout_type>;
+
+template <class MappingType, class AccessorType>
+MDSPAN_DEDUCTION_GUIDE mdspan(const typename AccessorType::data_handle_type, const MappingType&, const AccessorType&)
+ -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type, typename MappingType::layout_type, AccessorType>;
+#endif
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp b/ext/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp
new file mode 100644
index 0000000..36e64ee
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp
@@ -0,0 +1,97 @@
+//@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
+#pragma once
+
+#include "macros.hpp"
+#include "trait_backports.hpp"
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+//==============================================================================
+
+template <class _T, size_t _Disambiguator = 0, class _Enable = void>
+struct __no_unique_address_emulation {
+ using __stored_type = _T;
+ _T __v;
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T const &__ref() const noexcept {
+ return __v;
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T &__ref() noexcept {
+ return __v;
+ }
+};
+
+// Empty case
+// This doesn't work if _T is final, of course, but we're not using anything
+// like that currently. That kind of thing could be added pretty easily though
+template <class _T, size_t _Disambiguator>
+struct __no_unique_address_emulation<
+ _T, _Disambiguator,
+ std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T) &&
+ // If the type isn't trivially destructible, its destructor
+ // won't be called at the right time, so don't use this
+ // specialization
+ _MDSPAN_TRAIT(std::is_trivially_destructible, _T)>> :
+#ifdef _MDSPAN_COMPILER_MSVC
+ // MSVC doesn't allow you to access public static member functions of a type
+ // when you *happen* to privately inherit from that type.
+ protected
+#else
+ // But we still want this to be private if possible so that we don't accidentally
+ // access members of _T directly rather than calling __ref() first, which wouldn't
+ // work if _T happens to be stateful and thus we're using the unspecialized definition
+ // of __no_unique_address_emulation above.
+ private
+#endif
+ _T {
+ using __stored_type = _T;
+ MDSPAN_FORCE_INLINE_FUNCTION constexpr _T const &__ref() const noexcept {
+ return *static_cast<_T const *>(this);
+ }
+ MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T &__ref() noexcept {
+ return *static_cast<_T *>(this);
+ }
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __no_unique_address_emulation() noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __no_unique_address_emulation(
+ __no_unique_address_emulation const &) noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr __no_unique_address_emulation(
+ __no_unique_address_emulation &&) noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __no_unique_address_emulation &
+ operator=(__no_unique_address_emulation const &) noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ _MDSPAN_CONSTEXPR_14_DEFAULTED __no_unique_address_emulation &
+ operator=(__no_unique_address_emulation &&) noexcept = default;
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ ~__no_unique_address_emulation() noexcept = default;
+
+ // Explicitly make this not a reference so that the copy or move
+ // constructor still gets called.
+ MDSPAN_INLINE_FUNCTION
+ explicit constexpr __no_unique_address_emulation(_T const& __v) noexcept : _T(__v) {}
+ MDSPAN_INLINE_FUNCTION
+ explicit constexpr __no_unique_address_emulation(_T&& __v) noexcept : _T(::std::move(__v)) {}
+};
+
+//==============================================================================
+
+} // end namespace detail
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
diff --git a/ext/mdspan/include/experimental/__p0009_bits/trait_backports.hpp b/ext/mdspan/include/experimental/__p0009_bits/trait_backports.hpp
new file mode 100644
index 0000000..4933dd9
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/trait_backports.hpp
@@ -0,0 +1,132 @@
+//@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
+#ifndef MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_
+#define MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_
+
+#include "macros.hpp"
+#include "config.hpp"
+
+#include <type_traits>
+#include <utility> // integer_sequence
+
+//==============================================================================
+// <editor-fold desc="Variable template trait backports (e.g., is_void_v)"> {{{1
+
+#ifdef _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS
+
+#if _MDSPAN_USE_VARIABLE_TEMPLATES
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+#define _MDSPAN_BACKPORT_TRAIT(TRAIT) \
+ template <class... Args> _MDSPAN_INLINE_VARIABLE constexpr auto TRAIT##_v = TRAIT<Args...>::value;
+
+_MDSPAN_BACKPORT_TRAIT(is_assignable)
+_MDSPAN_BACKPORT_TRAIT(is_constructible)
+_MDSPAN_BACKPORT_TRAIT(is_convertible)
+_MDSPAN_BACKPORT_TRAIT(is_default_constructible)
+_MDSPAN_BACKPORT_TRAIT(is_trivially_destructible)
+_MDSPAN_BACKPORT_TRAIT(is_same)
+_MDSPAN_BACKPORT_TRAIT(is_empty)
+_MDSPAN_BACKPORT_TRAIT(is_void)
+
+#undef _MDSPAN_BACKPORT_TRAIT
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+#endif // _MDSPAN_USE_VARIABLE_TEMPLATES
+
+#endif // _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS
+
+// </editor-fold> end Variable template trait backports (e.g., is_void_v) }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="integer sequence (ugh...)"> {{{1
+
+#if !defined(_MDSPAN_USE_INTEGER_SEQUENCE) || !_MDSPAN_USE_INTEGER_SEQUENCE
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+template <class T, T... Vals>
+struct integer_sequence {
+ static constexpr size_t size() noexcept { return sizeof...(Vals); }
+ using value_type = T;
+};
+
+template <size_t... Vals>
+using index_sequence = std::integer_sequence<size_t, Vals...>;
+
+namespace __detail {
+
+template <class T, T N, T I, class Result>
+struct __make_int_seq_impl;
+
+template <class T, T N, T... Vals>
+struct __make_int_seq_impl<T, N, N, integer_sequence<T, Vals...>>
+{
+ using type = integer_sequence<T, Vals...>;
+};
+
+template <class T, T N, T I, T... Vals>
+struct __make_int_seq_impl<
+ T, N, I, integer_sequence<T, Vals...>
+> : __make_int_seq_impl<T, N, I+1, integer_sequence<T, Vals..., I>>
+{ };
+
+} // end namespace __detail
+
+template <class T, T N>
+using make_integer_sequence = typename __detail::__make_int_seq_impl<T, N, 0, integer_sequence<T>>::type;
+
+template <size_t N>
+using make_index_sequence = typename __detail::__make_int_seq_impl<size_t, N, 0, integer_sequence<size_t>>::type;
+
+template <class... T>
+using index_sequence_for = make_index_sequence<sizeof...(T)>;
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+#endif
+
+// </editor-fold> end integer sequence (ugh...) }}}1
+//==============================================================================
+
+//==============================================================================
+// <editor-fold desc="standard trait aliases"> {{{1
+
+#if !defined(_MDSPAN_USE_STANDARD_TRAIT_ALIASES) || !_MDSPAN_USE_STANDARD_TRAIT_ALIASES
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+#define _MDSPAN_BACKPORT_TRAIT_ALIAS(TRAIT) \
+ template <class... Args> using TRAIT##_t = typename TRAIT<Args...>::type;
+
+_MDSPAN_BACKPORT_TRAIT_ALIAS(remove_cv)
+_MDSPAN_BACKPORT_TRAIT_ALIAS(remove_reference)
+
+template <bool _B, class _T=void>
+using enable_if_t = typename enable_if<_B, _T>::type;
+
+#undef _MDSPAN_BACKPORT_TRAIT_ALIAS
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
+#endif
+
+// </editor-fold> end standard trait aliases }}}1
+//==============================================================================
+
+#endif //MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_
diff --git a/ext/mdspan/include/experimental/__p0009_bits/type_list.hpp b/ext/mdspan/include/experimental/__p0009_bits/type_list.hpp
new file mode 100644
index 0000000..deca7c1
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/type_list.hpp
@@ -0,0 +1,87 @@
+//@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 "macros.hpp"
+
+#include "trait_backports.hpp" // make_index_sequence
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+
+//==============================================================================
+
+namespace detail {
+
+template <class... _Ts> struct __type_list { static constexpr auto __size = sizeof...(_Ts); };
+
+// Implementation of type_list at() that's heavily optimized for small typelists
+template <size_t, class> struct __type_at;
+template <size_t, class _Seq, class=std::make_index_sequence<_Seq::__size>> struct __type_at_large_impl;
+
+template <size_t _I, size_t _Idx, class _T>
+struct __type_at_entry { };
+
+template <class _Result>
+struct __type_at_assign_op_ignore_rest {
+ template <class _T>
+ __type_at_assign_op_ignore_rest<_Result> operator=(_T&&);
+ using type = _Result;
+};
+
+struct __type_at_assign_op_impl {
+ template <size_t _I, size_t _Idx, class _T>
+ __type_at_assign_op_impl operator=(__type_at_entry<_I, _Idx, _T>&&);
+ template <size_t _I, class _T>
+ __type_at_assign_op_ignore_rest<_T> operator=(__type_at_entry<_I, _I, _T>&&);
+};
+
+template <size_t _I, class... _Ts, size_t... _Idxs>
+struct __type_at_large_impl<_I, __type_list<_Ts...>, std::integer_sequence<size_t, _Idxs...>>
+ : decltype(
+ _MDSPAN_FOLD_ASSIGN_LEFT(__type_at_assign_op_impl{}, /* = ... = */ __type_at_entry<_I, _Idxs, _Ts>{})
+ )
+{ };
+
+template <size_t _I, class... _Ts>
+struct __type_at<_I, __type_list<_Ts...>>
+ : __type_at_large_impl<_I, __type_list<_Ts...>>
+{ };
+
+template <class _T0, class... _Ts>
+struct __type_at<0, __type_list<_T0, _Ts...>> {
+ using type = _T0;
+};
+
+template <class _T0, class _T1, class... _Ts>
+struct __type_at<1, __type_list<_T0, _T1, _Ts...>> {
+ using type = _T1;
+};
+
+template <class _T0, class _T1, class _T2, class... _Ts>
+struct __type_at<2, __type_list<_T0, _T1, _T2, _Ts...>> {
+ using type = _T2;
+};
+
+template <class _T0, class _T1, class _T2, class _T3, class... _Ts>
+struct __type_at<3, __type_list<_T0, _T1, _T2, _T3, _Ts...>> {
+ using type = _T3;
+};
+
+
+} // namespace detail
+
+//==============================================================================
+
+} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE
+
diff --git a/ext/mdspan/include/experimental/__p0009_bits/utility.hpp b/ext/mdspan/include/experimental/__p0009_bits/utility.hpp
new file mode 100644
index 0000000..a078eeb
--- /dev/null
+++ b/ext/mdspan/include/experimental/__p0009_bits/utility.hpp
@@ -0,0 +1,172 @@
+#pragma once
+
+#include <cstddef>
+#include <type_traits>
+#include <array>
+#include <utility>
+
+namespace MDSPAN_IMPL_STANDARD_NAMESPACE {
+namespace detail {
+
+// type alias used for rank-based tag dispatch
+//
+// this is used to enable alternatives to constexpr if when building for C++14
+//
+template <std::size_t N>
+using with_rank = std::integral_constant<std::size_t, N>;
+
+template <class I1, class I2>
+MDSPAN_INLINE_FUNCTION
+constexpr bool common_integral_compare(I1 x, I2 y)
+{
+ static_assert(std::is_integral<I1>::value &&
+ std::is_integral<I2>::value, "");
+
+ using I = std::common_type_t<I1, I2>;
+ return static_cast<I>(x) == static_cast<I>(y);
+}
+
+template <class T1, class T2, class F>
+MDSPAN_INLINE_FUNCTION
+constexpr bool rankwise_equal(with_rank<0>, const T1&, const T2&, F)
+{
+ return true;
+}
+
+template <std::size_t N, class T1, class T2, class F>
+MDSPAN_INLINE_FUNCTION
+constexpr bool rankwise_equal(with_rank<N>, const T1& x, const T2& y, F func)
+{
+ bool match = true;
+
+ for (std::size_t r = 0; r < N; r++) {
+ match = match && common_integral_compare(func(x, r), func(y, r));
+ }
+
+ return match;
+}
+
+constexpr struct
+{
+ template <class T, class I>
+ MDSPAN_INLINE_FUNCTION
+ constexpr auto operator()(const T& x, I i) const
+ {
+ return x.extent(i);
+ }
+} extent;
+
+constexpr struct
+{
+ template <class T, class I>
+ MDSPAN_INLINE_FUNCTION
+ constexpr auto operator()(const T& x, I i) const
+ {
+ return x.stride(i);
+ }
+} stride;
+
+// same as std::integral_constant but with __host__ __device__ annotations on
+// the implicit conversion function and the call operator
+template <class T, T v>
+struct integral_constant {
+ using value_type = T;
+ using type = integral_constant<T, v>;
+
+ static constexpr T value = v;
+
+ MDSPAN_INLINE_FUNCTION_DEFAULTED
+ constexpr integral_constant() = default;
+
+ // These interop functions work, because other than the value_type operator
+ // everything of std::integral_constant works on device (defaulted functions)
+ MDSPAN_FUNCTION
+ constexpr integral_constant(std::integral_constant<T,v>) {};
+
+ MDSPAN_FUNCTION constexpr operator std::integral_constant<T,v>() const noexcept {
+ return std::integral_constant<T,v>{};
+ }
+
+ MDSPAN_FUNCTION constexpr operator value_type() const noexcept {
+ return value;
+ }
+
+ MDSPAN_FUNCTION constexpr value_type operator()() const noexcept {
+ return value;
+ }
+};
+
+// The tuple implementation only comes in play when using capabilities
+// such as submdspan which require C++17 anyway
+#if MDSPAN_HAS_CXX_17
+template<class T, size_t Idx>
+struct tuple_member {
+ using type = T;
+ static constexpr size_t idx = Idx;
+ T val;
+ MDSPAN_FUNCTION constexpr T& get() { return val; }
+ MDSPAN_FUNCTION constexpr const T& get() const { return val; }
+};
+
+// A helper class which will be used via a fold expression to
+// select the type with the correct Idx in a pack of tuple_member
+template<size_t SearchIdx, size_t Idx, class T>
+struct tuple_idx_matcher {
+ using type = tuple_member<T, Idx>;
+ template<class Other>
+ MDSPAN_FUNCTION
+ constexpr auto operator | ([[maybe_unused]] Other v) const {
+ if constexpr (Idx == SearchIdx) { return *this; }
+ else { return v; }
+ }
+};
+
+template<class IdxSeq, class ... Elements>
+struct tuple_impl;
+
+template<size_t ... Idx, class ... Elements>
+struct tuple_impl<std::index_sequence<Idx...>, Elements...>: public tuple_member<Elements, Idx> ... {
+
+ MDSPAN_FUNCTION
+ constexpr tuple_impl(Elements ... vals):tuple_member<Elements, Idx>{vals}... {}
+
+ template<size_t N>
+ MDSPAN_FUNCTION
+ constexpr auto& get() {
+ using base_t = decltype((tuple_idx_matcher<N, Idx, Elements>() | ...) );
+ return base_t::type::get();
+ }
+ template<size_t N>
+ MDSPAN_FUNCTION
+ constexpr const auto& get() const {
+ using base_t = decltype((tuple_idx_matcher<N, Idx, Elements>() | ...) );
+ return base_t::type::get();
+ }
+};
+
+// A simple tuple-like class for representing slices internally and is compatible with device code
+// This doesn't support type access since we don't need it
+// This is not meant as an external API
+template<class ... Elements>
+struct tuple: public tuple_impl<decltype(std::make_index_sequence<sizeof...(Elements)>()), Elements...> {
+ MDSPAN_FUNCTION
+ constexpr tuple(Elements ... vals):tuple_impl<decltype(std::make_index_sequence<sizeof...(Elements)>()), Elements ...>(vals ...) {}
+};
+
+template<size_t Idx, class ... Args>
+MDSPAN_FUNCTION
+constexpr auto& get(tuple<Args...>& vals) { return vals.template get<Idx>(); }
+
+template<size_t Idx, class ... Args>
+MDSPAN_FUNCTION
+constexpr const auto& get(const tuple<Args...>& vals) { return vals.template get<Idx>(); }
+
+template<class ... Elements>
+tuple(Elements ...) -> tuple<Elements...>;
+#endif
+} // namespace detail
+
+constexpr struct mdspan_non_standard_tag {
+} mdspan_non_standard;
+
+} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE