Skip to content

Commit f8c75f7

Browse files
committed
Split recursive_wrapper and recursive_wrapper_alloca
1 parent f4f47ca commit f8c75f7

8 files changed

Lines changed: 429 additions & 153 deletions

File tree

include/iris/rvariant/detail/recursive_traits.hpp

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

44
// SPDX-License-Identifier: MIT
@@ -10,6 +10,12 @@
1010

1111
namespace iris::detail {
1212

13+
template<class T>
14+
constexpr bool is_recursive_wrapper_like_v =
15+
is_ttp_specialization_of_v<T, recursive_wrapper> ||
16+
is_ttp_specialization_of_v<T, recursive_wrapper_alloca>;
17+
18+
1319
template<bool Found, std::size_t I, class U, class... Ts>
1420
struct select_maybe_wrapped_impl;
1521

@@ -20,10 +26,17 @@ struct select_maybe_wrapped_impl<false, I, U, U, Rest...>
2026
static constexpr std::size_t index = I;
2127
};
2228

29+
template<std::size_t I, class U, class... Rest>
30+
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper<U>, Rest...>
31+
{
32+
using type = recursive_wrapper<U>;
33+
static constexpr std::size_t index = I;
34+
};
35+
2336
template<std::size_t I, class U, class Allocator, class... Rest>
24-
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper<U, Allocator>, Rest...>
37+
struct select_maybe_wrapped_impl<false, I, U, recursive_wrapper_alloca<U, Allocator>, Rest...>
2538
{
26-
using type = recursive_wrapper<U, Allocator>;
39+
using type = recursive_wrapper_alloca<U, Allocator>;
2740
static constexpr std::size_t index = I;
2841
};
2942

include/iris/rvariant/detail/rvariant_fwd.hpp

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

44
// SPDX-License-Identifier: MIT
@@ -20,9 +20,12 @@ namespace iris {
2020
template<class... Ts>
2121
class rvariant;
2222

23-
template<class T, class Allocator>
23+
template<class T>
2424
class recursive_wrapper;
2525

26+
template<class T, class Allocator>
27+
class recursive_wrapper_alloca;
28+
2629

2730
namespace detail {
2831

Lines changed: 1 addition & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#ifndef IRIS_RVARIANT_DETAIL_VARIANT_REQUIREMENTS_HPP
1+
#ifndef IRIS_RVARIANT_DETAIL_VARIANT_REQUIREMENTS_HPP
22
#define IRIS_RVARIANT_DETAIL_VARIANT_REQUIREMENTS_HPP
33

44
// SPDX-License-Identifier: MIT
@@ -9,122 +9,6 @@
99

1010
namespace iris::detail {
1111

12-
template<class T, class U>
13-
struct check_recursive_wrapper_duplicate_impl : std::true_type {};
14-
15-
template<class T, class Allocator>
16-
struct check_recursive_wrapper_duplicate_impl<recursive_wrapper<T, Allocator>, T>
17-
: std::false_type
18-
{
19-
// ReSharper disable once CppStaticAssertFailure
20-
static_assert(
21-
false,
22-
"rvariant cannot contain both `T` and `recursive_wrapper<T, Allocator>` "
23-
"([rvariant.rvariant.general])."
24-
);
25-
};
26-
27-
template<class T, class Allocator>
28-
struct check_recursive_wrapper_duplicate_impl<T, recursive_wrapper<T, Allocator>>
29-
: std::false_type
30-
{
31-
// ReSharper disable once CppStaticAssertFailure
32-
static_assert(
33-
false,
34-
"rvariant cannot contain both `T` and `recursive_wrapper<T, Allocator>` "
35-
"([rvariant.rvariant.general])."
36-
);
37-
};
38-
39-
template<class T, class Allocator, class UAllocator>
40-
requires (!std::is_same_v<Allocator, UAllocator>)
41-
struct check_recursive_wrapper_duplicate_impl<recursive_wrapper<T, Allocator>, recursive_wrapper<T, UAllocator>>
42-
: std::false_type
43-
{
44-
// ReSharper disable once CppStaticAssertFailure
45-
static_assert(
46-
false,
47-
"rvariant cannot contain multiple different allocator specializations of "
48-
"`recursive_wrapper` for the same `T` ([rvariant.rvariant.general])."
49-
);
50-
};
51-
52-
template<class T, class... Ts>
53-
struct check_recursive_wrapper_duplicate : std::true_type {};
54-
55-
template<class T, class... Ts> requires (sizeof...(Ts) > 0)
56-
struct check_recursive_wrapper_duplicate<T, T, Ts...>
57-
: std::conjunction<check_recursive_wrapper_duplicate_impl<T, Ts>...>
58-
{};
59-
60-
template<class T, class List>
61-
struct non_wrapped_exactly_once : exactly_once<T, List>
62-
{
63-
static_assert(
64-
!is_ttp_specialization_of_v<T, recursive_wrapper>,
65-
"Constructing a `recursive_wrapper` alternative with its full type as the tag is "
66-
"prohibited to avoid confusion; just specify `T` instead."
67-
);
68-
};
69-
70-
template<class T, class List>
71-
constexpr bool non_wrapped_exactly_once_v = non_wrapped_exactly_once<T, List>::value;
72-
73-
74-
template<class T, class Variant>
75-
struct exactly_once_index
76-
{
77-
static_assert(exactly_once_v<T, typename Variant::unwrapped_types>, "T or recursive_wrapper<T> must occur exactly once in Ts...");
78-
static constexpr std::size_t value = find_index_v<T, typename Variant::unwrapped_types>;
79-
};
80-
81-
template<class T, class Variant>
82-
inline constexpr std::size_t exactly_once_index_v = exactly_once_index<T, Variant>::value;
83-
84-
85-
template<class T, class U = T const&>
86-
struct variant_copy_assignable : std::conjunction<std::is_constructible<T, U>, std::is_assignable<T&, U>>
87-
{
88-
static_assert(!std::is_reference_v<T>);
89-
static_assert(std::is_lvalue_reference_v<U>);
90-
};
91-
92-
template<class T, class U = T const&>
93-
struct variant_nothrow_copy_assignable : std::conjunction<std::is_nothrow_constructible<T, U>, std::is_nothrow_assignable<T&, U>>
94-
{
95-
static_assert(!std::is_reference_v<T>);
96-
static_assert(std::is_lvalue_reference_v<U>);
97-
static_assert(variant_copy_assignable<T, U>::value);
98-
};
99-
100-
template<class T, class U = T&&>
101-
struct variant_move_assignable : std::conjunction<std::is_constructible<T, U>, std::is_assignable<T&, U>>
102-
{
103-
static_assert(!std::is_reference_v<T>);
104-
static_assert(std::is_rvalue_reference_v<U>);
105-
};
106-
107-
template<class T, class U = T&&>
108-
struct variant_nothrow_move_assignable : std::conjunction<std::is_nothrow_constructible<T, U>, std::is_nothrow_assignable<T&, U>>
109-
{
110-
static_assert(!std::is_reference_v<T>);
111-
static_assert(std::is_rvalue_reference_v<U>);
112-
static_assert(variant_move_assignable<T, U>::value);
113-
};
114-
115-
template<class T, class U>
116-
struct variant_assignable : std::conjunction<std::is_constructible<T, U>, std::is_assignable<T&, U>>
117-
{
118-
static_assert(!std::is_reference_v<T>);
119-
};
120-
121-
template<class T, class U>
122-
struct variant_nothrow_assignable : std::conjunction<std::is_nothrow_constructible<T, U>, std::is_nothrow_assignable<T&, U>>
123-
{
124-
static_assert(!std::is_reference_v<T>);
125-
static_assert(variant_assignable<T, U>::value);
126-
};
127-
12812
} // iris::detail
12913

13014
#endif

0 commit comments

Comments
 (0)