Skip to content

Commit dac8b94

Browse files
authored
Merge pull request #338 from elbeno/array-zero-case
🐛 Fix `make_array` for zero-length cases
2 parents 3c6b24c + f63b6c0 commit dac8b94

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

include/stdx/array.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ template <typename D = void, typename... Ts>
1111
constexpr auto make_array(Ts &&...ts) {
1212
if constexpr (not std::is_void_v<D>) {
1313
return std::array<D, sizeof...(Ts)>{std::forward<Ts>(ts)...};
14+
} else if constexpr (sizeof...(Ts) == 0) {
15+
return std::array<int, 0>{};
1416
} else {
1517
using A = std::common_type_t<Ts...>;
1618
return std::array<A, sizeof...(Ts)>{std::forward<Ts>(ts)...};
@@ -19,7 +21,7 @@ constexpr auto make_array(Ts &&...ts) {
1921

2022
template <template <auto> typename D, typename T, T... Is>
2123
constexpr auto make_array(std::integer_sequence<T, Is...>) {
22-
using A = std::common_type_t<decltype(D<Is>::value)...>;
24+
using A = std::remove_const_t<decltype(D<T{}>::value)>;
2325
return std::array<A, sizeof...(Is)>{D<Is>::value...};
2426
}
2527

@@ -29,7 +31,7 @@ template <template <auto> typename D, auto N> constexpr auto make_array() {
2931

3032
template <typename T, T... Is, typename F>
3133
constexpr auto make_array(std::integer_sequence<T, Is...>, F &&f) {
32-
using A = std::common_type_t<decltype(f.template operator()<Is>())...>;
34+
using A = std::remove_const_t<decltype(f.template operator()<T{}>())>;
3335
return std::array<A, sizeof...(Is)>{f.template operator()<Is>()...};
3436
}
3537

test/array.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ TEST_CASE("make_array (variadic arguments)", "[array]") {
1010
CHECK(arr == std::array{1, 2, 3, 4, 5});
1111
}
1212

13+
TEST_CASE("make_array (zero case)", "[array]") {
14+
auto arr = stdx::make_array<float>();
15+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<float, 0>>);
16+
}
17+
18+
TEST_CASE("make_array (zero case default)", "[array]") {
19+
auto arr = stdx::make_array();
20+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 0>>);
21+
}
22+
1323
namespace {
1424
template <auto I> using V = std::integral_constant<decltype(I), I + 1>;
1525
}
@@ -20,12 +30,24 @@ TEST_CASE("make_array by sequence (template with ::value)", "[array]") {
2030
CHECK(arr == std::array{1, 2, 3, 4, 5});
2131
}
2232

33+
TEST_CASE("make_array by sequence - zero case (template with ::value)",
34+
"[array]") {
35+
auto arr = stdx::make_array<V>(std::make_integer_sequence<int, 0>{});
36+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 0>>);
37+
}
38+
2339
TEST_CASE("make_array by extent (template with ::value)", "[array]") {
2440
auto arr = stdx::make_array<V, 5>();
2541
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 5>>);
2642
CHECK(arr == std::array{1, 2, 3, 4, 5});
2743
}
2844

45+
TEST_CASE("make_array by extent - zero case (template with ::value)",
46+
"[array]") {
47+
auto arr = stdx::make_array<V, 0>();
48+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 0>>);
49+
}
50+
2951
namespace {
3052
struct {
3153
template <auto I> auto operator()() { return I + 1; }
@@ -38,8 +60,20 @@ TEST_CASE("make_array by sequence (factory function template)", "[array]") {
3860
CHECK(arr == std::array{1, 2, 3, 4, 5});
3961
}
4062

63+
TEST_CASE("make_array by sequence - zero case (factory function template)",
64+
"[array]") {
65+
auto arr = stdx::make_array(std::make_integer_sequence<int, 0>{}, f);
66+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 0>>);
67+
}
68+
4169
TEST_CASE("make_array by extent (factory function template)", "[array]") {
4270
auto arr = stdx::make_array<5>(f);
4371
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 5>>);
4472
CHECK(arr == std::array{1, 2, 3, 4, 5});
4573
}
74+
75+
TEST_CASE("make_array by extent - zero case (factory function template)",
76+
"[array]") {
77+
auto arr = stdx::make_array<0>(f);
78+
STATIC_CHECK(std::is_same_v<decltype(arr), std::array<int, 0>>);
79+
}

0 commit comments

Comments
 (0)