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
5 changes: 1 addition & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ jobs:
libs/function_types \
libs/functional \
libs/fusion \
libs/integer \
libs/io \
libs/mp11 \
libs/mpl \
Expand All @@ -203,11 +202,9 @@ jobs:
libs/static_assert \
libs/throw_exception \
libs/tuple \
libs/type_index \
libs/type_traits \
libs/typeof \
libs/utility \
libs/variant
libs/utility

- name: Build upstream Boost libraries (Ubuntu)
if: matrix.os.name == 'ubuntu' && steps.cache-boost.outputs.cache-hit != 'true'
Expand Down
20 changes: 0 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,6 @@ list(APPEND iris_x4_boost_deps functional)
list(APPEND iris_x4_boost_deps function)
list(APPEND iris_x4_boost_deps bind)

# Everything required by `variant` (manually confirmed)
list(APPEND iris_x4_boost_deps variant)
list(APPEND iris_x4_boost_deps integer)
list(APPEND iris_x4_boost_deps type_index)
list(APPEND iris_x4_boost_deps assert)
list(APPEND iris_x4_boost_deps config)
list(APPEND iris_x4_boost_deps container_hash)
list(APPEND iris_x4_boost_deps core)
list(APPEND iris_x4_boost_deps detail)
list(APPEND iris_x4_boost_deps mpl)
list(APPEND iris_x4_boost_deps preprocessor)
list(APPEND iris_x4_boost_deps static_assert)
list(APPEND iris_x4_boost_deps throw_exception)
list(APPEND iris_x4_boost_deps type_traits)
list(APPEND iris_x4_boost_deps utility)
list(APPEND iris_x4_boost_deps describe)
list(APPEND iris_x4_boost_deps mp11)
list(APPEND iris_x4_boost_deps predef)
list(APPEND iris_x4_boost_deps io)

# Everything required by `preprocessor` (manually confirmed)
list(APPEND iris_x4_boost_deps preprocessor)

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ git submodule update --init --depth 1 --recursive -- \
tools/build tools/boost_install libs/assert libs/bind libs/config \
libs/container_hash libs/core libs/describe libs/detail \
libs/function libs/function_types libs/functional libs/fusion \
libs/integer libs/io libs/mp11 libs/mpl libs/predef libs/preprocessor \
libs/static_assert libs/throw_exception libs/tuple libs/type_index \
libs/type_traits libs/typeof libs/utility libs/variant
libs/io libs/mp11 libs/mpl libs/predef libs/preprocessor \
libs/static_assert libs/throw_exception libs/tuple \
libs/type_traits libs/typeof libs/utility

# Linux
./bootstrap.sh
Expand Down
2 changes: 0 additions & 2 deletions include/iris/x4/core/detail/parse_into_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
#include <boost/fusion/sequence/intrinsic/front.hpp>
#include <boost/fusion/sequence/intrinsic/back.hpp>

#include <boost/variant/variant.hpp> // TODO: remove Boost.Variant usage

#include <iterator>
#include <type_traits>
#include <utility>
Expand Down
11 changes: 5 additions & 6 deletions include/iris/x4/debug/print_attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
#include <iris/x4/traits/attribute_category.hpp>
#include <iris/x4/traits/variant_traits.hpp>

#include <boost/fusion/include/for_each.hpp>
#include <iris/rvariant/rvariant_io.hpp>

#include <boost/variant.hpp>
#include <boost/variant/apply_visitor.hpp> // TODO: remove this
#include <boost/fusion/include/for_each.hpp>

#ifdef IRIS_X4_UNICODE
# include <iris/x4/char_encoding/unicode.hpp>
Expand Down Expand Up @@ -57,9 +56,9 @@ struct print_fusion_sequence

// print elements in a variant
template<class Out>
struct print_visitor : boost::static_visitor<>
struct print_visitor
{
print_visitor(Out& out)
explicit print_visitor(Out& out)
: out(out)
{}

Expand Down Expand Up @@ -144,7 +143,7 @@ struct print_attribute_debug
// for variant types
static void call(Out& out, CategorizedAttr<variant_attr> auto const& val)
{
boost::apply_visitor(detail::print_visitor<Out>(out), val);
iris::visit(detail::print_visitor<Out>{out}, val);
}

static void call(Out& out, CategorizedAttr<optional_attr> auto const& val)
Expand Down
4 changes: 2 additions & 2 deletions include/iris/x4/operator/alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <iris/x4/traits/attribute_of_binary.hpp>
#include <iris/x4/traits/container_traits.hpp>

#include <boost/variant/variant.hpp> // TODO: remove this
#include <iris/rvariant/rvariant.hpp>

#include <concepts>
#include <iterator>
Expand All @@ -31,7 +31,7 @@ namespace iris::x4 {
template<class Left, class Right>
struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
{
using attribute_type = traits::attribute_of_binary<boost::variant, alternative, Left, Right>::type;
using attribute_type = traits::attribute_of_binary<iris::rvariant, alternative, Left, Right>::type;

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

Expand Down
149 changes: 71 additions & 78 deletions include/iris/x4/traits/variant_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,120 +14,113 @@

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

#include <boost/variant/variant_fwd.hpp> // TODO: remove this

#include <boost/mpl/find.hpp> // TODO: remove this
#include <boost/mpl/deref.hpp> // TODO: remove this
#include <boost/mpl/find_if.hpp> // TODO: remove this
#include <boost/mpl/eval_if.hpp> // TODO: remove this
#include <boost/mpl/begin_end.hpp> // TODO: remove this
#include <iris/rvariant/variant_helper.hpp>

#include <type_traits>

namespace iris::x4::traits {

// TODO: define a legit concept for determining variant-like types

template<class T>
struct is_variant : std::false_type {};

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

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

template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
: std::true_type
{};
template<class... Ts>
struct is_variant<iris::rvariant<Ts...>> : std::true_type {};


namespace detail {

template<class Attr, class... Ts>
struct variant_find_substitute_impl;

template<class Variant, X4Attribute T>
struct variant_find_substitute
template<class Attr>
struct variant_find_substitute_impl<Attr>
{
// Get the type from the Variant that can be a substitute for T.
// If none is found, just return T

using variant_type = Variant;
using types = typename variant_type::types;
using end = typename boost::mpl::end<types>::type;

using iter_1 = typename boost::mpl::find<types, T>::type;

using iter = typename boost::mpl::eval_if<
std::is_same<iter_1, end>,
boost::mpl::find_if<types, is_substitute<T, boost::mpl::_1>>,
std::type_identity<iter_1>
>::type;

using type = typename boost::mpl::eval_if<
std::is_same<iter, end>,
std::type_identity<T>,
boost::mpl::deref<iter>
>::type;
using type = Attr;
};

template<class Variant, X4Attribute T>
using variant_find_substitute_t = typename variant_find_substitute<Variant, T>::type;

template<class Variant>
struct variant_find_substitute<Variant, Variant>
template<class Attr, class First, class... Rest>
struct variant_find_substitute_impl<Attr, First, Rest...>
{
using type = Variant;
using type = std::conditional_t<
is_substitute_v<Attr, iris::unwrap_recursive_t<First>>,

// TODO
// Given some type `T`, when both `T` and `recursive_wrapper<T>` is seen
// during attribute resolution, X4 should ideally materialize the latter
// because:
// - It means that the user has supplied at least one explicit type
// (possibly a rule attribute type) that is `recursive_wrapper<T>`,
// - Constructing `T` and then moving it to `recursive_wrapper<T>`
// involves copying from stack to heap.
//
// This is to-do because the above optimization is currently not
// implementable in a straightforward way. We need to add
// `unwrap_recursive(attr)` to every places where any parser attempts
// to modify the content.
iris::unwrap_recursive_t<First>,

typename variant_find_substitute_impl<Attr, Rest...>::type
>;
};

} // detail

namespace detail {

template<class Variant, X4Attribute T>
struct variant_has_substitute_impl
{
// Find a type from the Variant that can be a substitute for T.
// return true_ if one is found, else false_
template<class Variant, X4Attribute Attr>
struct variant_find_substitute;

using variant_type = Variant;
using types = typename variant_type::types;
using end = typename boost::mpl::end<types>::type;
using iter_1 = typename boost::mpl::find<types, T>::type;
template<class Variant, X4Attribute Attr>
using variant_find_substitute_t = typename variant_find_substitute<Variant, Attr>::type;

using iter = typename boost::mpl::eval_if<
std::is_same<iter_1, end>,
boost::mpl::find_if<types, is_substitute<T, boost::mpl::_1>>,
std::type_identity<iter_1>
>::type;
template<X4Attribute Attr>
struct variant_find_substitute<Attr, Attr>
{
using type = Attr;
};

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

} // detail

template<class Variant, X4Attribute Attr>
struct variant_has_substitute
: detail::variant_has_substitute_impl<Variant, Attr>::type
{};
struct variant_has_substitute;

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

template<X4Attribute Attr>
struct variant_has_substitute<unused_type, Attr> : std::true_type {};
struct variant_has_substitute<Attr, Attr>
: std::true_type
{};

template<X4Attribute Attr>
struct variant_has_substitute<unused_type const, Attr> : std::true_type {};
struct variant_has_substitute<unused_type, Attr>
: std::true_type
{};

template<X4Attribute Attr>
struct variant_has_substitute<unused_type const, Attr>
: std::true_type
{};

// Recursively find the first type from the variant that can be a substitute for `T`.
// Returns boolean value whether it was found.
template<X4Attribute Attr, class... Ts>
requires (!std::same_as<iris::rvariant<Ts...>, Attr>)
struct variant_has_substitute<iris::rvariant<Ts...>, Attr>
: std::disjunction<is_substitute<Attr, Ts>...>
{};

} // iris::x4::traits

Expand Down
2 changes: 1 addition & 1 deletion modules/iris
Submodule iris updated 55 files
+30 −0 .clang-tidy
+1 −0 .github/workflows/ci.yml
+2 −0 .gitignore
+9 −3 CMakeLists.txt
+19 −0 cpp.hint
+4 −0 doc/.gitignore
+1 −0 doc/_std-indirect-proxy.adoc
+1 −0 doc/_std-variant-proxy.adoc
+405 −0 doc/docinfo.html
+1,588 −0 doc/rvariant.adoc
+3,040 −0 doc/rvariant.html
+25 −0 include/iris/bits/is_function_object.hpp
+33 −0 include/iris/bits/specialization_of.hpp
+75 −0 include/iris/compare.hpp
+208 −0 include/iris/cond_trivial_smf.hpp
+20 −0 include/iris/config.hpp
+45 −0 include/iris/default_init_allocator.hpp
+74 −0 include/iris/format_traits.hpp
+128 −0 include/iris/hash.hpp
+87 −0 include/iris/hash/FNV_hash.hpp
+18 −0 include/iris/hash_fwd.hpp
+493 −0 include/iris/indirect.hpp
+18 −0 include/iris/indirect_pmr.hpp
+40 −0 include/iris/io_fwd.hpp
+143 −0 include/iris/requirements.hpp
+12 −0 include/iris/rvariant.hpp
+51 −0 include/iris/rvariant/detail/recursive_traits.hpp
+40 −0 include/iris/rvariant/detail/rvariant_fwd.hpp
+121 −0 include/iris/rvariant/detail/seq.hpp
+130 −0 include/iris/rvariant/detail/variant_requirements.hpp
+336 −0 include/iris/rvariant/detail/variant_storage.hpp
+668 −0 include/iris/rvariant/detail/visit.hpp
+68 −0 include/iris/rvariant/pack.hpp
+268 −0 include/iris/rvariant/recursive_wrapper.hpp
+17 −0 include/iris/rvariant/recursive_wrapper_pmr.hpp
+1,580 −0 include/iris/rvariant/rvariant.hpp
+276 −0 include/iris/rvariant/rvariant_io.hpp
+73 −0 include/iris/rvariant/subset.hpp
+165 −0 include/iris/rvariant/variant_helper.hpp
+272 −13 include/iris/type_traits.hpp
+255 −0 iris.natvis
+8 −6 test/CMakeLists.txt
+13 −0 test/cpp.hint
+77 −0 test/rvariant/CMakeLists.txt
+434 −0 test/rvariant/core_test.cpp
+465 −0 test/rvariant/flexible_test.cpp
+802 −0 test/rvariant/get_visit_test.cpp
+143 −0 test/rvariant/indirect_test.cpp
+398 −0 test/rvariant/io_test.cpp
+101 −0 test/rvariant/many_alternatives_32_test.cpp
+296 −0 test/rvariant/recursive_wrapper_test.cpp
+1,910 −0 test/rvariant/rvariant_test.cpp
+164 −0 test/rvariant/rvariant_test.hpp
+189 −0 test/rvariant/truly_recursive_test.cpp
+1 −1 test/test.hpp
Loading