diff --git a/include/experimental/__p1673_bits/transposed.hpp b/include/experimental/__p1673_bits/transposed.hpp index cd40ef84..5fedc065 100644 --- a/include/experimental/__p1673_bits/transposed.hpp +++ b/include/experimental/__p1673_bits/transposed.hpp @@ -99,7 +99,7 @@ template class layout_transpose { public: using nested_layout_type = Layout; - + template struct mapping { private: @@ -265,6 +265,27 @@ namespace impl { } }; + template + struct transposed_layout> { + using layout_type = layout_right_padded; + + template + static auto mapping(const typename layout_left_padded::template mapping& orig_map) { + using input_mapping_type = + typename layout_left_padded::template mapping; + using output_extents_type = + transpose_extents_t; + using output_mapping_type = + typename layout_type::template mapping; + + const auto padding_value = orig_map.stride(1); + return output_mapping_type{ + transpose_extents(orig_map.extents()), + padding_value + }; + } + }; + template using opposite_storage_t = std::conditional_t< std::is_same_v, diff --git a/tests/native/transposed.cpp b/tests/native/transposed.cpp index ad3b5266..4e72d6f0 100644 --- a/tests/native/transposed.cpp +++ b/tests/native/transposed.cpp @@ -199,6 +199,106 @@ namespace { } } + template + void test_transposed_layout_left_padded(auto runtime_padding_value) + { + auto test_one = [=] (auto in_exts, auto out_exts, + std::vector& fake_storage) + { + using in_extents_type = decltype(in_exts); + using out_extents_type = decltype(out_exts); + + typename layout_left_padded::template mapping in_map{ + in_exts, runtime_padding_value + }; + typename layout_right_padded::template mapping out_map{ + out_exts, runtime_padding_value + }; + test_transposed_layout(in_map, out_map, fake_storage); + }; + + std::vector storage; + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{}, out_extents_type{}, storage); + } + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{4}, out_extents_type{4}, storage); + } + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{3, 4}, out_extents_type{4, 3}, storage); + } + } + + TEST(transposed_layout, layout_left_padded) + { + { + constexpr size_t padding_value = dynamic_extent; + constexpr size_t runtime_padding_value = 5u; + test_transposed_layout_left_padded(runtime_padding_value); + } + { + constexpr size_t padding_value = 5u; + constexpr size_t runtime_padding_value = padding_value; + test_transposed_layout_left_padded(runtime_padding_value); + } + } + + template + void test_transposed_layout_right_padded(auto runtime_padding_value) + { + auto test_one = [=] (auto in_exts, auto out_exts, + std::vector& fake_storage) + { + using in_extents_type = decltype(in_exts); + using out_extents_type = decltype(out_exts); + + typename layout_left_padded::template mapping in_map{ + in_exts, runtime_padding_value + }; + typename layout_right_padded::template mapping out_map{ + out_exts, runtime_padding_value + }; + test_transposed_layout(in_map, out_map, fake_storage); + }; + + std::vector storage; + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{}, out_extents_type{}, storage); + } + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{4}, out_extents_type{4}, storage); + } + { + using in_extents_type = extents; + using out_extents_type = extents; + test_one(in_extents_type{3, 4}, out_extents_type{4, 3}, storage); + } + } + + TEST(transposed_layout, layout_right_padded) + { + { + constexpr size_t padding_value = dynamic_extent; + constexpr size_t runtime_padding_value = 5u; + test_transposed_layout_right_padded(runtime_padding_value); + } + { + constexpr size_t padding_value = 5u; + constexpr size_t runtime_padding_value = padding_value; + test_transposed_layout_right_padded(runtime_padding_value); + } + } + TEST(transposed, mdspan_double) { using real_t = double;