├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake └── MDArrayConfig.cmake.in ├── compilation_tests ├── CMakeLists.txt ├── ctest_common.hpp └── ctest_constructor_sfinae.cpp ├── examples ├── CMakeLists.txt ├── dot_product │ ├── CMakeLists.txt │ └── dot_product.cpp └── pmr_usage │ ├── CMakeLists.txt │ └── pmr_usage.cpp ├── include └── experimental │ ├── __p1684_bits │ ├── basic_mdarray.hpp │ ├── const_wrapped_accessor_policy.hpp │ └── container_policy_basic.hpp │ └── mdarray ├── make_single_header.py └── tests └── CMakeLists.txt /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.12) 3 | project(MDArray 4 | VERSION 0.0.1 5 | LANGUAGES CXX 6 | ) 7 | 8 | ################################################################################ 9 | 10 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 11 | 12 | ################################################################################ 13 | 14 | option(MDARRAY_ENABLE_TESTS "Enable tests." Off) 15 | option(MDARRAY_ENABLE_EXAMPLES "Build examples." Off) 16 | #option(MDARRAY_ENABLE_BENCHMARKS "Enable benchmarks." Off) 17 | #option(MDARRAY_ENABLE_COMP_BENCH "Enable compilation benchmarks." Off) 18 | 19 | # Option to override which C++ standard to use 20 | set(MDARRAY_CXX_STANDARD DETECT CACHE STRING "Override the default CXX_STANDARD to compile with.") 21 | set_property(CACHE MDARRAY_CXX_STANDARD PROPERTY STRINGS DETECT 11 14 17 20) 22 | 23 | option(MDARRAY_ENABLE_CONCEPTS "Try to enable concepts support by giving extra flags." On) 24 | 25 | ################################################################################ 26 | 27 | # Decide on the standard to use 28 | if(MDARRAY_CXX_STANDARD STREQUAL "17") 29 | if("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 30 | message(STATUS "Using C++17 standard") 31 | set(CMAKE_CXX_STANDARD 17) 32 | else() 33 | message(FATAL_ERROR "Requested MDARRAY_CXX_STANDARD \"17\" not supported by provided C++ compiler") 34 | endif() 35 | elseif(MDARRAY_CXX_STANDARD STREQUAL "14") 36 | if("cxx_std_14" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 37 | message(STATUS "Using C++14 standard") 38 | set(CMAKE_CXX_STANDARD 14) 39 | else() 40 | message(FATAL_ERROR "Requested MDARRAY_CXX_STANDARD \"14\" not supported by provided C++ compiler") 41 | endif() 42 | elseif(MDARRAY_CXX_STANDARD STREQUAL "11") 43 | message(STATUS "Using C++11 standard") 44 | set(CMAKE_CXX_STANDARD 11) 45 | elseif(MDARRAY_CXX_STANDARD STREQUAL "20") 46 | if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 47 | message(STATUS "Using C++20 standard") 48 | set(CMAKE_CXX_STANDARD 20) 49 | else() 50 | message(FATAL_ERROR "Requested MDARRAY_CXX_STANDARD \"20\" not supported by provided C++ compiler") 51 | endif() 52 | else() 53 | if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 54 | set(CMAKE_CXX_STANDARD 20) 55 | message(STATUS "Detected support for C++20 standard") 56 | elseif("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 57 | set(CMAKE_CXX_STANDARD 17) 58 | message(STATUS "Detected support for C++17 standard") 59 | elseif("cxx_std_14" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 60 | set(CMAKE_CXX_STANDARD 14) 61 | message(STATUS "Detected support for C++14 standard") 62 | elseif("cxx_std_11" IN_LIST CMAKE_CXX_COMPILE_FEATURES) 63 | set(CMAKE_CXX_STANDARD 11) 64 | message(STATUS "Newest supported C++ standard detected is C++11.") 65 | else() 66 | message(FATAL_ERROR "Cannot detect CXX_STANDARD of C++11 or newer.") 67 | endif() 68 | endif() 69 | 70 | ################################################################################ 71 | 72 | if(MDARRAY_ENABLE_CONCEPTS) 73 | if(CMAKE_CXX_STANDARD STREQUAL "20") 74 | include(CheckCXXCompilerFlag) 75 | CHECK_CXX_COMPILER_FLAG("-fconcepts" COMPILER_SUPPORTS_FCONCEPTS) 76 | if(COMPILER_SUPPORTS_FCONCEPTS) 77 | message(STATUS "Using \"-fconcepts\" to enable concepts support") 78 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fconcepts") 79 | else() 80 | CHECK_CXX_COMPILER_FLAG("-fconcepts-ts" COMPILER_SUPPORTS_FCONCEPTS_TS) 81 | if(COMPILER_SUPPORTS_FCONCEPTS) 82 | message(STATUS "Using \"-fconcepts-ts\" to enable concepts support") 83 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fconcepts-ts") 84 | endif() 85 | endif() 86 | # Otherwise, it's possible that the compiler supports concepts without flags, 87 | # but if it doesn't, they just won't be used, which is fine 88 | endif() 89 | endif() 90 | 91 | ################################################################################ 92 | 93 | find_package(mdspan REQUIRED) 94 | if(mdspan_FOUND) 95 | message(STATUS "Found mdspan in ${mdspan_DIR}") 96 | endif() 97 | 98 | ################################################################################ 99 | 100 | add_library(mdarray INTERFACE) 101 | add_library(std::mdarray ALIAS mdarray) 102 | 103 | target_link_libraries(mdarray INTERFACE std::mdspan) 104 | 105 | target_include_directories(mdarray INTERFACE 106 | $ 107 | $ 108 | ) 109 | 110 | ################################################################################ 111 | 112 | install(TARGETS mdarray EXPORT mdarrayTargets 113 | INCLUDES DESTINATION include 114 | ) 115 | 116 | install(EXPORT mdarrayTargets 117 | FILE mdarrayTargets.cmake 118 | NAMESPACE std:: 119 | DESTINATION cmake 120 | ) 121 | 122 | export(TARGETS mdarray 123 | NAMESPACE std:: 124 | FILE mdarrayTargets.cmake 125 | ) 126 | 127 | install(DIRECTORY include/experimental DESTINATION include) 128 | 129 | include(CMakePackageConfigHelpers) 130 | configure_package_config_file(cmake/MDArrayConfig.cmake.in 131 | ${CMAKE_CURRENT_BINARY_DIR}/MDArrayConfig.cmake 132 | INSTALL_DESTINATION cmake 133 | ) 134 | write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/MDArrayConfigVersion.cmake 135 | COMPATIBILITY SameMajorVersion 136 | ) 137 | 138 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MDArrayConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/MDArrayConfigVersion.cmake 139 | DESTINATION cmake 140 | ) 141 | 142 | ################################################################################ 143 | 144 | if(MDARRAY_ENABLE_TESTS) 145 | enable_testing() 146 | add_subdirectory(tests) 147 | add_subdirectory(compilation_tests) 148 | endif() 149 | 150 | if(MDARRAY_ENABLE_EXAMPLES) 151 | add_subdirectory(examples) 152 | endif() 153 | 154 | #if(MDARRAY_ENABLE_BENCHMARKS) 155 | # add_subdirectory(benchmarks) 156 | #endif() 157 | 158 | #if(MDARRAY_ENABLE_COMP_BENCH) 159 | # add_subdirectory(comp_bench) 160 | #endif() 161 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | //@HEADER 2 | // ************************************************************************ 3 | // 4 | // Kokkos v. 2.0 5 | // Copyright (2014) Sandia Corporation 6 | // 7 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 8 | // the U.S. Government retains certain rights in this software. 9 | // 10 | // Kokkos is licensed under 3-clause BSD terms of use: 11 | // 12 | // Redistribution and use in source and binary forms, with or without 13 | // modification, are permitted provided that the following conditions are 14 | // met: 15 | // 16 | // 1. Redistributions of source code must retain the above copyright 17 | // notice, this list of conditions and the following disclaimer. 18 | // 19 | // 2. Redistributions in binary form must reproduce the above copyright 20 | // notice, this list of conditions and the following disclaimer in the 21 | // documentation and/or other materials provided with the distribution. 22 | // 23 | // 3. Neither the name of the Corporation nor the names of the 24 | // contributors may be used to endorse or promote products derived from 25 | // this software without specific prior written permission. 26 | // 27 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 28 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 31 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | // 39 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 40 | // 41 | // ************************************************************************ 42 | //@HEADER 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repo is *DEPRECATED*. 2 | It was an attempt of an implementation of MDArray R0. 3 | We added a new version based on R1 in the mdspan repo https://github.com/kokkos/mdspan. 4 | -------------------------------------------------------------------------------- /cmake/MDArrayConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/mdarrayTargets.cmake") 4 | -------------------------------------------------------------------------------- /compilation_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | macro(add_compilation_test name) 3 | add_executable(${name} ${name}.cpp) 4 | target_link_libraries(${name} mdarray) 5 | endmacro() 6 | 7 | add_compilation_test(ctest_constructor_sfinae) 8 | 9 | -------------------------------------------------------------------------------- /compilation_tests/ctest_common.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #include 45 | 46 | #include 47 | 48 | #pragma once 49 | 50 | #define MDSPAN_STATIC_TEST(...) \ 51 | static_assert(__VA_ARGS__, "MDSpan compile time test failed at " __FILE__ ":" MDSPAN_PP_STRINGIFY(__LINE__)) 52 | 53 | 54 | // All tests need a main so that they'll link 55 | int main() { } 56 | -------------------------------------------------------------------------------- /compilation_tests/ctest_constructor_sfinae.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #include "ctest_common.hpp" 45 | 46 | #include 47 | 48 | #include 49 | 50 | namespace stdex = std::experimental; 51 | 52 | //============================================================================== 53 | // {{{1 54 | 55 | MDSPAN_STATIC_TEST( 56 | std::is_constructible< 57 | stdex::mdarray, 58 | int 59 | >::value 60 | ); 61 | 62 | MDSPAN_STATIC_TEST( 63 | std::is_constructible< 64 | stdex::mdarray, 65 | unsigned, int 66 | >::value 67 | ); 68 | 69 | // end Test allowed pointer + extents ctors }}}1 70 | //============================================================================== 71 | 72 | 73 | //============================================================================== 74 | // {{{1 75 | 76 | MDSPAN_STATIC_TEST( 77 | !std::is_constructible< 78 | stdex::mdarray, 79 | double*, int 80 | >::value 81 | ); 82 | 83 | MDSPAN_STATIC_TEST( 84 | !std::is_constructible< 85 | stdex::mdarray, 86 | int* 87 | >::value 88 | ); 89 | 90 | // end Test forbidden pointer + extents ctors }}}1 91 | //============================================================================== -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | function(mdarray_add_example EXENAME) 3 | add_executable(${EXENAME} ${EXENAME}.cpp) 4 | target_link_libraries(${EXENAME} mdarray) 5 | endfunction(mdarray_add_example) 6 | 7 | add_subdirectory(dot_product) 8 | add_subdirectory(pmr_usage) -------------------------------------------------------------------------------- /examples/dot_product/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | mdarray_add_example(dot_product) 2 | -------------------------------------------------------------------------------- /examples/dot_product/dot_product.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace stdex = std::experimental; 9 | 10 | //================================================================================ 11 | 12 | template < 13 | class T, 14 | class ExtsA, class LayA, class AccA, 15 | class ExtsB, class LayB, class AccB 16 | > 17 | T dot_product( 18 | stdex::basic_mdarray const& a, 19 | stdex::basic_mdarray const& b 20 | ) //requires ExtsA::rank() == ExtsB::rank() && ExtsA::rank() == 2 21 | { 22 | T result = 0; 23 | for(int i = 0; i < a.extent(0); ++i) { 24 | for(int j = 0; j < a.extent(1); ++j) { 25 | result += a(i, j) * b(i, j); 26 | } 27 | } 28 | return result; 29 | } 30 | 31 | //================================================================================ 32 | 33 | template < 34 | class T, 35 | class ExtsA, class LayA, class AccA 36 | > 37 | void fill_in_order( 38 | stdex::basic_mdarray& a 39 | ) // requires ExtsA::rank() == 2 40 | { 41 | T count = 0; 42 | for(int i = 0; i < a.extent(0); ++i) { 43 | for(int j = 0; j < a.extent(1); ++j) { 44 | a(i, j) = count++; 45 | } 46 | } 47 | } 48 | 49 | //================================================================================ 50 | 51 | constexpr int rows = 3; 52 | constexpr int cols = 3; 53 | 54 | //================================================================================ 55 | 56 | int main() { 57 | { 58 | using array_2d_dynamic = stdex::basic_mdarray, stdex::layout_right>; 59 | using array_2d_dynamic_left = stdex::basic_mdarray, stdex::layout_left>; 60 | 61 | auto a = array_2d_dynamic(rows, cols); 62 | auto b = array_2d_dynamic_left(rows, cols); 63 | auto c = array_2d_dynamic(std::allocator{}); 64 | auto d = array_2d_dynamic(3, 4, std::allocator{}); 65 | array_2d_dynamic e{d, std::allocator{}}; 66 | array_2d_dynamic f{std::move(e), std::allocator{}}; 67 | 68 | fill_in_order(a); 69 | fill_in_order(b); 70 | 71 | std::cout << dot_product(a, b) << std::endl; 72 | } 73 | 74 | { 75 | using array_2d_10_10 = stdex::basic_mdarray, stdex::layout_right>; 76 | using array_2d_10_10_left = stdex::basic_mdarray, stdex::layout_right>; 77 | 78 | auto a = array_2d_10_10(); 79 | auto b = array_2d_10_10_left(); 80 | fill_in_order(a); 81 | fill_in_order(b); 82 | 83 | std::cout << dot_product(a, b) << std::endl; 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /examples/pmr_usage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | mdarray_add_example(pmr_usage) 2 | -------------------------------------------------------------------------------- /examples/pmr_usage/pmr_usage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace stdex = std::experimental; 8 | 9 | #ifdef __cpp_lib_memory_resource 10 | #include 11 | 12 | 13 | //For testing, prints allocs and deallocs to cout 14 | struct ChatterResource : std::pmr::memory_resource{ 15 | 16 | ChatterResource() = default; 17 | 18 | ChatterResource(std::pmr::memory_resource* upstream): upstream(upstream){} 19 | 20 | ChatterResource(const ChatterResource&) = delete; 21 | 22 | ChatterResource(ChatterResource&&) = delete; 23 | 24 | ChatterResource& operator=(const ChatterResource&) = delete; 25 | 26 | ChatterResource& operator=(ChatterResource&&) = delete; 27 | 28 | private: 29 | 30 | void* do_allocate( std::size_t bytes, std::size_t alignment ) override{ 31 | 32 | std::cout << "Allocation - size: " << bytes << ", alignment: " << alignment << std::endl; 33 | 34 | return upstream->allocate(bytes, alignment); 35 | //else return new chunk 36 | } 37 | 38 | void do_deallocate( void* p, std::size_t bytes, std::size_t alignment ) override{ 39 | 40 | std::cout << "Deallocation - size: " << bytes << ", alignment: " << alignment << std::endl; 41 | 42 | upstream->deallocate(p, bytes, alignment); 43 | } 44 | 45 | bool do_is_equal( const std::pmr::memory_resource& other ) const noexcept override{ 46 | return this == &other; 47 | }; 48 | 49 | std::pmr::memory_resource* upstream = std::pmr::get_default_resource(); 50 | }; 51 | 52 | 53 | int main(){ 54 | 55 | using array_2d_pmr_dynamic = stdex::basic_mdarray, stdex::layout_right, stdex::vector_container_policy>>; 56 | 57 | ChatterResource allocation_logger; 58 | constexpr bool test = std::uses_allocator_v>; 59 | 60 | array_2d_pmr_dynamic mdarray{3,3, &allocation_logger}; 61 | array_2d_pmr_dynamic anotherMdarray{3,3}; 62 | 63 | std::pmr::vector top_container{&allocation_logger}; 64 | top_container.reserve(4); 65 | 66 | top_container.emplace_back(3,3); 67 | top_container.emplace_back(mdarray.mapping()); 68 | top_container.emplace_back(mdarray.mapping(), mdarray.container_policy()); 69 | top_container.push_back({mdarray}); 70 | 71 | } 72 | 73 | 74 | #endif -------------------------------------------------------------------------------- /include/experimental/__p1684_bits/basic_mdarray.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #ifndef MDARRAY_INCLUDE_EXPERIMENTAL_BITS_BASIC_MDARRAY_HPP_ 45 | #define MDARRAY_INCLUDE_EXPERIMENTAL_BITS_BASIC_MDARRAY_HPP_ 46 | 47 | #include "container_policy_basic.hpp" 48 | #include "const_wrapped_accessor_policy.hpp" 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | namespace std { 57 | namespace experimental { 58 | inline namespace __mdarray_version_0 { 59 | 60 | namespace __detail { 61 | 62 | template 63 | struct _basic_mdarray_crtp_helper; 64 | 65 | // Workaround for not being able to give explicit template parameters to lambdas in older 66 | // versions of C++, thus making expanding parameter packs with indices more difficult 67 | template 68 | struct _basic_mdarray_crtp_helper< 69 | Derived, std::index_sequence 70 | > 71 | { 72 | protected: 73 | MDSPAN_FORCE_INLINE_FUNCTION Derived& __self() noexcept { return *static_cast(this); } 74 | MDSPAN_FORCE_INLINE_FUNCTION Derived const& __self() const noexcept { return *static_cast(this); } 75 | MDSPAN_FORCE_INLINE_FUNCTION constexpr size_t __size() const noexcept { 76 | return _MDSPAN_FOLD_TIMES_RIGHT((__self().map_.extents().template __extent()), /* * ... * */ 1); 77 | } 78 | template 79 | MDSPAN_FORCE_INLINE_FUNCTION constexpr ReferenceType __callop(const array& indices) noexcept { 80 | return __self().cp_.access(__self().c_, __self().map_(indices[ExtIdxs]...)); 81 | } 82 | template 83 | MDSPAN_FORCE_INLINE_FUNCTION constexpr ReferenceType __callop(const array& indices) const noexcept { 84 | return __self().cp_.access(__self().c_, __self().map_(indices[ExtIdxs]...)); 85 | } 86 | }; 87 | 88 | template 89 | using __policy_allocator_t = typename ContainerPolicy::container_type::allocator_type; 90 | 91 | template 92 | struct __has_allocator : false_type {}; 93 | 94 | // Me: Hey mom? Can we have C++17's std::void_t? 95 | // Mom: No honey, we have void_t at home. 96 | template 97 | struct __void_at_home{ 98 | using type = void; 99 | }; 100 | 101 | // Indirection in case CWG issue 1558 resolution is not supported. 102 | template 103 | using __void_t_at_home = typename __void_at_home::type; 104 | 105 | // TODO: Make this C++14 friendly 106 | template 107 | struct __has_allocator>> : true_type {}; 108 | 109 | template 110 | constexpr bool __has_allocator_v = __has_allocator::value; 111 | 112 | template 115 | auto __uses_allocator_helper(const Alloc& alloc, Args&&... args) 116 | noexcept(noexcept(Container{allocator_arg, alloc, std::forward(args)...}))-> 117 | decltype(Container{allocator_arg, alloc, std::forward(args)...}){ 118 | 119 | return Container{allocator_arg, alloc, std::forward(args)...}; 120 | 121 | } 122 | 123 | template 126 | auto __uses_allocator_helper(const Alloc& alloc, Args&&... args) 127 | noexcept(noexcept(Container{std::forward(args)..., alloc}))-> 128 | decltype(Container{std::forward(args)..., alloc}){ 129 | 130 | return Container{std::forward(args)..., alloc}; 131 | 132 | } 133 | 134 | // can't use type_identity for this pre C++20 135 | template 136 | struct __nondeduced{ 137 | using type = Type; 138 | }; 139 | 140 | 141 | template 142 | using __nondeduced_t = typename __nondeduced::type; 143 | 144 | template 145 | struct __make_dependent{ 146 | using type = Independent; 147 | }; 148 | 149 | template 150 | using __make_dependent_t = typename __make_dependent::type; 151 | 152 | template 153 | struct __type_list{}; 154 | 155 | template 156 | struct __type_pop_back_imp; 157 | 158 | 159 | template 160 | struct __type_pop_back_imp, NextType, RemainingTypes...>{ 161 | static_assert(sizeof...(RemainingTypes)!=0); 162 | using type = typename __type_pop_back_imp< 163 | sizeof...(RemainingTypes)!=1, 164 | __type_list, 165 | RemainingTypes... 166 | >::type; 167 | }; 168 | 169 | template 170 | struct __type_pop_back_imp, LastType>{ 171 | using type = __type_pop_back_imp; 172 | using list = __type_list; 173 | using last = LastType; 174 | }; 175 | 176 | template 177 | struct __type_pop_back{ 178 | using type = typename __type_pop_back_imp<(sizeof...(Types)>1),__type_list<>, Types...>::type::list; 179 | }; 180 | 181 | // Avoid hard compile errors 182 | template<> 183 | struct __type_pop_back<>{ 184 | using type = __type_list<>; 185 | }; 186 | 187 | template 188 | using __type_pop_back_t = typename __type_pop_back< Types...>::type; 189 | 190 | template 191 | struct __get_last{ 192 | using type = typename __type_pop_back_imp<(sizeof...(Types)>1),__type_list<>, Types...>::type::last; 193 | }; 194 | 195 | template 196 | using __get_last_t = typename __get_last< Types...>::type; 197 | 198 | using test = __type_pop_back_t; 199 | using other_test = __get_last_t; 200 | 201 | template 202 | struct __can_make_mapping { 203 | static constexpr bool value = _MDSPAN_FOLD_AND((is_convertible::value)) && 204 | (sizeof...(IndexTypes) == MDArray::extents_type::rank_dynamic()) && 205 | is_constructible::value; 206 | }; 207 | 208 | 209 | template 210 | using __is_mdarray_alloc_t = is_same::type>::type, __policy_allocator_t>; 211 | 212 | template 213 | using __to_const_ref_t = const typename remove_cv::type>::type&; 214 | 215 | template 216 | struct __map_and_alloc{ 217 | Mapping first; 218 | const Alloc& second; 219 | }; 220 | 221 | template::value, bool>::type = true, 225 | typename enable_if<(__is_mdarray_alloc_t{} 226 | || is_convertible>::value), 227 | bool>::type = true 228 | > 229 | pair> __resolve_pack_overload_imp(Types&&... args, Last&& last){ 230 | return pair>{ typename MDArray::extents_type{forward(args)...}, last}; 231 | } 232 | 233 | template::value, bool>::type = true 237 | > 238 | typename MDArray::mapping_type __resolve_pack_overload_imp(Types&&... args, Last&& last){ 239 | return typename MDArray::mapping_type{ typename MDArray::extents_type{forward(args)..., forward(last)}}; 240 | } 241 | 242 | template 243 | auto __resolve_pack_split_first(__type_list, ActualPack&&... args)->decltype(__resolve_pack_overload_imp(forward(args)...)){ 244 | return __resolve_pack_overload_imp(forward(args)...); 245 | } 246 | 247 | template 248 | auto __resolve_pack_overload(Types&&... args)->decltype(__resolve_pack_split_first(__type_pop_back_t{}, forward(args)...)){ 249 | return __resolve_pack_split_first(__type_pop_back_t{}, forward(args)...); 250 | } 251 | 252 | 253 | template 254 | using __attempt_resolve_t = decltype(__resolve_pack_overload(declval()...)); 255 | 256 | } // end namespace __detail 257 | 258 | template < 259 | class ElementType, 260 | class Extents, 261 | class LayoutPolicy=layout_right, 262 | class ContainerPolicy=typename __detail::__container_policy_select::type 263 | > 264 | class basic_mdarray; 265 | 266 | template < 267 | class ElementType, 268 | size_t... Exts, 269 | class LayoutPolicy, 270 | class ContainerPolicy 271 | > 272 | class basic_mdarray< 273 | ElementType, std::experimental::extents, 274 | LayoutPolicy, ContainerPolicy 275 | > : __detail::_basic_mdarray_crtp_helper< 276 | basic_mdarray, LayoutPolicy, ContainerPolicy>, 277 | make_index_sequence 278 | > 279 | { 280 | private: 281 | 282 | using __crtp_base_t = __detail::_basic_mdarray_crtp_helper< 283 | basic_mdarray, LayoutPolicy, ContainerPolicy>, 284 | make_index_sequence 285 | >; 286 | 287 | public: 288 | using element_type = ElementType; 289 | using extents_type = std::experimental::extents; 290 | using layout_type = LayoutPolicy; 291 | using mapping_type = typename layout_type::template mapping; // TODO @proposal-bug typo in synopsis 292 | using value_type = remove_cv_t; 293 | using index_type = size_t; 294 | using difference_type = size_t; 295 | using container_policy_type = ContainerPolicy; 296 | using container_type = typename container_policy_type::container_type; 297 | using pointer = typename container_policy_type::pointer; // TODO @proposal-bug this is misspelled in the synopsis 298 | using const_pointer = typename container_policy_type::const_pointer; 299 | using reference = typename container_policy_type::reference; 300 | using const_reference = typename container_policy_type::const_reference; 301 | using view_type = 302 | mdspan; 303 | using const_view_type = 304 | mdspan 306 | >; 307 | 308 | MDSPAN_INLINE_FUNCTION_DEFAULTED 309 | constexpr basic_mdarray() noexcept(std::is_nothrow_default_constructible::value) = default; 310 | MDSPAN_INLINE_FUNCTION_DEFAULTED 311 | constexpr basic_mdarray(basic_mdarray const&) noexcept(std::is_nothrow_copy_constructible::value) = default; 312 | MDSPAN_INLINE_FUNCTION_DEFAULTED 313 | constexpr basic_mdarray(basic_mdarray&&) noexcept(std::is_nothrow_move_constructible::value) = default; 314 | MDSPAN_INLINE_FUNCTION_DEFAULTED 315 | _MDSPAN_CONSTEXPR_14_DEFAULTED basic_mdarray& operator=(basic_mdarray&&) noexcept(std::is_nothrow_move_assignable::value) = default; 316 | MDSPAN_INLINE_FUNCTION_DEFAULTED 317 | _MDSPAN_CONSTEXPR_14_DEFAULTED basic_mdarray& operator=(basic_mdarray const&) noexcept(std::is_nothrow_copy_assignable::value) = default; 318 | 319 | MDSPAN_INLINE_FUNCTION_DEFAULTED 320 | ~basic_mdarray() noexcept(std::is_nothrow_destructible::value) = default; 321 | 322 | // TODO noexcept clause 323 | template< 324 | class... IndexType, 325 | class = enable_if_t::value, bool>, // 326 | class = __detail::__attempt_resolve_t 327 | // TODO constraint on create without allocator being available, if we don't change to CP owning the allocator 328 | > 329 | MDSPAN_INLINE_FUNCTION 330 | constexpr explicit 331 | basic_mdarray(IndexType... dynamic_extents) 332 | : basic_mdarray(__detail::__resolve_pack_overload(dynamic_extents...)) 333 | // This resolves to either basic_mdarray(mapping_type&&) or the private basic_mdarray(pair) 334 | { } 335 | 336 | // TODO noexcept specification 337 | MDSPAN_FUNCTION_REQUIRES( 338 | (MDSPAN_INLINE_FUNCTION constexpr explicit), 339 | basic_mdarray, (const mapping_type& m), noexcept, 340 | /* requires */ (_MDSPAN_TRAIT(is_default_constructible, container_policy_type)) 341 | ) : cp_(), 342 | map_(m), 343 | c_(cp_.create(map_.required_span_size())) 344 | { } 345 | 346 | // TODO noexcept specification 347 | // TODO @proposal-bug add this to the proposal? 348 | MDSPAN_FUNCTION_REQUIRES( 349 | (MDSPAN_INLINE_FUNCTION constexpr explicit), 350 | basic_mdarray, (mapping_type&& m), noexcept, 351 | /* requires */ (_MDSPAN_TRAIT(is_default_constructible, container_policy_type)) 352 | ) : cp_(), 353 | map_(std::move(m)), 354 | c_(cp_.create(map_.required_span_size())) 355 | { } 356 | 357 | MDSPAN_INLINE_FUNCTION 358 | constexpr 359 | basic_mdarray(mapping_type const& m, container_policy_type const& cp) 360 | : cp_(cp), 361 | map_(m), 362 | c_(cp_.create(map_.required_span_size())) 363 | { } 364 | 365 | // TODO noexcept specification 366 | MDSPAN_TEMPLATE_REQUIRES( 367 | class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherCP, 368 | /* requires */ ( 369 | _MDSPAN_TRAIT(is_convertible, typename OtherLayoutPolicy::template mapping, mapping_type) && 370 | _MDSPAN_TRAIT(is_constructible, container_policy_type, OtherCP const&) && 371 | _MDSPAN_TRAIT(is_constructible, container_type, typename OtherCP::container_type const&) && 372 | _MDSPAN_TRAIT(is_convertible, OtherExtents, extents_type) 373 | ) 374 | ) 375 | constexpr basic_mdarray( 376 | basic_mdarray const& other 377 | ) noexcept 378 | : cp_(other.cp_), 379 | map_(other.map_), 380 | c_(other.c_) 381 | { } 382 | 383 | // TODO noexcept specification 384 | MDSPAN_TEMPLATE_REQUIRES( 385 | class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherCP, 386 | /* requires */ ( 387 | _MDSPAN_TRAIT(is_convertible, typename OtherLayoutPolicy::template mapping, mapping_type) && 388 | _MDSPAN_TRAIT(is_constructible, container_policy_type, OtherCP&&) && 389 | _MDSPAN_TRAIT(is_constructible, container_type, typename OtherCP::container_type&&) && 390 | _MDSPAN_TRAIT(is_convertible, OtherExtents, extents_type) 391 | ) 392 | ) 393 | constexpr basic_mdarray( 394 | basic_mdarray&& other 395 | ) noexcept 396 | : cp_(std::move(other.cp_)), 397 | map_(std::move(other.map_)), 398 | c_(std::move(other.c_)) 399 | { } 400 | 401 | //========================================================================== 402 | // Allocator Aware Constructors 403 | 404 | //Pretty sure I need to invoke raw SFINAE here 405 | 406 | template< 407 | class Dummy = void, 408 | class Alloc = __detail::__policy_allocator_t::type> 409 | > 410 | constexpr explicit basic_mdarray(const typename __detail::__nondeduced::type& alloc) noexcept 411 | : cp_(), 412 | map_(), 413 | c_(cp_.create(map_.required_span_size(), alloc)) 414 | { } 415 | 416 | private: 417 | template 418 | struct nothrow_alloc_copy{ 419 | static constexpr bool value = is_nothrow_copy_constructible::value 420 | && is_nothrow_copy_constructible::value 421 | && noexcept(__detail::__uses_allocator_helper(declval(), declval())); 422 | }; 423 | public: 424 | 425 | template< 426 | class Dummy = void, 427 | class Alloc = __detail::__policy_allocator_t::type> 428 | > 429 | constexpr explicit basic_mdarray(const basic_mdarray& other, const typename __detail::__nondeduced::type& alloc) noexcept(nothrow_alloc_copy::value) 430 | : cp_(), 431 | map_(), 432 | c_(__detail::__uses_allocator_helper(alloc, other.c_)) 433 | { } 434 | 435 | private: 436 | template 437 | struct nothrow_alloc_move{ 438 | static constexpr bool value = is_nothrow_move_constructible::value 439 | && is_nothrow_move_constructible::value 440 | && noexcept(__detail::__uses_allocator_helper(declval(), declval())); 441 | }; 442 | 443 | public: 444 | 445 | template< 446 | class Dummy = void, 447 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 448 | > 449 | constexpr explicit basic_mdarray(basic_mdarray&& other, const __detail::__nondeduced_t& alloc) noexcept(nothrow_alloc_move::value) 450 | : cp_(std::move(other.cp_)), 451 | map_(std::move(other.map_)), 452 | c_(__detail::__uses_allocator_helper(alloc, std::move(other.c_))) 453 | { } 454 | 455 | // TODO noexcept specification 456 | template< 457 | class Dummy = void, 458 | class = typename enable_if>::value, bool>::type, 459 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 460 | > 461 | MDSPAN_INLINE_FUNCTION constexpr explicit 462 | basic_mdarray(const mapping_type& m, const __detail::__nondeduced_t& alloc) noexcept 463 | : cp_(), 464 | map_(m), 465 | c_(cp_.create(map_.required_span_size())) 466 | { } 467 | 468 | template< 469 | class Dummy = void, 470 | class = typename enable_if>::value, bool>::type, 471 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 472 | > 473 | MDSPAN_INLINE_FUNCTION constexpr explicit 474 | basic_mdarray(mapping_type&& m, const __detail::__nondeduced_t& alloc) noexcept 475 | : cp_(), 476 | map_(std::move(m)), 477 | c_(cp_.create(map_.required_span_size(), alloc)) 478 | { } 479 | 480 | private: 481 | template< 482 | class Dummy = void, 483 | class = typename enable_if>::value, bool>::type, 484 | class Alloc, 485 | class DependantContainerPolicy = __detail::__make_dependent_t, 486 | class = typename enable_if, Alloc>{} 487 | || is_convertible>::value, 488 | bool>::type 489 | > 490 | MDSPAN_INLINE_FUNCTION constexpr explicit 491 | basic_mdarray(pair mapping_and_alloc) noexcept 492 | : cp_(), 493 | map_(std::move(mapping_and_alloc.first)), 494 | c_(cp_.create(map_.required_span_size(), mapping_and_alloc.second)) 495 | { } 496 | 497 | public: 498 | template< 499 | class Dummy = void, 500 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 501 | > 502 | MDSPAN_INLINE_FUNCTION constexpr 503 | basic_mdarray(mapping_type const& m, container_policy_type const& cp, const __detail::__nondeduced_t& alloc) 504 | : cp_(cp), 505 | map_(m), 506 | c_(cp_.create(map_.required_span_size(), alloc)) 507 | { } 508 | 509 | private: 510 | 511 | template 512 | struct can_deduce_copy{ 513 | static constexpr bool value = is_convertible, mapping_type>::value 514 | && is_constructible::value 515 | && is_constructible::value 516 | && is_convertible::value; 517 | }; 518 | 519 | public: 520 | 521 | // TODO noexcept specification 522 | template< 523 | class OtherElementType, 524 | class OtherExtents, 525 | class OtherLayoutPolicy, 526 | class OtherCP, 527 | enable_if::value, bool> = true, 528 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 529 | > 530 | constexpr basic_mdarray( 531 | basic_mdarray const& other, const __detail::__nondeduced_t& alloc 532 | ) noexcept 533 | : cp_(other.cp_), 534 | map_(other.map_), 535 | c_(__detail::__uses_allocator_helper(alloc, other.c_)) 536 | { } 537 | 538 | private: 539 | 540 | template 541 | struct can_deduce_move{ 542 | static constexpr bool value = is_convertible, mapping_type>::value 543 | && is_constructible::value 544 | && is_constructible::value 545 | && is_convertible::value; 546 | }; 547 | 548 | public: 549 | 550 | // TODO noexcept specification 551 | template< 552 | class OtherElementType, 553 | class OtherExtents, 554 | class OtherLayoutPolicy, 555 | class OtherCP, 556 | enable_if::value, bool> = true, 557 | class Alloc = __detail::__policy_allocator_t<__detail::__make_dependent_t> 558 | > 559 | constexpr basic_mdarray( 560 | basic_mdarray&& other, const __detail::__nondeduced_t& alloc 561 | ) noexcept 562 | : cp_(std::move(other.cp_)), 563 | map_(std::move(other.map_)), 564 | c_(__detail::__uses_allocator_helper(alloc, std::move(other.c_))) 565 | { } 566 | 567 | 568 | //========================================================================== 569 | 570 | // TODO noexcept specification 571 | MDSPAN_TEMPLATE_REQUIRES( 572 | class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherCP, 573 | /* requires */ ( 574 | _MDSPAN_TRAIT(is_convertible, typename OtherLayoutPolicy::template mapping, mapping_type) && 575 | _MDSPAN_TRAIT(is_assignable, container_policy_type, OtherCP const&) && 576 | _MDSPAN_TRAIT(is_assignable, container_type, typename OtherCP::container_type const&) && 577 | _MDSPAN_TRAIT(is_convertible, OtherExtents, extents_type) 578 | ) 579 | ) 580 | _MDSPAN_CONSTEXPR_14 basic_mdarray& operator=( 581 | basic_mdarray const& other 582 | ) noexcept 583 | { 584 | cp_ = other.cp_; 585 | map_ = other.map_; 586 | c_ = other.c_; 587 | return *this; 588 | } 589 | 590 | // TODO noexcept specification 591 | MDSPAN_TEMPLATE_REQUIRES( 592 | class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherCP, 593 | /* requires */ ( 594 | _MDSPAN_TRAIT(is_convertible, typename OtherLayoutPolicy::template mapping, mapping_type) && 595 | _MDSPAN_TRAIT(is_assignable, container_policy_type, OtherCP&&) && 596 | _MDSPAN_TRAIT(is_assignable, container_type, typename OtherCP::container_type&&) && 597 | _MDSPAN_TRAIT(is_convertible, OtherExtents, extents_type) 598 | ) 599 | ) 600 | _MDSPAN_CONSTEXPR_14 basic_mdarray& operator=( 601 | basic_mdarray&& other 602 | ) noexcept 603 | { 604 | cp_ = std::move(other.cp_); 605 | map_ = std::move(other.map_); 606 | c_ = std::move(other.c_); 607 | return *this; 608 | } 609 | 610 | //========================================================================== 611 | 612 | MDSPAN_TEMPLATE_REQUIRES( 613 | class Index, 614 | /* requires */ ( 615 | _MDSPAN_TRAIT(is_convertible, Index, index_type) && 616 | sizeof...(Exts) == 1 617 | ) 618 | ) 619 | MDSPAN_FORCE_INLINE_FUNCTION 620 | _MDSPAN_CONSTEXPR_14 reference operator[](Index idx) noexcept 621 | { 622 | return cp_.access(c_, map_(index_type(idx))); 623 | } 624 | 625 | MDSPAN_TEMPLATE_REQUIRES( 626 | class Index, 627 | /* requires */ ( 628 | _MDSPAN_TRAIT(is_convertible, Index, index_type) && 629 | sizeof...(Exts) == 1 630 | ) 631 | ) 632 | MDSPAN_FORCE_INLINE_FUNCTION 633 | constexpr reference operator[](Index idx) const noexcept 634 | { 635 | return cp_.access(c_, map_(index_type(idx))); 636 | } 637 | 638 | MDSPAN_TEMPLATE_REQUIRES( 639 | class... IndexType, 640 | /* requires */ ( 641 | _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, IndexType, index_type) /* && ... */) && 642 | sizeof...(Exts) == extents_type::rank() 643 | ) 644 | ) 645 | MDSPAN_FORCE_INLINE_FUNCTION 646 | _MDSPAN_CONSTEXPR_14 reference operator()(IndexType... indices) noexcept 647 | { 648 | return cp_.access(c_, map_(index_type(indices)...)); 649 | } 650 | 651 | MDSPAN_TEMPLATE_REQUIRES( 652 | class... IndexType, 653 | /* requires */ ( 654 | _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(is_convertible, IndexType, index_type) /* && ... */) && 655 | sizeof...(Exts) == extents_type::rank() 656 | ) 657 | ) 658 | MDSPAN_FORCE_INLINE_FUNCTION 659 | constexpr const_reference operator()(IndexType... indices) const noexcept 660 | { 661 | return cp_.access(c_, map_(index_type(indices)...)); 662 | } 663 | 664 | 665 | // TODO array version of dereference op 666 | 667 | //========================================================================== 668 | 669 | MDSPAN_INLINE_FUNCTION static constexpr int rank() noexcept { return extents_type::rank(); } 670 | MDSPAN_INLINE_FUNCTION static constexpr int rank_dynamic() noexcept { return extents_type::rank_dynamic(); } 671 | MDSPAN_INLINE_FUNCTION static constexpr index_type static_extent(size_t r) noexcept { return extents_type::static_extent(r); } 672 | 673 | MDSPAN_INLINE_FUNCTION constexpr extents_type extents() const noexcept { return map_.extents(); }; 674 | MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return map_.extents().extent(r); }; 675 | // TODO basic_mdarray.size() 676 | MDSPAN_INLINE_FUNCTION constexpr index_type size() const noexcept { 677 | return this->__crtp_base_t::template __size(); 678 | }; 679 | 680 | MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 index_type unique_size() const noexcept { 681 | if(map_.is_unique()) { 682 | return size(); 683 | } 684 | else if(map_.is_contiguous()) { 685 | return map_.required_span_size(); 686 | } 687 | else { 688 | // ??? guess, for now, until this gets fixed in the proposal ??? 689 | return map_.required_span_size(); 690 | } 691 | } 692 | 693 | MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); }; 694 | MDSPAN_INLINE_FUNCTION static constexpr bool is_always_contiguous() noexcept { return mapping_type::is_always_contiguous(); }; 695 | MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); }; 696 | 697 | MDSPAN_INLINE_FUNCTION constexpr mapping_type mapping() const noexcept { return map_; }; 698 | MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { return map_.is_unique(); }; 699 | MDSPAN_INLINE_FUNCTION constexpr bool is_contiguous() const noexcept { return map_.is_contiguous(); }; 700 | MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return map_.is_strided(); }; 701 | MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return map_.stride(r); }; 702 | 703 | //========================================================================== 704 | 705 | // TODO noexcept specification 706 | MDSPAN_INLINE_FUNCTION 707 | _MDSPAN_CONSTEXPR_14 view_type view() noexcept { 708 | return view_type(c_.data(), map_, cp_); 709 | } 710 | // TODO noexcept specification 711 | MDSPAN_INLINE_FUNCTION 712 | constexpr const const_view_type view() const noexcept { 713 | return const_view_type(c_.data(), map_, cp_); 714 | } 715 | 716 | // TODO noexcept specification 717 | MDSPAN_INLINE_FUNCTION 718 | _MDSPAN_CONSTEXPR_14 pointer data() noexcept { 719 | return cp_.data(); 720 | } 721 | 722 | // TODO noexcept specification 723 | MDSPAN_INLINE_FUNCTION 724 | constexpr const_pointer data() const noexcept { 725 | return cp_.data(); 726 | } 727 | 728 | MDSPAN_INLINE_FUNCTION 729 | constexpr container_policy_type container_policy() const noexcept { return cp_; } 730 | 731 | private: 732 | 733 | template 734 | friend class basic_mdarray; 735 | 736 | // TODO @proposal-bug these should be in the reverse order in the proposal, even as exposition only 737 | _MDSPAN_NO_UNIQUE_ADDRESS container_policy_type cp_; // TODO @proposal-bug this is misspelled in the synopsis 738 | _MDSPAN_NO_UNIQUE_ADDRESS mapping_type map_; 739 | container_type c_; 740 | 741 | }; 742 | 743 | template 744 | using mdarray = basic_mdarray>; 745 | 746 | //class basic_mdarray< 747 | // ElementType, std::experimental::extents, 748 | // LayoutPolicy, ContainerPolicy 749 | //> 750 | 751 | 752 | } // end namespace __mdarray_version_0 753 | } // end namespace experimental 754 | 755 | template 756 | struct uses_allocator, Allocator> 757 | : uses_allocator {}; 758 | 759 | } // end namespace std 760 | 761 | #endif //MDARRAY_INCLUDE_EXPERIMENTAL_BITS_BASIC_MDARRAY_HPP_ 762 | -------------------------------------------------------------------------------- /include/experimental/__p1684_bits/const_wrapped_accessor_policy.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #ifndef MDARRAY_INCLUDE_EXPERIMENTAL___P1684_BITS_CONST_WRAPPED_ACCESSOR_POLICY_HPP_ 45 | #define MDARRAY_INCLUDE_EXPERIMENTAL___P1684_BITS_CONST_WRAPPED_ACCESSOR_POLICY_HPP_ 46 | 47 | #include 48 | #include 49 | #include 50 | 51 | namespace std { 52 | namespace experimental { 53 | inline namespace __mdarray_version_0 { 54 | namespace __detail { 55 | 56 | template 57 | struct __const_wrapped_accessor_policy { 58 | private: 59 | 60 | _MDSPAN_NO_UNIQUE_ADDRESS CP __underlying_cp; 61 | 62 | public: 63 | 64 | using element_type = add_const_t; 65 | using pointer = typename CP::const_pointer; 66 | using reference = typename CP::const_reference; 67 | // TODO @proposal-bug if we keep offset_policy in P0009, we need `const_offset_policy`... 68 | using offset_policy = typename CP::const_offset_policy; 69 | 70 | 71 | MDSPAN_INLINE_FUNCTION_DEFAULTED 72 | constexpr __const_wrapped_accessor_policy() noexcept(noexcept(CP())) = default; 73 | MDSPAN_INLINE_FUNCTION_DEFAULTED 74 | constexpr __const_wrapped_accessor_policy(__const_wrapped_accessor_policy const&) 75 | noexcept(is_nothrow_copy_constructible::value) = default; 76 | MDSPAN_INLINE_FUNCTION_DEFAULTED 77 | constexpr __const_wrapped_accessor_policy(__const_wrapped_accessor_policy&&) 78 | noexcept(is_nothrow_move_constructible::value) = default; 79 | MDSPAN_INLINE_FUNCTION_DEFAULTED 80 | _MDSPAN_CONSTEXPR_14_DEFAULTED __const_wrapped_accessor_policy& 81 | operator=(__const_wrapped_accessor_policy const&) 82 | noexcept(is_nothrow_copy_assignable::value) = default; 83 | _MDSPAN_CONSTEXPR_14_DEFAULTED __const_wrapped_accessor_policy& 84 | operator=(__const_wrapped_accessor_policy&&) 85 | noexcept(is_nothrow_move_assignable::value) = default; 86 | MDSPAN_INLINE_FUNCTION_DEFAULTED 87 | ~__const_wrapped_accessor_policy() noexcept = default; 88 | 89 | MDSPAN_INLINE_FUNCTION 90 | explicit constexpr 91 | __const_wrapped_accessor_policy(CP&& underlying) 92 | noexcept(is_nothrow_move_constructible::value) 93 | : __underlying_cp(std::move(underlying)) 94 | { } 95 | 96 | MDSPAN_INLINE_FUNCTION 97 | explicit constexpr 98 | __const_wrapped_accessor_policy(CP const& underlying) 99 | noexcept(is_nothrow_copy_constructible::value) 100 | : __underlying_cp(underlying) 101 | { } 102 | 103 | MDSPAN_INLINE_FUNCTION 104 | constexpr reference access(pointer ptr, size_t i) const 105 | noexcept(noexcept(__underlying_cp.access(ptr, i))) 106 | { 107 | return __underlying_cp.access(ptr, i); 108 | } 109 | 110 | MDSPAN_INLINE_FUNCTION 111 | constexpr pointer offset(pointer p, size_t i) const 112 | noexcept(noexcept(__underlying_cp.offset(p, i))) 113 | { 114 | return __underlying_cp.offset(p, i); 115 | } 116 | }; 117 | 118 | } // end namespace __detail 119 | } // end inline namespace __mdarray_version_0 120 | } // end namespace experimental 121 | } // end namespace std 122 | 123 | #endif //MDARRAY_INCLUDE_EXPERIMENTAL___P1684_BITS_CONST_WRAPPED_ACCESSOR_POLICY_HPP_ 124 | -------------------------------------------------------------------------------- /include/experimental/__p1684_bits/container_policy_basic.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #ifndef MDARRAY_INCLUDE_EXPERIMENTAL_BITS_CONTAINER_POLICY_BASIC_HPP_ 45 | #define MDARRAY_INCLUDE_EXPERIMENTAL_BITS_CONTAINER_POLICY_BASIC_HPP_ 46 | 47 | #include "const_wrapped_accessor_policy.hpp" 48 | 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include // std::allocator 56 | #include 57 | 58 | 59 | // TODO @proposal-bug should the container policy own the allocator? 60 | 61 | namespace std { 62 | namespace experimental { 63 | inline namespace __mdarray_version_0 { 64 | 65 | namespace __detail { 66 | 67 | // TODO this is inefficient with a stateful allocator. Make different class for the offset policy portion 68 | template 69 | class __container_policy_common { 70 | public: 71 | using container_type = Container; 72 | // TODO @proposal-bug This should be value_type (both here and in P0009) 73 | using element_type = typename container_type::value_type; 74 | using pointer = typename container_type::pointer; 75 | using const_pointer = typename container_type::const_pointer; 76 | using reference = typename container_type::reference; 77 | using const_reference = typename container_type::const_reference; 78 | 79 | MDSPAN_FORCE_INLINE_FUNCTION 80 | static constexpr reference access(container_type& c, size_t i) 81 | noexcept(noexcept(c[i])) 82 | { 83 | return c[size_t(i)]; 84 | } 85 | MDSPAN_FORCE_INLINE_FUNCTION 86 | static constexpr const_reference access(container_type const& c, size_t i) 87 | noexcept(noexcept(c[i])) 88 | { 89 | return c[size_t(i)]; 90 | } 91 | MDSPAN_FORCE_INLINE_FUNCTION 92 | static constexpr reference access(pointer c, size_t i) noexcept { 93 | return c[size_t(i)]; 94 | } 95 | MDSPAN_FORCE_INLINE_FUNCTION 96 | static constexpr const_reference access(const_pointer c, size_t i) noexcept { 97 | return c[size_t(i)]; 98 | } 99 | 100 | MDSPAN_INLINE_FUNCTION 101 | static constexpr pointer offset(pointer p, size_t i) noexcept { 102 | return &p[size_t(i)]; 103 | } 104 | MDSPAN_INLINE_FUNCTION 105 | static constexpr const_pointer offset(const_pointer p, size_t i) noexcept { 106 | return &p[size_t(i)]; 107 | } 108 | 109 | // TODO converting constructors (and make sure they work for conversion to const offset policy 110 | //MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED 111 | //__container_policy_common() noexcept = default; 112 | //MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED 113 | //__container_policy_common(__container_policy_common const&) noexcept = default; 114 | //MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED 115 | //__container_policy_common(__container_policy_common&&) noexcept = default; 116 | //MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED 117 | //__container_policy_common& operator=(__container_policy_common const&) noexcept = default; 118 | //MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED 119 | //__container_policy_common& operator=(__container_policy_common&&) noexcept = default; 120 | //MDSPAN_INLINE_FUNCTION_DEFAULTED ~__container_policy_common() noexcept = default; 121 | // 122 | //MDSPAN_INLINE_FUNCTION 123 | //__container_policy_common(Derived const&) noexcept { } 124 | 125 | }; 126 | 127 | } // end namespace __detail 128 | 129 | template > 130 | class vector_container_policy 131 | : public __detail::__container_policy_common< 132 | std::vector, vector_container_policy 133 | > 134 | { 135 | private: 136 | using __base_t_ = __detail::__container_policy_common< 137 | std::vector, vector_container_policy 138 | >; 139 | public: 140 | 141 | using offset_policy = vector_container_policy; 142 | using const_offset_policy = __detail::__const_wrapped_accessor_policy<__base_t_>; 143 | 144 | // TODO noexcept clause 145 | MDSPAN_FUNCTION_REQUIRES( 146 | (MDSPAN_INLINE_FUNCTION static constexpr typename __base_t_::container_type), 147 | create, (size_t n), noexcept, 148 | /* requires */ ( 149 | _MDSPAN_TRAIT(is_constructible, typename __base_t_::container_type, size_t, typename __base_t_::element_type) 150 | ) 151 | ) 152 | { 153 | return typename __base_t_::container_type(n, typename __base_t_::element_type{}); 154 | } 155 | 156 | // TODO noexcept clause 157 | MDSPAN_FUNCTION_REQUIRES( 158 | (MDSPAN_INLINE_FUNCTION static constexpr typename __base_t_::container_type), 159 | create, (size_t n, const Allocator& alloc), noexcept, 160 | /* requires */ ( 161 | _MDSPAN_TRAIT( 162 | is_constructible, 163 | typename __base_t_::container_type, size_t, typename __base_t_::element_type, const Allocator& 164 | ) 165 | ) 166 | ) 167 | { 168 | return typename __base_t_::container_type(n, typename __base_t_::element_type{}, alloc); 169 | } 170 | }; 171 | 172 | template 173 | class array_container_policy 174 | : public __detail::__container_policy_common< 175 | std::array, array_container_policy 176 | > 177 | { 178 | private: 179 | using __base_t_ = __detail::__container_policy_common< 180 | std::array, array_container_policy 181 | >; 182 | public: 183 | 184 | using offset_policy = array_container_policy; 185 | using const_offset_policy = __detail::__const_wrapped_accessor_policy<__base_t_>; 186 | 187 | MDSPAN_INLINE_FUNCTION 188 | static constexpr typename __base_t_::container_type 189 | create(size_t n) { 190 | if(n > N) throw length_error("array_container_policy asked for an array larger than static size"); 191 | return typename __base_t_::container_type(n); 192 | } 193 | }; 194 | 195 | namespace __detail { 196 | 197 | //============================================================================== 198 | // {{{1 199 | 200 | template using __void_size_t = void; 201 | 202 | // TODO make an alternative to this that works with MSVC? 203 | template 204 | struct __has_constexpr_required_span_size 205 | : std::false_type 206 | { static constexpr auto size = 0; }; 207 | 208 | template 209 | struct __has_constexpr_required_span_size< 210 | Map, __void_size_t<(Map{}.required_span_size(), 0)> 211 | > : std::true_type 212 | { static constexpr auto size = Map{}.required_span_size(); }; 213 | 214 | template struct __container_policy_select; 215 | 216 | template 217 | struct __container_policy_select< 218 | T, LP, std::experimental::extents 219 | > 220 | { 221 | 222 | // Avoid even instantiating the constexpr check if there are dynamic 223 | // extents (it's extra work, and it doesn't mean anything, because 224 | // the default constructed map doesn't have all of the information 225 | // to get the right size) 226 | struct __has_constexpr_req_size_delay { 227 | template 228 | using __apply = __has_constexpr_required_span_size; 229 | }; 230 | 231 | struct __false_zero_delay { 232 | template 233 | struct __apply { 234 | static constexpr auto value = false; 235 | static constexpr auto size = 0; 236 | }; 237 | }; 238 | 239 | using __use_array = typename std::conditional< 240 | _MDSPAN_FOLD_OR(Extents == dynamic_extent), 241 | __false_zero_delay, 242 | __has_constexpr_req_size_delay 243 | >::type::template __apply< 244 | typename LP::template mapping> 245 | >; 246 | 247 | // TODO delay instantiation of policy until conditional is resolved? 248 | using type = typename std::conditional< 249 | __use_array::value, 250 | array_container_policy, 251 | vector_container_policy 252 | >::type; 253 | }; 254 | 255 | // end container policy select implementation }}}1 256 | //============================================================================== 257 | 258 | } // end namespace __detail 259 | 260 | } // end inline namespace __mdarray_version_0 261 | } // end namespace experimental 262 | } // end namespace std 263 | 264 | #endif //MDARRAY_INCLUDE_EXPERIMENTAL_BITS_CONTAINER_POLICY_BASIC_HPP_ 265 | -------------------------------------------------------------------------------- /include/experimental/mdarray: -------------------------------------------------------------------------------- 1 | /* 2 | //@HEADER 3 | // ************************************************************************ 4 | // 5 | // Kokkos v. 2.0 6 | // Copyright (2019) Sandia Corporation 7 | // 8 | // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 9 | // the U.S. Government retains certain rights in this software. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are 13 | // met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. Neither the name of the Corporation nor the names of the 23 | // contributors may be used to endorse or promote products derived from 24 | // this software without specific prior written permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 27 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 39 | // 40 | // ************************************************************************ 41 | //@HEADER 42 | */ 43 | 44 | #ifndef MDARRAY_INCLUDE_EXPERIMENTAL_MDARRAY_ 45 | #define MDARRAY_INCLUDE_EXPERIMENTAL_MDARRAY_ 46 | 47 | #include "__p1684_bits/basic_mdarray.hpp" 48 | #include "__p1684_bits/const_wrapped_accessor_policy.hpp" 49 | #include "__p1684_bits/container_policy_basic.hpp" 50 | 51 | #include 52 | #include 53 | #include 54 | 55 | #endif //MDARRAY_INCLUDE_EXPERIMENTAL_MDARRAY_ 56 | -------------------------------------------------------------------------------- /make_single_header.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | import sys 5 | import os 6 | from os.path import dirname, join as path_join, abspath, exists 7 | 8 | extra_paths = [path_join(dirname(abspath(__file__)), "include")] 9 | 10 | def find_file(included_name, current_file): 11 | current_dir = dirname(abspath(current_file)) 12 | for idir in [current_dir] + extra_paths: 13 | try_path = path_join(idir, included_name) 14 | if exists(try_path): 15 | return try_path 16 | return None 17 | 18 | def process_file(file_path, out_lines=[], front_matter_lines=[], processed_files=[]): 19 | with open(file_path, "r") as f: 20 | for line in f: 21 | m_inc = re.match(r'#include\s*[<"](.+)[>"]\s*', line) 22 | if m_inc: 23 | inc_name = m_inc.group(1) 24 | inc_path = find_file(inc_name, file_path) 25 | if inc_path not in processed_files: 26 | if inc_path is not None: 27 | processed_files += [inc_path] 28 | process_file(inc_path, out_lines, front_matter_lines, processed_files) 29 | else: 30 | # assume it's a system header; add it to the front matter just to be clean 31 | front_matter_lines += [line] 32 | continue 33 | m_once = re.match(r"#pragma once\s*", line) 34 | # ignore pragma once; we're handling it here 35 | if m_once: 36 | continue 37 | # otherwise, just add the line to the output 38 | if line[-1] != "\n": line = line + "\n" 39 | out_lines += [line] 40 | return "".join(front_matter_lines) + "\n" + "".join(out_lines) 41 | 42 | if __name__ == "__main__": 43 | print(process_file(abspath(sys.argv[1]), [], ["#pragma once\n"], [abspath(sys.argv[1])])) 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | macro(mdarray_add_test name) 3 | add_executable(${name} ${name}.cpp) 4 | target_link_libraries(${name} mdarray GTest::GTest GTest::Main) 5 | add_test(${name} ${name}) 6 | endmacro() 7 | 8 | find_package(GTest REQUIRED) 9 | 10 | #mdarray_add_test(test_thingy) 11 | 12 | --------------------------------------------------------------------------------