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
4 changes: 2 additions & 2 deletions include/iris/x4/core/detail/parse_alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ struct parse_into_container_impl<alternative<Left, Right>>
using parser_type = alternative<Left, Right>;

template<std::forward_iterator It, std::sentinel_for<It> Se, class Context, X4Attribute Attr>
requires traits::is_variant_v<traits::container_value_t<Attr>>
requires traits::is_variant_v<typename traits::container_value<Attr>::type>
[[nodiscard]] static constexpr bool
call(
parser_type const& parser,
Expand All @@ -242,7 +242,7 @@ struct parse_into_container_impl<alternative<Left, Right>>
}

template<std::forward_iterator It, std::sentinel_for<It> Se, class Context, X4Attribute Attr>
requires (!traits::is_variant_v<traits::container_value_t<Attr>>)
requires (!traits::is_variant_v<typename traits::container_value<Attr>::type>)
[[nodiscard]] static constexpr bool
call(
parser_type const& parser,
Expand Down
7 changes: 3 additions & 4 deletions include/iris/x4/core/detail/parse_into_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ struct parse_into_container_base_impl
{
static_assert(!std::same_as<std::remove_const_t<Attr>, unused_container_type>);

using value_type = traits::container_value_t<unwrap_recursive_type<Attr>>;
value_type val; // default-initialize
typename traits::container_value<unwrap_recursive_type<Attr>>::type val{}; // value-initialize

//static_assert(Parsable<Parser, It, Se, Context, value_type>);
if (!parser.parse(first, last, ctx, val)) return false;
Expand Down Expand Up @@ -149,7 +148,7 @@ struct parse_into_container_impl<Parser>
It, Se, Context,
typename parser_traits<Parser>::attribute_type
>::actual_type,
traits::container_value_t<Attr>
typename traits::container_value<Attr>::type
>>
>;

Expand Down Expand Up @@ -217,7 +216,7 @@ parse_into_container(
using attribute_type = parser_traits<Parser>::attribute_type;

// e.g. `std::string` when the attribute_type is `char`
using substitute_type = traits::variant_find_substitute_t<Attr, traits::build_container_t<attribute_type>>;
using substitute_type = traits::variant_find_substitute_t<Attr, typename traits::build_container<attribute_type>::type>;

// instead of creating a temporary `substitute_type`, append directly into the emplaced alternative
auto& variant_alt = attr.template emplace<substitute_type>();
Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/core/detail/parse_sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ struct parse_into_container_impl<sequence<Left, Right>>
template<X4Attribute Attr>
static constexpr bool is_container_substitute = traits::is_substitute_v<
typename sequence<Left, Right>::attribute_type,
traits::container_value_t<Attr>
typename traits::container_value<Attr>::type
>;

template<std::forward_iterator It, std::sentinel_for<It> Se, class Context, X4Attribute Attr>
Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/directive/repeat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ template<class Subject, detail::RepeatBounds Bounds>
struct repeat_directive : proxy_parser<Subject, repeat_directive<Subject, Bounds>>
{
using base_type = proxy_parser<Subject, repeat_directive>;
using attribute_type = traits::build_container_t<typename parser_traits<Subject>::attribute_type>;
using attribute_type = traits::build_container<typename parser_traits<Subject>::attribute_type>::type;

static constexpr bool handles_container = true;

Expand Down
27 changes: 23 additions & 4 deletions include/iris/x4/operator/alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@

namespace iris::x4 {

namespace detail {

template<bool IsBothSameAttribute, class Left, class Right>
struct alternative_attribute_impl;

// Both same attribute
template<class Left, class Right>
struct alternative_attribute_impl<true, Left, Right>
{
using type = parser_traits<Left>::attribute_type;
};

// Not same attribute
template<class Left, class Right>
struct alternative_attribute_impl<false, Left, Right>
{
using type = traits::detail::attribute_of_alternative<Left, Right>::type;
};

} // detail

template<class Left, class Right>
struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
{
Expand All @@ -40,10 +61,8 @@ struct alternative : binary_parser<Left, Right, alternative<Left, Right>>

public:
// Canonicalize `rvariant<X, X>` to `X`
using attribute_type = std::conditional_t<
is_both_same_attribute,
std::type_identity<typename parser_traits<Left>::attribute_type>,
traits::attribute_of_binary<iris::rvariant, Left, Right>
using attribute_type = detail::alternative_attribute_impl<
is_both_same_attribute, Left, Right
>::type;

// If canonicalized, proxy the underlying `sequence_size`. In other words:
Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/operator/kleene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace iris::x4 {
template<class Subject>
struct kleene : unary_parser<Subject, kleene<Subject>>
{
using attribute_type = traits::build_container_t<typename parser_traits<Subject>::attribute_type>;
using attribute_type = traits::build_container<typename parser_traits<Subject>::attribute_type>::type;

static constexpr bool handles_container = true;

Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/operator/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace iris::x4 {
template<class Left, class Right>
struct list : binary_parser<Left, Right, list<Left, Right>>
{
using attribute_type = traits::build_container_t<typename parser_traits<Left>::attribute_type>;
using attribute_type = traits::build_container<typename parser_traits<Left>::attribute_type>::type;

static constexpr bool handles_container = true;

Expand Down
12 changes: 5 additions & 7 deletions include/iris/x4/operator/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace iris::x4 {
template<class Subject>
struct optional : unary_parser<Subject, optional<Subject>>
{
using attribute_type = traits::build_optional_t<typename parser_traits<Subject>::attribute_type>;
using attribute_type = traits::build_optional<typename parser_traits<Subject>::attribute_type>::type;

static constexpr bool handles_container = true;

Expand Down Expand Up @@ -82,15 +82,13 @@ struct optional : unary_parser<Subject, optional<Subject>>
[[nodiscard]] constexpr bool
parse(It& first, Se const& last, Context const& ctx, Attr& attr) const
noexcept(
std::is_nothrow_default_constructible_v<x4::traits::optional_value_t<Attr>> &&
is_nothrow_parsable_v<Subject, It, Se, Context, x4::traits::optional_value_t<Attr>> &&
noexcept(x4::move_to(std::declval<x4::traits::optional_value_t<Attr>&&>(), attr))
std::is_nothrow_default_constructible_v<typename traits::optional_value<Attr>::type> &&
is_nothrow_parsable_v<Subject, It, Se, Context, typename traits::optional_value<Attr>::type> &&
noexcept(x4::move_to(std::declval<typename traits::optional_value<Attr>::type&&>(), attr))
)
{
using value_type = x4::traits::optional_value_t<Attr>;
value_type val; // default-initialize
typename traits::optional_value<Attr>::type val{}; // value-initialize

static_assert(Parsable<Subject, It, Se, Context, value_type>);
if (this->subject.parse(first, last, ctx, val)) {
// assign the parsed value into our attribute
x4::move_to(std::move(val), attr);
Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/operator/plus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace iris::x4 {
template<class Subject>
struct plus : unary_parser<Subject, plus<Subject>>
{
using attribute_type = traits::build_container_t<typename parser_traits<Subject>::attribute_type>;
using attribute_type = traits::build_container<typename parser_traits<Subject>::attribute_type>::type;

static constexpr bool handles_container = true;

Expand Down
2 changes: 1 addition & 1 deletion include/iris/x4/operator/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace iris::x4 {
template<class Left, class Right>
struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
{
using attribute_type = traits::attribute_of_binary<alloy::tuple, Left, Right>::type;
using attribute_type = traits::detail::attribute_of_sequence<Left, Right>::type;

static constexpr std::size_t sequence_size =
parser_traits<Left>::sequence_size + parser_traits<Right>::sequence_size;
Expand Down
4 changes: 2 additions & 2 deletions include/iris/x4/string/detail/string_parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ string_parse(
{
using synthesized_value_type = traits::synthesized_value_t<Attr>;
static_assert(std::same_as<traits::attribute_category_t<synthesized_value_type>, traits::container_attr>);
using value_type = traits::container_value_t<synthesized_value_type>;
using value_type = traits::container_value<synthesized_value_type>::type;
static_assert(!traits::CharLike<value_type> || std::same_as<value_type, CharT>, "Mixing incompatible char types is not allowed");

It it = first;
Expand Down Expand Up @@ -79,7 +79,7 @@ string_parse(
{
using synthesized_value_type = traits::synthesized_value_t<Attr>;
static_assert(std::same_as<traits::attribute_category_t<synthesized_value_type>, traits::container_attr>);
using value_type = traits::container_value_t<synthesized_value_type>;
using value_type = traits::container_value<synthesized_value_type>::type;
static_assert(!traits::CharLike<value_type> || std::same_as<value_type, CharT>, "Mixing incompatible char types is not allowed");

auto uc_it = ucstr.begin();
Expand Down
163 changes: 84 additions & 79 deletions include/iris/x4/traits/attribute_of_binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,108 +12,113 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#include <iris/x4/core/attribute.hpp>
#include <iris/x4/core/unused.hpp>
#include <iris/x4/core/parser_traits.hpp>

#include <iris/type_traits.hpp> // TODO: move iris::type_list to separate header

#include <type_traits>

namespace iris::x4::traits {

namespace detail {

template<class TypeList, class... Us>
struct append_to_type_list {};

template<class TypeList, class... Us>
using append_to_type_list_t = append_to_type_list<TypeList, Us...>::type;

template<class... Ts>
struct append_to_type_list<type_list<Ts...>>
{
using type = type_list<Ts...>;
};
template<class TTypeList, class UTypeList>
struct concat_type_list;

template<class... Ts, class... Us>
struct append_to_type_list<type_list<Ts...>, unused_type, Us...>
: append_to_type_list<type_list<Ts...>, Us...>
{};

template<class... Ts, class U, class... Us>
struct append_to_type_list<type_list<Ts...>, U, Us...>
: append_to_type_list<type_list<Ts..., U>, Us...>
{};

template<class... Ts, class... Us, class... Vs>
struct append_to_type_list<type_list<Ts...>, type_list<Us...>, Vs...>
: append_to_type_list<append_to_type_list_t<type_list<Ts...>, Us...>, Vs...>
{};

template<template<class...> class TupleTT, class T>
struct tuple_to_type_list;

template<template<class...> class TupleTT, class T>
using tuple_to_type_list_t = tuple_to_type_list<TupleTT, T>::type;

template<template<class...> class TupleTT, class T>
struct tuple_to_type_list
{
using type = T;
};

template<template<class...> class TupleTT, class... Ts>
struct tuple_to_type_list<TupleTT, TupleTT<Ts...>>
struct concat_type_list<type_list<Ts...>, type_list<Us...>>
{
using type = type_list<tuple_to_type_list_t<TupleTT, Ts>...>;
using type = type_list<Ts..., Us...>;
};

template<template<class...> class TupleTT, class T>
using tuple_to_type_list_t = tuple_to_type_list<TupleTT, T>::type;

template<template<class...> class TupleTT, class TypeList>
struct type_list_to_tuple {};
#if 0
#define IRIS_X4_TRAITS_DETAIL_DEFINE_TYPE_LIST_CONV(postfix, tmpl) \
template<class T> \
struct to_type_list_##postfix \
{ \
using type = type_list<T>; \
}; \
template<> \
struct to_type_list_##postfix<unused_type> \
{ \
using type = type_list<>; \
}; \
template<class... Ts> \
struct to_type_list_##postfix<tmpl<Ts...>> \
{ \
using type = type_list<Ts...>; \
}; \
\
template<class TypeList> \
struct from_type_list_##postfix {}; \
template<> \
struct from_type_list_##postfix<type_list<>> \
{ \
using type = unused_type; \
}; \
template<class T> \
struct from_type_list_##postfix<type_list<T>> \
{ \
using type = T; \
}; \
template<class T0, class T1, class... Ts> \
struct from_type_list_##postfix<type_list<T0, T1, Ts...>> \
{ \
using type = tmpl<T0, T1, Ts...>; \
}; \
\
template<class LeftParser, class RightParser> \
struct attribute_of_##postfix { \
using type = detail::from_type_list_##postfix< \
typename detail::concat_type_list< \
typename detail::to_type_list_##postfix<typename parser_traits<LeftParser>::attribute_type>::type, \
typename detail::to_type_list_##postfix<typename parser_traits<RightParser>::attribute_type>::type \
>::type \
>::type; \
};
#endif

template<template<class...> class TupleTT>
struct type_list_to_tuple<TupleTT, type_list<>>
{
//
// AUTOGENERATED CODE; DO NOT EDIT.
// Expanded using Visual Studio's "Expand Inline" feature.
// Code style is kept as-is.
//

// IRIS_X4_TRAITS_DETAIL_DEFINE_TYPE_LIST_CONV(sequence, alloy::tuple)
template<class T> struct to_type_list_sequence {
using type = type_list<T>;
}; template<> struct to_type_list_sequence<unused_type> {
using type = type_list<>;
}; template<class... Ts> struct to_type_list_sequence<alloy::tuple<Ts...>> {
using type = type_list<Ts...>;
}; template<class TypeList> struct from_type_list_sequence {}; template<> struct from_type_list_sequence<type_list<>> {
using type = unused_type;
};

template<template<class...> class TupleTT, class T>
struct type_list_to_tuple<TupleTT, type_list<T>>
{
}; template<class T> struct from_type_list_sequence<type_list<T>> {
using type = T;
}; template<class T0, class T1, class... Ts> struct from_type_list_sequence<type_list<T0, T1, Ts...>> {
using type = alloy::tuple<T0, T1, Ts...>;
}; template<class LeftParser, class RightParser> struct attribute_of_sequence {
using type = detail::from_type_list_sequence< typename detail::concat_type_list< typename detail::to_type_list_sequence<typename parser_traits<LeftParser>::attribute_type>::type, typename detail::to_type_list_sequence<typename parser_traits<RightParser>::attribute_type>::type >::type >::type;
};

template<template<class...> class TupleTT, class T0, class T1, class... Ts>
struct type_list_to_tuple<TupleTT, type_list<T0, T1, Ts...>>
{
using type = TupleTT<T0, T1, Ts...>;
// IRIS_X4_TRAITS_DETAIL_DEFINE_TYPE_LIST_CONV(alternative, rvariant)
template<class T> struct to_type_list_alternative {
using type = type_list<T>;
}; template<> struct to_type_list_alternative<unused_type> {
using type = type_list<>;
}; template<class... Ts> struct to_type_list_alternative<rvariant<Ts...>> {
using type = type_list<Ts...>;
}; template<class TypeList> struct from_type_list_alternative {}; template<> struct from_type_list_alternative<type_list<>> {
using type = unused_type;
}; template<class T> struct from_type_list_alternative<type_list<T>> {
using type = T;
}; template<class T0, class T1, class... Ts> struct from_type_list_alternative<type_list<T0, T1, Ts...>> {
using type = rvariant<T0, T1, Ts...>;
}; template<class LeftParser, class RightParser> struct attribute_of_alternative {
using type = detail::from_type_list_alternative< typename detail::concat_type_list< typename detail::to_type_list_alternative<typename parser_traits<LeftParser>::attribute_type>::type, typename detail::to_type_list_alternative<typename parser_traits<RightParser>::attribute_type>::type >::type >::type;
};

template<template<class...> class TupleTT, class TypeList>
using type_list_to_tuple_t = type_list_to_tuple<TupleTT, TypeList>::type;

} // detail

template<
template<class...> class TupleTT,
class LeftParser, class RightParser
>
struct attribute_of_binary
{
using type = detail::type_list_to_tuple_t<
TupleTT,
detail::append_to_type_list_t<
type_list<>,
detail::tuple_to_type_list_t<TupleTT, typename parser_traits<LeftParser>::attribute_type>,
detail::tuple_to_type_list_t<TupleTT, typename parser_traits<RightParser>::attribute_type>
>
>;
};

} // iris::x4::traits

#endif
Loading
Loading