Skip to content

Commit 5c66c69

Browse files
committed
fix(forward-cast): fix return type
1 parent 4efa0f6 commit 5c66c69

File tree

8 files changed

+51
-58
lines changed

8 files changed

+51
-58
lines changed

include/stdsharp/type_traits/type.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace stdsharp
1616
};
1717

1818
template<typename T>
19-
inline constexpr auto get_ref_qualifier = lvalue_ref<T> ? //
19+
inline constexpr auto ref_qualifier_v = lvalue_ref<T> ? //
2020
ref_qualifier::lvalue :
2121
rvalue_ref<T> ? ref_qualifier::rvalue : ref_qualifier::none;
2222

@@ -33,13 +33,14 @@ namespace stdsharp
3333
std::conditional_t<ref == ref_qualifier::rvalue, std::add_rvalue_reference_t<T>, T>>;
3434

3535
template<typename T, bool Const, bool Volatile, ref_qualifier ref>
36-
using apply_qualifiers = apply_ref<apply_volatile<apply_const<T, Const>, Volatile>, ref>;
36+
using apply_qualifiers =
37+
apply_ref<apply_volatile<apply_const<std::remove_cvref_t<T>, Const>, Volatile>, ref>;
3738

3839
template<typename T>
3940
using add_const_lvalue_ref_t = std::add_lvalue_reference_t<std::add_const_t<T>>;
4041

4142
template<typename T, typename U>
42-
using ref_align_t = apply_ref<U, get_ref_qualifier<T>>;
43+
using ref_align_t = apply_ref<U, ref_qualifier_v<T>>;
4344

4445
template<typename T, typename U>
4546
using const_align_t = apply_const<U, const_<T>>;
@@ -50,11 +51,6 @@ namespace stdsharp
5051
template<typename T, typename U>
5152
using cv_ref_align_t = ref_align_t<T, volatile_align_t<T, const_align_t<T, U>>>;
5253

53-
template<typename T>
54-
inline constexpr auto ref_qualifier_v = std::is_lvalue_reference_v<T> ? //
55-
ref_qualifier::lvalue :
56-
std::is_rvalue_reference_v<T> ? ref_qualifier::rvalue : ref_qualifier::none;
57-
5854
template<typename, ref_qualifier>
5955
struct override_ref;
6056

include/stdsharp/type_traits/value_sequence.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,16 @@ namespace stdsharp
104104
template<auto... Func>
105105
struct transform_fn
106106
{
107-
[[nodiscard]] constexpr value_sequence<stdsharp::invoke(Func..., Values)...>
107+
[[nodiscard]] constexpr value_sequence<stdsharp::invoke(Func, Values)...>
108108
operator()() const noexcept
109-
requires(sizeof...(Func) == 1)
110109
{
111110
return {};
112111
};
112+
};
113113

114+
template<auto Func>
115+
struct transform_fn<Func>
116+
{
114117
[[nodiscard]] constexpr value_sequence<stdsharp::invoke(Func, Values)...>
115118
operator()() const noexcept
116119
{
@@ -457,11 +460,13 @@ namespace stdsharp
457460
{
458461
constexpr auto unique_indices = []
459462
{
460-
std::array<std::size_t, size()> indices{find(Comp{}, Values)...};
463+
std::array<std::size_t, size()> indices{
464+
find_if(std::bind_front(Comp{}, Values))... //
465+
};
461466

462467
std::ranges::sort(indices);
463468

464-
if(const auto res = std::ranges::unique(indices); res) res.back() = size();
469+
if(const auto res = std::ranges::unique(indices); res) res.front() = size();
465470

466471
return indices;
467472
}();
@@ -492,7 +497,8 @@ namespace stdsharp
492497
to_value_sequence<typename to_value_sequence<front_t<Index>>::template append_t<
493498
Other>>::template append_by_seq_t<back_t<size() - Index - 1>>;
494499

495-
template<typename Comp>
500+
template<typename Comp = std::ranges::equal_to>
501+
requires(cpp_is_constexpr(Comp{}))
496502
using unique_t = unique_value_sequence<Comp>::type;
497503
};
498504
}

include/stdsharp/utility/forward_cast.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,10 @@
22

33
#include "../concepts/type.h"
44
#include "../macros.h"
5-
6-
#include <utility>
5+
#include "../type_traits/type.h"
76

87
#include "../compilation_config_in.h"
98

10-
namespace stdsharp
11-
{
12-
template<typename From, typename To>
13-
using forward_cast_t = decltype(std::forward_like<From>(std::declval<To>()));
14-
}
15-
169
namespace stdsharp::details
1710
{
1811
template<typename... Pairs>
@@ -38,6 +31,9 @@ namespace stdsharp
3831
template<typename...>
3932
struct forward_cast_fn;
4033

34+
template<typename From, typename To>
35+
using forward_cast_t = forward_cast_fn<From, To>::cast_t;
36+
4137
template<typename From, typename To>
4238
struct forward_cast_fn<From, To>
4339
{
@@ -47,23 +43,30 @@ namespace stdsharp
4743

4844
using pairs = details::forward_cast_pairs<forward_cast_fn>;
4945

46+
using no_ref_from_t = std::remove_reference_t<From>;
47+
5048
public:
5149
using from_t = std::remove_cvref_t<From>;
5250
using to_t = std::remove_cvref_t<To>;
51+
using cast_t = apply_qualifiers<
52+
To,
53+
const_<no_ref_from_t>,
54+
volatile_<no_ref_from_t>,
55+
ref_qualifier_v<From&&>>;
5356

5457
template<typename T>
5558
requires std::same_as<std::remove_cvref_t<T>, from_t> && base_of<to_t, from_t> &&
5659
not_same_as<from_t, to_t>
5760
[[nodiscard]] constexpr decltype(auto) operator()(T&& from) const noexcept
5861
{ // c-style cast allow us cast to inaccessible base
59-
return (forward_cast_t<From, To>)from; // NOLINT
62+
return (cast_t)from; // NOLINT
6063
}
6164

6265
template<typename T>
6366
requires std::same_as<std::remove_cvref_t<T>, from_t>
6467
[[nodiscard]] constexpr decltype(auto) operator()(T&& from) const noexcept
6568
{
66-
return static_cast<forward_cast_t<From, To>>(cpp_forward(from));
69+
return static_cast<cast_t>(cpp_forward(from));
6770
}
6871

6972
template<typename T>
@@ -87,7 +90,7 @@ namespace stdsharp
8790
using current_t = forward_cast_fn<From, To>;
8891

8992
using pairs = details::forward_cast_pairs<current_t>:: //
90-
template append_t<typename forward_cast_fn<To, Rest...>::pairs>;
93+
template append_t<typename forward_cast_fn<typename current_t::cast_t, Rest...>::pairs>;
9194

9295
public:
9396
[[nodiscard]] constexpr auto operator()(auto&& from) const noexcept -> //

include/stdsharp/utility/value_wrapper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ namespace stdsharp::details
2121
}
2222

2323
template<typename Self>
24-
[[nodiscard]] constexpr forward_cast_t<Self, T> get(this Self&& self) noexcept
24+
[[nodiscard]] constexpr decltype(auto) get(this Self&& self) noexcept
2525
{
26-
return forward_cast<Self, value_wrapper>(self).v;
26+
return (forward_cast<Self, value_wrapper>(self).v);
2727
}
2828
};
2929

tests/src/functional/sequenced_invocables.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,12 @@ using namespace stdsharp;
88
SCENARIO("sequenced invocables", "[functional]")
99
{
1010
[[maybe_unused]] sequenced_invocables fn{[](int) {}, [](array<int, 1>) {}, empty_invoke};
11-
1211
using fn_t = decltype(fn);
13-
14-
auto&& v = fn.get<2>();
15-
1612
STATIC_REQUIRE(fn.size() == 3);
1713
STATIC_REQUIRE(std::invocable<fn_t, int>);
1814
STATIC_REQUIRE(std::invocable<fn_t&, int>);
1915
STATIC_REQUIRE(std::invocable<fn_t, array<int, 1>>);
2016
STATIC_REQUIRE(std::invocable<fn_t&, array<int, 1>>);
2117
STATIC_REQUIRE(std::invocable<fn_t, char*>);
2218
STATIC_REQUIRE(std::invocable<fn_t&, char*>);
23-
2419
}

tests/src/type_traits/value_sequence.cpp

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,6 @@ namespace // Escape Catch2 special characters like '[' and ']'
6565
};
6666
}
6767

68-
void foo()
69-
{
70-
auto v = find_if_functor_3_t::value;
71-
72-
v("");
73-
}
74-
7568
TEMPLATE_TEST_CASE_SIG( // NOLINT
7669
"Scenario: value sequence find if",
7770
"[type traits]",
@@ -102,9 +95,12 @@ TEMPLATE_TEST_CASE_SIG( // NOLINT
10295

10396
namespace // Escape Catch2 special characters like '[' and ']'
10497
{
105-
inline constexpr sequenced_invocables count_if_functor_3{
106-
[](const size_t) { return true; },
107-
always_false
98+
struct count_if_functor_3_t
99+
{
100+
static constexpr sequenced_invocables value{
101+
[](const size_t) { return true; },
102+
always_false
103+
};
108104
};
109105
}
110106

@@ -114,10 +110,14 @@ TEMPLATE_TEST_CASE_SIG( // NOLINT
114110
((auto Fn, auto Expect), Fn, Expect),
115111
(always_true, test_seq::size()),
116112
(always_false, 0),
117-
(count_if_functor_3, 4)
113+
(count_if_functor_3_t{}, 4)
118114
)
119115
{
120-
STATIC_REQUIRE(test_seq::count_if(Fn) == Expect);
116+
if constexpr(constant_value<decltype(Fn)>)
117+
{
118+
STATIC_REQUIRE(test_seq::count_if(Fn.value) == Expect);
119+
}
120+
else STATIC_REQUIRE(test_seq::count_if(Fn) == Expect);
121121
}
122122

123123
SCENARIO("apply_t", "[type traits]") // NOLINT
@@ -237,13 +237,7 @@ TEMPLATE_TEST_CASE_SIG( // NOLINT
237237
(0, regular_value_sequence<0, 10, 1, 5, 10, 1>, regular_value_sequence<0, 10, 1, 5>) //
238238
)
239239
{
240-
STATIC_REQUIRE( //
241-
same_as<
242-
typename to_value_sequence<Seq>:: //
243-
template apply_t<unique_value_sequence>,
244-
Expect
245-
>
246-
);
240+
STATIC_REQUIRE(same_as<typename to_value_sequence<Seq>::template unique_t<>, Expect>);
247241
}
248242

249243
TEMPLATE_TEST_CASE_SIG( // NOLINT
@@ -256,10 +250,5 @@ TEMPLATE_TEST_CASE_SIG( // NOLINT
256250
(0, regular_value_sequence<1, 2>, regular_value_sequence<2, 1>) //
257251
)
258252
{
259-
STATIC_REQUIRE( //
260-
same_as<
261-
decltype(test_seq{}.get_reverse()),
262-
Expect
263-
>
264-
);
253+
STATIC_REQUIRE(same_as<decltype(to_value_sequence<Seq>{}.get_reverse()), Expect>);
265254
}

tests/src/utility/forward_cast.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ class t2 : t1
2020

2121
SCENARIO("forward cast", "[utility]")
2222
{
23+
STATIC_REQUIRE(same_as<forward_cast_t<int, int>, int&&>);
24+
STATIC_REQUIRE(same_as<forward_cast_t<int&, int>, int&>);
25+
STATIC_REQUIRE(same_as<forward_cast_t<const int&, int>, const int&>);
26+
STATIC_REQUIRE(same_as<forward_cast_t<const int&, int&>, const int&>);
27+
STATIC_REQUIRE(same_as<forward_cast_t<const volatile int&, int&&>, const volatile int&>);
28+
2329
GIVEN("t0")
2430
{
2531
[[maybe_unused]] t0 v{};
@@ -47,7 +53,6 @@ SCENARIO("forward cast", "[utility]")
4753
{
4854
[[maybe_unused]] t2 v{};
4955

50-
STATIC_REQUIRE(same_as<decltype(v | forward_cast<t2&, t1> | forward_cast<t1&, t0>), t0&>);
5156
STATIC_REQUIRE(same_as<decltype(forward_cast<t2&, t1, t0>(v)), t0&>);
5257
STATIC_REQUIRE(same_as<decltype(forward_cast<const t2&, t1, t0>(v)), const t0&>);
5358
STATIC_REQUIRE(same_as<decltype(forward_cast<t2&&, t1, t0>(v)), t0&&>);

tests/src/utility/value_wrapper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ SCENARIO("value_wrapper", "[value_wrapper]") // NOLINT
2929
STATIC_REQUIRE(nothrow_copyable<value_wrapper<int>>);
3030
STATIC_REQUIRE(nothrow_swappable<value_wrapper<int>>);
3131

32-
3332
THEN("Set the wrapper value")
3433
{
3534
[[maybe_unused]] value_wrapper<int> wrapper{};

0 commit comments

Comments
 (0)