Skip to content

Commit 8faae1b

Browse files
committed
Revise unwrap_recursive family
1 parent 4ad99df commit 8faae1b

8 files changed

Lines changed: 218 additions & 199 deletions

File tree

doc/rvariant.adoc

Lines changed: 54 additions & 55 deletions
Large diffs are not rendered by default.

doc/rvariant.html

Lines changed: 59 additions & 55 deletions
Large diffs are not rendered by default.

include/iris/rvariant/detail/visit.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#ifndef IRIS_RVARIANT_DETAIL_VISIT_HPP
1+
#ifndef IRIS_RVARIANT_DETAIL_VISIT_HPP
22
#define IRIS_RVARIANT_DETAIL_VISIT_HPP
33

44
// SPDX-License-Identifier: MIT
@@ -306,16 +306,16 @@ struct visit_check_impl<T0R, Visitor, type_list<Args...>>
306306

307307
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
308308
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...>&, Rest...>
309-
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>&>, Rest...>...> {};
309+
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>&>, Rest...>...> {};
310310
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
311311
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...> const&, Rest...>
312-
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const&>, Rest...>...> {};
312+
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const&>, Rest...>...> {};
313313
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
314314
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...>&&, Rest...>
315-
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>>, Rest...>...> {};
315+
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>>, Rest...>...> {};
316316
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
317317
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...> const&&, Rest...>
318-
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const>, Rest...>...> {};
318+
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const>, Rest...>...> {};
319319

320320
template<class T0R, class Visitor, class... Variants>
321321
using visit_check = visit_check_impl<T0R, Visitor, type_list<>, Variants...>;
@@ -357,16 +357,16 @@ struct visit_R_check_impl<R, Visitor, type_list<Args...>>
357357

358358
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
359359
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...>&, Rest...>
360-
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>&>, Rest...>...> {};
360+
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>&>, Rest...>...> {};
361361
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
362362
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...> const&, Rest...>
363-
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const&>, Rest...>...> {};
363+
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const&>, Rest...>...> {};
364364
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
365365
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...>&&, Rest...>
366-
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>>, Rest...>...> {};
366+
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>>, Rest...>...> {};
367367
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
368368
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...> const&&, Rest...>
369-
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const>, Rest...>...> {};
369+
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const>, Rest...>...> {};
370370

371371
template<class R, class Visitor, class... Variants>
372372
using visit_R_check = visit_R_check_impl<R, Visitor, type_list<>, Variants...>;
@@ -387,7 +387,7 @@ struct multi_visit_noexcept<R, std::index_sequence<Is...>, Visitor, Storage...>
387387
using type = std::is_nothrow_invocable_r<
388388
R,
389389
Visitor,
390-
unwrap_recursive_t<
390+
unwrap_recursive_type<
391391
detail::raw_get_t<detail::valueless_unbias<Storage_>(Is), Storage_>
392392
>...
393393
>;

include/iris/rvariant/rvariant.hpp

Lines changed: 48 additions & 48 deletions
Large diffs are not rendered by default.

include/iris/rvariant/rvariant_io.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ template<class... Ts>
4646
// Required to work around MSVC bug where it instantiates this function
4747
// for completely irrelevant call, e.g. `std::cout << "foo"sv << 'c' << std::endl;`
4848
(sizeof...(Ts) > 0) &&
49-
std::conjunction_v<req::ADL_ostreamable<unwrap_recursive_t<Ts>>...>
49+
std::conjunction_v<req::ADL_ostreamable<unwrap_recursive_type<Ts>>...>
5050
std::ostream& operator<<(std::ostream& os, rvariant<Ts...> const& v)
5151
{
5252
std::ostream::sentry sentry(os);
@@ -65,7 +65,7 @@ std::ostream& operator<<(std::ostream& os, rvariant<Ts...> const& v)
6565
if constexpr (i == std::variant_npos) {
6666
std::unreachable();
6767
} else {
68-
os << detail::unwrap_recursive(o); // NOTE: this may also throw `std::bad_variant_access`
68+
os << unwrap_recursive(o); // NOTE: this may also throw `std::bad_variant_access`
6969
}
7070
});
7171

@@ -181,7 +181,7 @@ struct variant_alts_formattable : std::false_type
181181

182182
template<class charT, class... Ts>
183183
struct variant_alts_formattable<charT, rvariant<Ts...>>
184-
: std::bool_constant<(std::formattable<unwrap_recursive_t<Ts>, charT> && ...)>
184+
: std::bool_constant<(std::formattable<unwrap_recursive_type<Ts>, charT> && ...)>
185185
{};
186186

187187
} // detail
@@ -192,7 +192,7 @@ struct variant_alts_formattable<charT, rvariant<Ts...>>
192192
namespace std {
193193

194194
template<class... Ts, class charT>
195-
requires (std::formattable<::iris::unwrap_recursive_t<Ts>, charT> && ...)
195+
requires (std::formattable<::iris::unwrap_recursive_type<Ts>, charT> && ...)
196196
struct formatter<::iris::rvariant<Ts...>, charT> // NOLINT(cert-dcl58-cpp)
197197
{
198198
static constexpr typename std::basic_format_parse_context<charT>::const_iterator
@@ -219,8 +219,8 @@ struct formatter<::iris::rvariant<Ts...>, charT> // NOLINT(cert-dcl58-cpp)
219219
} else {
220220
return std::format_to(
221221
ctx.out(),
222-
::iris::format_traits<charT>::template brace_full<::iris::unwrap_recursive_t<VT> const&>,
223-
::iris::detail::unwrap_recursive(alt)
222+
::iris::format_traits<charT>::template brace_full<::iris::unwrap_recursive_type<VT> const&>,
223+
::iris::unwrap_recursive(alt)
224224
);
225225
}
226226
}
@@ -257,13 +257,13 @@ struct formatter<::iris::detail::variant_format_proxy<VFormat, Variant>, charT>
257257
::iris::detail::throw_bad_variant_access();
258258
} else {
259259
static_assert(
260-
std::is_invocable_v<VFormat, std::in_place_type_t<::iris::unwrap_recursive_t<VT>>>,
260+
std::is_invocable_v<VFormat, std::in_place_type_t<::iris::unwrap_recursive_type<VT>>>,
261261
"`VFormat` must provide format string for all alternative types."
262262
);
263263
return std::format_to(
264264
ctx.out(),
265-
std::invoke(proxy.v_fmt, std::in_place_type<::iris::unwrap_recursive_t<VT>>),
266-
::iris::detail::unwrap_recursive(alt)
265+
std::invoke(proxy.v_fmt, std::in_place_type<::iris::unwrap_recursive_type<VT>>),
266+
::iris::unwrap_recursive(alt)
267267
);
268268
}
269269
}

include/iris/rvariant/subset.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct is_subset_of<rvariant<Us...>, rvariant<Ts...>>
4747
: std::conjunction<
4848
std::disjunction<
4949
is_in<Us, Ts...>,
50-
is_in<Us, unwrap_recursive_t<Ts>...>
50+
is_in<Us, unwrap_recursive_type<Ts>...>
5151
>...
5252
>
5353
{};

include/iris/rvariant/variant_helper.hpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#ifndef IRIS_RVARIANT_VARIANT_HELPER_HPP
1+
#ifndef IRIS_RVARIANT_VARIANT_HELPER_HPP
22
#define IRIS_RVARIANT_VARIANT_HELPER_HPP
33

44
// SPDX-License-Identifier: MIT
@@ -70,21 +70,37 @@ struct variant_size<rvariant<Ts...>> : std::integral_constant<std::size_t, sizeo
7070
namespace detail {
7171

7272
template<class T>
73-
[[nodiscard]] IRIS_FORCEINLINE constexpr auto&&
74-
unwrap_recursive(T&& o IRIS_LIFETIMEBOUND) noexcept
73+
struct unwrap_recursive_type_impl
7574
{
76-
if constexpr (is_ttp_specialization_of_v<std::remove_cvref_t<T>, recursive_wrapper>) {
77-
return *std::forward<T>(o);
78-
} else {
79-
return std::forward<T>(o);
75+
using type = T;
76+
};
77+
78+
template<class T, class Allocator>
79+
struct unwrap_recursive_type_impl<recursive_wrapper<T, Allocator>>
80+
{
81+
using type = T;
82+
};
83+
84+
struct unwrap_recursive_fn
85+
{
86+
template<class T>
87+
[[nodiscard]] IRIS_FORCEINLINE static constexpr auto&&
88+
operator()(T&& o IRIS_LIFETIMEBOUND) noexcept
89+
{
90+
if constexpr (is_ttp_specialization_of_v<std::remove_cvref_t<T>, recursive_wrapper>) {
91+
return *std::forward<T>(o);
92+
} else {
93+
return std::forward<T>(o);
94+
}
8095
}
81-
}
96+
};
8297

8398
} // detail
8499

85-
template<class T> struct unwrap_recursive { using type = T; };
86-
template<class T, class Allocator> struct unwrap_recursive<recursive_wrapper<T, Allocator>> { using type = T; };
87-
template<class T> using unwrap_recursive_t = unwrap_recursive<T>::type;
100+
template<class T>
101+
using unwrap_recursive_type = detail::unwrap_recursive_type_impl<T>::type;
102+
103+
inline constexpr detail::unwrap_recursive_fn unwrap_recursive{};
88104

89105

90106
template<std::size_t I, class Variant>
@@ -97,7 +113,7 @@ template<std::size_t I, class Variant>
97113
struct variant_alternative<I, Variant const> : std::add_const<variant_alternative_t<I, Variant>> {};
98114

99115
template<std::size_t I, class... Ts>
100-
struct variant_alternative<I, rvariant<Ts...>> : pack_indexing<I, unwrap_recursive_t<Ts>...>
116+
struct variant_alternative<I, rvariant<Ts...>> : pack_indexing<I, unwrap_recursive_type<Ts>...>
101117
{
102118
static_assert(I < sizeof...(Ts));
103119
};

test/rvariant/rvariant.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,15 +1589,15 @@ TEST_CASE("recursive_wrapper") // not [recursive]
15891589

15901590
TEST_CASE("unwrap_recursive") // not [recursive]
15911591
{
1592-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int&>())), int&>);
1593-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int&&>())), int&&>);
1594-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int const&>())), int const&>);
1595-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int const&&>())), int const&&>);
1596-
1597-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&>())), int&>);
1598-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&&>())), int&&>);
1599-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&>())), int const&>);
1600-
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&&>())), int const&&>);
1592+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int&>())), int&>);
1593+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int&&>())), int&&>);
1594+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int const&>())), int const&>);
1595+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int const&&>())), int const&&>);
1596+
1597+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&>())), int&>);
1598+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&&>())), int&&>);
1599+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&>())), int const&>);
1600+
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&&>())), int const&&>);
16011601
}
16021602

16031603
TEST_CASE("maybe_wrapped") // not [recursive]

0 commit comments

Comments
 (0)