From c4817358aa9c5d2b9b64fa959df4bab0369d2470 Mon Sep 17 00:00:00 2001 From: Som1Lse Date: Wed, 3 Aug 2016 22:28:25 +0200 Subject: [PATCH] Implemented https://github.com/Microsoft/GSL/issues/260 --- include/multi_span.h | 22 ++++++++++++++++------ tests/multi_span_tests.cpp | 28 ++++++++++++++-------------- tests/strided_span_tests.cpp | 18 +++++++++--------- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/include/multi_span.h b/include/multi_span.h index a8a1af2..c883fb0 100644 --- a/include/multi_span.h +++ b/include/multi_span.h @@ -1053,18 +1053,28 @@ template class general_span_iterator; template -struct dim +struct dim_t { static const std::ptrdiff_t value = DimSize; }; template <> -struct dim +struct dim_t { static const std::ptrdiff_t value = dynamic_range; const std::ptrdiff_t dvalue; - dim(std::ptrdiff_t size) : dvalue(size) {} + dim_t(std::ptrdiff_t size) : dvalue(size) {} }; +template +constexpr std::enable_if_t<(N >= 0),dim_t> dim() noexcept { + return dim_t(); +} + +template +constexpr std::enable_if_t> dim(std::ptrdiff_t n) noexcept { + return dim_t<>(n); +} + template class multi_span; @@ -1133,13 +1143,13 @@ namespace details } template std::enable_if_t< - !std::is_same>::value && !std::is_same::value, T> + !std::is_same>::value && !std::is_same::value, T> static_as_multi_span_helper(Arg, Args... args) { return static_as_multi_span_helper(args...); } template - T static_as_multi_span_helper(dim val, Args... args) + T static_as_multi_span_helper(dim_t val, Args... args) { return static_as_multi_span_helper(args..., val.dvalue); } @@ -1682,7 +1692,7 @@ constexpr auto as_multi_span(multi_span s) noexcept } template -constexpr auto as_multi_span(T* const& ptr, dim... args) +constexpr auto as_multi_span(T* const& ptr, dim_t... args) -> multi_span, Dimensions...> { return {reinterpret_cast*>(ptr), diff --git a/tests/multi_span_tests.cpp b/tests/multi_span_tests.cpp index 7432057..003d236 100644 --- a/tests/multi_span_tests.cpp +++ b/tests/multi_span_tests.cpp @@ -687,9 +687,9 @@ SUITE(multi_span_tests) fn(av.bounds()); auto av2 = as_multi_span(av, dim<60>()); auto av3 = as_multi_span(av2, dim<3>(), dim<4>(), dim<5>()); - auto av4 = as_multi_span(av3, dim<4>(), dim<>(3), dim<5>()); + auto av4 = as_multi_span(av3, dim<4>(), dim(3), dim<5>()); auto av5 = as_multi_span(av4, dim<3>(), dim<4>(), dim<5>()); - auto av6 = as_multi_span(av5, dim<12>(), dim<>(5)); + auto av6 = as_multi_span(av5, dim<12>(), dim(5)); fill(av6.begin(), av6.end(), 1); @@ -954,7 +954,7 @@ SUITE(multi_span_tests) CHECK(s1 == s2); - multi_span s3 = as_multi_span(s1, dim<>(20)); + multi_span s3 = as_multi_span(s1, dim(20)); CHECK(s3 == s2 && s3 == s1); } @@ -1122,7 +1122,7 @@ SUITE(multi_span_tests) CHECK(count == 34 * 60); overloaded_func(av, 34); - overloaded_func(as_multi_span(av, dim<>(4), dim<>(3), dim<>(5)), 34); + overloaded_func(as_multi_span(av, dim(4), dim(3), dim(5)), 34); // fixed_func(av, 34); delete[] data; @@ -1137,7 +1137,7 @@ SUITE(multi_span_tests) // size check will be done auto image_view = - as_multi_span(as_multi_span(image_ptr, imgSize), dim<>(height), dim<>(width), dim<3>()); + as_multi_span(as_multi_span(image_ptr, imgSize), dim(height), dim(width), dim<3>()); iota(image_view.begin(), image_view.end(), 1); @@ -1165,7 +1165,7 @@ SUITE(multi_span_tests) { int* arr = new int[150]; - auto av = as_multi_span(arr, dim<10>(), dim<>(3), dim<5>()); + auto av = as_multi_span(arr, dim<10>(), dim(3), dim<5>()); fill(av.begin(), av.end(), 24); overloaded_func(av, 24); @@ -1174,13 +1174,13 @@ SUITE(multi_span_tests) array stdarr{0}; auto av2 = as_multi_span(stdarr); - overloaded_func(as_multi_span(av2, dim<>(1), dim<3>(), dim<5>()), 0); + overloaded_func(as_multi_span(av2, dim(1), dim<3>(), dim<5>()), 0); string str = "ttttttttttttttt"; // size = 15 auto t = str.data(); (void) t; auto av3 = as_multi_span(str); - overloaded_func(as_multi_span(av3, dim<>(1), dim<3>(), dim<5>()), 't'); + overloaded_func(as_multi_span(av3, dim(1), dim<3>(), dim<5>()), 't'); } { @@ -1258,7 +1258,7 @@ SUITE(multi_span_tests) CHECK(av[i] == 4); - auto av2 = as_multi_span(av, dim<4>(), dim<>(2)); + auto av2 = as_multi_span(av, dim<4>(), dim(2)); ptrdiff_t a2[2] = {0, 1}; index<2> i2 = a2; @@ -1490,17 +1490,17 @@ SUITE(multi_span_tests) // first bound is dynamic { - multi_span av2 = as_multi_span(av, dim<>(height), dim<>(width)); + multi_span av2 = as_multi_span(av, dim(height), dim(width)); iterate_second_column(av2); } // second bound is dynamic { - multi_span av2 = as_multi_span(av, dim<>(height), dim<>(width)); + multi_span av2 = as_multi_span(av, dim(height), dim(width)); iterate_second_column(av2); } // both bounds are dynamic { - multi_span av2 = as_multi_span(av, dim<>(height), dim<>(width)); + multi_span av2 = as_multi_span(av, dim(height), dim(width)); iterate_second_column(av2); } @@ -1521,7 +1521,7 @@ SUITE(multi_span_tests) CHECK_THROW(av1[10][3][4], fail_fast); - multi_span av2 = as_multi_span(av1, dim<>(5), dim<6>(), dim<4>()); + multi_span av2 = as_multi_span(av1, dim(5), dim<6>(), dim<4>()); (void) av2; } @@ -1568,7 +1568,7 @@ SUITE(multi_span_tests) { multi_span av = arr; - multi_span av2 = as_multi_span(av, dim<>(2), dim<>(2)); + multi_span av2 = as_multi_span(av, dim(2), dim(2)); auto workaround_macro = [&]() { return av2[{1, 0}] == 2; }; CHECK(workaround_macro()); } diff --git a/tests/strided_span_tests.cpp b/tests/strided_span_tests.cpp index 19056b1..b81a5e7 100644 --- a/tests/strided_span_tests.cpp +++ b/tests/strided_span_tests.cpp @@ -463,7 +463,7 @@ SUITE(strided_span_tests) // retype strided array with regular strides - from multi_span { strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } }; - multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); + multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); strided_span sav2{ bytes2, bounds }; strided_span sav3 = sav2.as_strided_span(); CHECK(sav3[0][0] == 0); @@ -475,7 +475,7 @@ SUITE(strided_span_tests) // retype strided array with not enough elements - last dimension of the array is too small { strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } }; - multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); + multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); strided_span sav2{ bytes2, bounds }; CHECK_THROW(sav2.as_strided_span(), fail_fast); } @@ -483,7 +483,7 @@ SUITE(strided_span_tests) // retype strided array with not enough elements - strides are too small { strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } }; - multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); + multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); strided_span sav2{ bytes2, bounds }; CHECK_THROW(sav2.as_strided_span(), fail_fast); } @@ -491,7 +491,7 @@ SUITE(strided_span_tests) // retype strided array with not enough elements - last dimension does not divide by the new typesize { strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } }; - multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); + multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); strided_span sav2{ bytes2, bounds }; CHECK_THROW(sav2.as_strided_span(), fail_fast); } @@ -499,7 +499,7 @@ SUITE(strided_span_tests) // retype strided array with not enough elements - strides does not divide by the new typesize { strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } }; - multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim<>(bytes.size() / 2)); + multi_span bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2)); strided_span sav2{ bytes2, bounds }; CHECK_THROW(sav2.as_strided_span(), fail_fast); } @@ -675,17 +675,17 @@ SUITE(strided_span_tests) } { - auto av = as_multi_span(as_multi_span(arr, 24), dim<>(3), dim<4>(), dim<2>()); + auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>()); iterate_second_slice(av); } { - auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<>(4), dim<2>()); + auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>()); iterate_second_slice(av); } { - auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<>(2)); + auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2)); iterate_second_slice(av); } delete[] arr; @@ -704,7 +704,7 @@ SUITE(strided_span_tests) auto d1 = sizeof(int) * 12 / d2; // convert to 4x12 array of bytes - auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim<>(d1), dim<>(d2)); + auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2)); CHECK(av.bounds().index_bounds()[0] == 4); CHECK(av.bounds().index_bounds()[1] == 12);