Skip to content

Commit c733740

Browse files
authored
Merge pull request #9 from iris-cpp/introduce-rvariant
Replace `boost::variant` with `iris::rvariant`
2 parents 83205e4 + dbaf4ef commit c733740

13 files changed

Lines changed: 145 additions & 161 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ jobs:
194194
libs/function_types \
195195
libs/functional \
196196
libs/fusion \
197-
libs/integer \
198197
libs/io \
199198
libs/mp11 \
200199
libs/mpl \
@@ -203,11 +202,9 @@ jobs:
203202
libs/static_assert \
204203
libs/throw_exception \
205204
libs/tuple \
206-
libs/type_index \
207205
libs/type_traits \
208206
libs/typeof \
209-
libs/utility \
210-
libs/variant
207+
libs/utility
211208
212209
- name: Build upstream Boost libraries (Ubuntu)
213210
if: matrix.os.name == 'ubuntu' && steps.cache-boost.outputs.cache-hit != 'true'

CMakeLists.txt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,26 +80,6 @@ list(APPEND iris_x4_boost_deps functional)
8080
list(APPEND iris_x4_boost_deps function)
8181
list(APPEND iris_x4_boost_deps bind)
8282

83-
# Everything required by `variant` (manually confirmed)
84-
list(APPEND iris_x4_boost_deps variant)
85-
list(APPEND iris_x4_boost_deps integer)
86-
list(APPEND iris_x4_boost_deps type_index)
87-
list(APPEND iris_x4_boost_deps assert)
88-
list(APPEND iris_x4_boost_deps config)
89-
list(APPEND iris_x4_boost_deps container_hash)
90-
list(APPEND iris_x4_boost_deps core)
91-
list(APPEND iris_x4_boost_deps detail)
92-
list(APPEND iris_x4_boost_deps mpl)
93-
list(APPEND iris_x4_boost_deps preprocessor)
94-
list(APPEND iris_x4_boost_deps static_assert)
95-
list(APPEND iris_x4_boost_deps throw_exception)
96-
list(APPEND iris_x4_boost_deps type_traits)
97-
list(APPEND iris_x4_boost_deps utility)
98-
list(APPEND iris_x4_boost_deps describe)
99-
list(APPEND iris_x4_boost_deps mp11)
100-
list(APPEND iris_x4_boost_deps predef)
101-
list(APPEND iris_x4_boost_deps io)
102-
10383
# Everything required by `preprocessor` (manually confirmed)
10484
list(APPEND iris_x4_boost_deps preprocessor)
10585

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ git submodule update --init --depth 1 --recursive -- \
4848
tools/build tools/boost_install libs/assert libs/bind libs/config \
4949
libs/container_hash libs/core libs/describe libs/detail \
5050
libs/function libs/function_types libs/functional libs/fusion \
51-
libs/integer libs/io libs/mp11 libs/mpl libs/predef libs/preprocessor \
52-
libs/static_assert libs/throw_exception libs/tuple libs/type_index \
53-
libs/type_traits libs/typeof libs/utility libs/variant
51+
libs/io libs/mp11 libs/mpl libs/predef libs/preprocessor \
52+
libs/static_assert libs/throw_exception libs/tuple \
53+
libs/type_traits libs/typeof libs/utility
5454

5555
# Linux
5656
./bootstrap.sh

include/iris/x4/core/detail/parse_into_container.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
#include <boost/fusion/sequence/intrinsic/front.hpp>
2323
#include <boost/fusion/sequence/intrinsic/back.hpp>
2424

25-
#include <boost/variant/variant.hpp> // TODO: remove Boost.Variant usage
26-
2725
#include <iterator>
2826
#include <type_traits>
2927
#include <utility>

include/iris/x4/debug/print_attribute.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
#include <iris/x4/traits/attribute_category.hpp>
1515
#include <iris/x4/traits/variant_traits.hpp>
1616

17-
#include <boost/fusion/include/for_each.hpp>
17+
#include <iris/rvariant/rvariant_io.hpp>
1818

19-
#include <boost/variant.hpp>
20-
#include <boost/variant/apply_visitor.hpp> // TODO: remove this
19+
#include <boost/fusion/include/for_each.hpp>
2120

2221
#ifdef IRIS_X4_UNICODE
2322
# include <iris/x4/char_encoding/unicode.hpp>
@@ -57,9 +56,9 @@ struct print_fusion_sequence
5756

5857
// print elements in a variant
5958
template<class Out>
60-
struct print_visitor : boost::static_visitor<>
59+
struct print_visitor
6160
{
62-
print_visitor(Out& out)
61+
explicit print_visitor(Out& out)
6362
: out(out)
6463
{}
6564

@@ -144,7 +143,7 @@ struct print_attribute_debug
144143
// for variant types
145144
static void call(Out& out, CategorizedAttr<variant_attr> auto const& val)
146145
{
147-
boost::apply_visitor(detail::print_visitor<Out>(out), val);
146+
iris::visit(detail::print_visitor<Out>{out}, val);
148147
}
149148

150149
static void call(Out& out, CategorizedAttr<optional_attr> auto const& val)

include/iris/x4/operator/alternative.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <iris/x4/traits/attribute_of_binary.hpp>
2020
#include <iris/x4/traits/container_traits.hpp>
2121

22-
#include <boost/variant/variant.hpp> // TODO: remove this
22+
#include <iris/rvariant/rvariant.hpp>
2323

2424
#include <concepts>
2525
#include <iterator>
@@ -31,7 +31,7 @@ namespace iris::x4 {
3131
template<class Left, class Right>
3232
struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
3333
{
34-
using attribute_type = traits::attribute_of_binary<boost::variant, alternative, Left, Right>::type;
34+
using attribute_type = traits::attribute_of_binary<iris::rvariant, alternative, Left, Right>::type;
3535

3636
using binary_parser<Left, Right, alternative>::binary_parser;
3737

include/iris/x4/traits/variant_traits.hpp

Lines changed: 71 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -14,120 +14,113 @@
1414

1515
#include <iris/x4/traits/substitution.hpp>
1616

17-
#include <boost/variant/variant_fwd.hpp> // TODO: remove this
18-
19-
#include <boost/mpl/find.hpp> // TODO: remove this
20-
#include <boost/mpl/deref.hpp> // TODO: remove this
21-
#include <boost/mpl/find_if.hpp> // TODO: remove this
22-
#include <boost/mpl/eval_if.hpp> // TODO: remove this
23-
#include <boost/mpl/begin_end.hpp> // TODO: remove this
17+
#include <iris/rvariant/variant_helper.hpp>
2418

2519
#include <type_traits>
2620

2721
namespace iris::x4::traits {
2822

29-
// TODO: define a legit concept for determining variant-like types
30-
3123
template<class T>
3224
struct is_variant : std::false_type {};
3325

3426
template<class T>
3527
constexpr bool is_variant_v = is_variant<T>::value;
3628

37-
// By declaring a nested struct named `adapted_variant_tag` in
38-
// your class, you tell X4 that it is regarded as a variant type.
39-
// The minimum required interface for such a variant is that it has
40-
// constructors for various types supported by your variant and
41-
// `::types` which is an mpl sequence of the contained types.
42-
// Note (2025): The above spec is obsolete and will change in the near future.
43-
//
44-
// This is an intrusive interface. For a non-intrusive interface,
45-
// specialize the is_variant trait.
46-
template<class T>
47-
requires requires {
48-
typename T::adapted_variant_tag;
49-
}
50-
struct is_variant<T> : std::true_type
51-
{};
29+
// `std::variant` is not supported, as it does can't handle recursive types
5230

53-
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
54-
struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
55-
: std::true_type
56-
{};
31+
template<class... Ts>
32+
struct is_variant<iris::rvariant<Ts...>> : std::true_type {};
33+
34+
35+
namespace detail {
5736

37+
template<class Attr, class... Ts>
38+
struct variant_find_substitute_impl;
5839

59-
template<class Variant, X4Attribute T>
60-
struct variant_find_substitute
40+
template<class Attr>
41+
struct variant_find_substitute_impl<Attr>
6142
{
62-
// Get the type from the Variant that can be a substitute for T.
63-
// If none is found, just return T
64-
65-
using variant_type = Variant;
66-
using types = typename variant_type::types;
67-
using end = typename boost::mpl::end<types>::type;
68-
69-
using iter_1 = typename boost::mpl::find<types, T>::type;
70-
71-
using iter = typename boost::mpl::eval_if<
72-
std::is_same<iter_1, end>,
73-
boost::mpl::find_if<types, is_substitute<T, boost::mpl::_1>>,
74-
std::type_identity<iter_1>
75-
>::type;
76-
77-
using type = typename boost::mpl::eval_if<
78-
std::is_same<iter, end>,
79-
std::type_identity<T>,
80-
boost::mpl::deref<iter>
81-
>::type;
43+
using type = Attr;
8244
};
8345

84-
template<class Variant, X4Attribute T>
85-
using variant_find_substitute_t = typename variant_find_substitute<Variant, T>::type;
86-
87-
template<class Variant>
88-
struct variant_find_substitute<Variant, Variant>
46+
template<class Attr, class First, class... Rest>
47+
struct variant_find_substitute_impl<Attr, First, Rest...>
8948
{
90-
using type = Variant;
49+
using type = std::conditional_t<
50+
is_substitute_v<Attr, iris::unwrap_recursive_t<First>>,
51+
52+
// TODO
53+
// Given some type `T`, when both `T` and `recursive_wrapper<T>` is seen
54+
// during attribute resolution, X4 should ideally materialize the latter
55+
// because:
56+
// - It means that the user has supplied at least one explicit type
57+
// (possibly a rule attribute type) that is `recursive_wrapper<T>`,
58+
// - Constructing `T` and then moving it to `recursive_wrapper<T>`
59+
// involves copying from stack to heap.
60+
//
61+
// This is to-do because the above optimization is currently not
62+
// implementable in a straightforward way. We need to add
63+
// `unwrap_recursive(attr)` to every places where any parser attempts
64+
// to modify the content.
65+
iris::unwrap_recursive_t<First>,
66+
67+
typename variant_find_substitute_impl<Attr, Rest...>::type
68+
>;
9169
};
9270

71+
} // detail
9372

94-
namespace detail {
9573

96-
template<class Variant, X4Attribute T>
97-
struct variant_has_substitute_impl
98-
{
99-
// Find a type from the Variant that can be a substitute for T.
100-
// return true_ if one is found, else false_
74+
template<class Variant, X4Attribute Attr>
75+
struct variant_find_substitute;
10176

102-
using variant_type = Variant;
103-
using types = typename variant_type::types;
104-
using end = typename boost::mpl::end<types>::type;
105-
using iter_1 = typename boost::mpl::find<types, T>::type;
77+
template<class Variant, X4Attribute Attr>
78+
using variant_find_substitute_t = typename variant_find_substitute<Variant, Attr>::type;
10679

107-
using iter = typename boost::mpl::eval_if<
108-
std::is_same<iter_1, end>,
109-
boost::mpl::find_if<types, is_substitute<T, boost::mpl::_1>>,
110-
std::type_identity<iter_1>
111-
>::type;
80+
template<X4Attribute Attr>
81+
struct variant_find_substitute<Attr, Attr>
82+
{
83+
using type = Attr;
84+
};
11285

113-
using type = std::bool_constant<!std::is_same_v<iter, end>>;
86+
// Recursively find the first type from the variant that can be a substitute for `Attr`.
87+
// If none is found, returns `Attr`.
88+
template<X4Attribute Attr, class... Ts>
89+
requires (!std::same_as<iris::rvariant<Ts...>, Attr>)
90+
struct variant_find_substitute<iris::rvariant<Ts...>, Attr>
91+
{
92+
using type = typename detail::variant_find_substitute_impl<Attr, Ts...>::type;
11493
};
11594

116-
} // detail
11795

11896
template<class Variant, X4Attribute Attr>
119-
struct variant_has_substitute
120-
: detail::variant_has_substitute_impl<Variant, Attr>::type
121-
{};
97+
struct variant_has_substitute;
12298

12399
template<class Variant, X4Attribute Attr>
124100
constexpr bool variant_has_substitute_v = variant_has_substitute<Variant, Attr>::value;
125101

126102
template<X4Attribute Attr>
127-
struct variant_has_substitute<unused_type, Attr> : std::true_type {};
103+
struct variant_has_substitute<Attr, Attr>
104+
: std::true_type
105+
{};
128106

129107
template<X4Attribute Attr>
130-
struct variant_has_substitute<unused_type const, Attr> : std::true_type {};
108+
struct variant_has_substitute<unused_type, Attr>
109+
: std::true_type
110+
{};
111+
112+
template<X4Attribute Attr>
113+
struct variant_has_substitute<unused_type const, Attr>
114+
: std::true_type
115+
{};
116+
117+
// Recursively find the first type from the variant that can be a substitute for `T`.
118+
// Returns boolean value whether it was found.
119+
template<X4Attribute Attr, class... Ts>
120+
requires (!std::same_as<iris::rvariant<Ts...>, Attr>)
121+
struct variant_has_substitute<iris::rvariant<Ts...>, Attr>
122+
: std::disjunction<is_substitute<Attr, Ts>...>
123+
{};
131124

132125
} // iris::x4::traits
133126

modules/iris

Submodule iris updated 55 files

0 commit comments

Comments
 (0)