Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 54 additions & 55 deletions doc/rvariant.adoc

Large diffs are not rendered by default.

114 changes: 59 additions & 55 deletions doc/rvariant.html

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions include/iris/rvariant/detail/visit.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef IRIS_RVARIANT_DETAIL_VISIT_HPP
#ifndef IRIS_RVARIANT_DETAIL_VISIT_HPP
#define IRIS_RVARIANT_DETAIL_VISIT_HPP

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

template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...>&, Rest...>
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>&>, Rest...>...> {};
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>&>, Rest...>...> {};
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...> const&, Rest...>
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const&>, Rest...>...> {};
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const&>, Rest...>...> {};
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...>&&, Rest...>
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>>, Rest...>...> {};
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>>, Rest...>...> {};
template<class T0R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_check_impl<T0R, Visitor, type_list<Args...>, rvariant<Ts...> const&&, Rest...>
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const>, Rest...>...> {};
: std::conjunction<visit_check_impl<T0R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const>, Rest...>...> {};

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

template<class R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...>&, Rest...>
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>&>, Rest...>...> {};
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>&>, Rest...>...> {};
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...> const&, Rest...>
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const&>, Rest...>...> {};
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const&>, Rest...>...> {};
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...>&&, Rest...>
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts>>, Rest...>...> {};
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts>>, Rest...>...> {};
template<class R, class Visitor, class... Args, class... Ts, class... Rest>
struct visit_R_check_impl<R, Visitor, type_list<Args...>, rvariant<Ts...> const&&, Rest...>
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_t<Ts> const>, Rest...>...> {};
: std::conjunction<visit_R_check_impl<R, Visitor, type_list<Args..., unwrap_recursive_type<Ts> const>, Rest...>...> {};

template<class R, class Visitor, class... Variants>
using visit_R_check = visit_R_check_impl<R, Visitor, type_list<>, Variants...>;
Expand All @@ -387,7 +387,7 @@ struct multi_visit_noexcept<R, std::index_sequence<Is...>, Visitor, Storage...>
using type = std::is_nothrow_invocable_r<
R,
Visitor,
unwrap_recursive_t<
unwrap_recursive_type<
detail::raw_get_t<detail::valueless_unbias<Storage_>(Is), Storage_>
>...
>;
Expand Down
96 changes: 48 additions & 48 deletions include/iris/rvariant/rvariant.hpp

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions include/iris/rvariant/rvariant_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ template<class... Ts>
// Required to work around MSVC bug where it instantiates this function
// for completely irrelevant call, e.g. `std::cout << "foo"sv << 'c' << std::endl;`
(sizeof...(Ts) > 0) &&
std::conjunction_v<req::ADL_ostreamable<unwrap_recursive_t<Ts>>...>
std::conjunction_v<req::ADL_ostreamable<unwrap_recursive_type<Ts>>...>
std::ostream& operator<<(std::ostream& os, rvariant<Ts...> const& v)
{
std::ostream::sentry sentry(os);
Expand All @@ -65,7 +65,7 @@ std::ostream& operator<<(std::ostream& os, rvariant<Ts...> const& v)
if constexpr (i == std::variant_npos) {
std::unreachable();
} else {
os << detail::unwrap_recursive(o); // NOTE: this may also throw `std::bad_variant_access`
os << unwrap_recursive(o); // NOTE: this may also throw `std::bad_variant_access`
}
});

Expand Down Expand Up @@ -181,7 +181,7 @@ struct variant_alts_formattable : std::false_type

template<class charT, class... Ts>
struct variant_alts_formattable<charT, rvariant<Ts...>>
: std::bool_constant<(std::formattable<unwrap_recursive_t<Ts>, charT> && ...)>
: std::bool_constant<(std::formattable<unwrap_recursive_type<Ts>, charT> && ...)>
{};

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

template<class... Ts, class charT>
requires (std::formattable<::iris::unwrap_recursive_t<Ts>, charT> && ...)
requires (std::formattable<::iris::unwrap_recursive_type<Ts>, charT> && ...)
struct formatter<::iris::rvariant<Ts...>, charT> // NOLINT(cert-dcl58-cpp)
{
static constexpr typename std::basic_format_parse_context<charT>::const_iterator
Expand All @@ -219,8 +219,8 @@ struct formatter<::iris::rvariant<Ts...>, charT> // NOLINT(cert-dcl58-cpp)
} else {
return std::format_to(
ctx.out(),
::iris::format_traits<charT>::template brace_full<::iris::unwrap_recursive_t<VT> const&>,
::iris::detail::unwrap_recursive(alt)
::iris::format_traits<charT>::template brace_full<::iris::unwrap_recursive_type<VT> const&>,
::iris::unwrap_recursive(alt)
);
}
}
Expand Down Expand Up @@ -257,13 +257,13 @@ struct formatter<::iris::detail::variant_format_proxy<VFormat, Variant>, charT>
::iris::detail::throw_bad_variant_access();
} else {
static_assert(
std::is_invocable_v<VFormat, std::in_place_type_t<::iris::unwrap_recursive_t<VT>>>,
std::is_invocable_v<VFormat, std::in_place_type_t<::iris::unwrap_recursive_type<VT>>>,
"`VFormat` must provide format string for all alternative types."
);
return std::format_to(
ctx.out(),
std::invoke(proxy.v_fmt, std::in_place_type<::iris::unwrap_recursive_t<VT>>),
::iris::detail::unwrap_recursive(alt)
std::invoke(proxy.v_fmt, std::in_place_type<::iris::unwrap_recursive_type<VT>>),
::iris::unwrap_recursive(alt)
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion include/iris/rvariant/subset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct is_subset_of<rvariant<Us...>, rvariant<Ts...>>
: std::conjunction<
std::disjunction<
is_in<Us, Ts...>,
is_in<Us, unwrap_recursive_t<Ts>...>
is_in<Us, unwrap_recursive_type<Ts>...>
>...
>
{};
Expand Down
40 changes: 28 additions & 12 deletions include/iris/rvariant/variant_helper.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef IRIS_RVARIANT_VARIANT_HELPER_HPP
#ifndef IRIS_RVARIANT_VARIANT_HELPER_HPP
#define IRIS_RVARIANT_VARIANT_HELPER_HPP

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

template<class T>
[[nodiscard]] IRIS_FORCEINLINE constexpr auto&&
unwrap_recursive(T&& o IRIS_LIFETIMEBOUND) noexcept
struct unwrap_recursive_type_impl
{
if constexpr (is_ttp_specialization_of_v<std::remove_cvref_t<T>, recursive_wrapper>) {
return *std::forward<T>(o);
} else {
return std::forward<T>(o);
using type = T;
};

template<class T, class Allocator>
struct unwrap_recursive_type_impl<recursive_wrapper<T, Allocator>>
{
using type = T;
};

struct unwrap_recursive_fn
{
template<class T>
[[nodiscard]] IRIS_FORCEINLINE static constexpr auto&&
operator()(T&& o IRIS_LIFETIMEBOUND) noexcept
{
if constexpr (is_ttp_specialization_of_v<std::remove_cvref_t<T>, recursive_wrapper>) {
return *std::forward<T>(o);
} else {
return std::forward<T>(o);
}
}
}
};

} // detail

template<class T> struct unwrap_recursive { using type = T; };
template<class T, class Allocator> struct unwrap_recursive<recursive_wrapper<T, Allocator>> { using type = T; };
template<class T> using unwrap_recursive_t = unwrap_recursive<T>::type;
template<class T>
using unwrap_recursive_type = detail::unwrap_recursive_type_impl<T>::type;

inline constexpr detail::unwrap_recursive_fn unwrap_recursive{};


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

template<std::size_t I, class... Ts>
struct variant_alternative<I, rvariant<Ts...>> : pack_indexing<I, unwrap_recursive_t<Ts>...>
struct variant_alternative<I, rvariant<Ts...>> : pack_indexing<I, unwrap_recursive_type<Ts>...>
{
static_assert(I < sizeof...(Ts));
};
Expand Down
18 changes: 9 additions & 9 deletions test/rvariant/rvariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1589,15 +1589,15 @@ TEST_CASE("recursive_wrapper") // not [recursive]

TEST_CASE("unwrap_recursive") // not [recursive]
{
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int&>())), int&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int&&>())), int&&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int const&>())), int const&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<int const&&>())), int const&&>);

STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&>())), int&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&&>())), int&&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&>())), int const&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::detail::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&&>())), int const&&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int&>())), int&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int&&>())), int&&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int const&>())), int const&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<int const&&>())), int const&&>);

STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&>())), int&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int>&&>())), int&&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&>())), int const&>);
STATIC_REQUIRE(std::is_same_v<decltype(iris::unwrap_recursive(std::declval<iris::recursive_wrapper<int> const&&>())), int const&&>);
}

TEST_CASE("maybe_wrapped") // not [recursive]
Expand Down