-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A | A not being simplified to A in 1.78.0 #722
Comments
Try something like the type_sequence in following in attribute _of_binary.hpp //Purpose:
// Prototype a **MAYBE** solution to https://github.com/boostorg/spirit/issues/722
// The MAYBE is because it's unknown whether this change to type_sequence will
// break other parts of code such as that in alternative.hpp or detail/alternative.hpp.
//========
#include <boost/mp11.hpp>
namespace mp11=boost::mp11;
#include <boost/utility/trace_scope.hpp>
#include <boost/iostreams/utility/templ_expr/demangle_fmt_type.hpp>
#define USE_TRANSFER_VARIANT_UNIQUE
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/utility/enable_if.hpp>
namespace x3=boost::spirit::x3;
template <typename... T>
struct type_sequence
//A prototype of detail::type_sequence in:
// attribute_of_binary.hpp
//which "unique-izes" the template args to boost::variant.
{
#ifdef USE_TRANSFER_VARIANT_UNIQUE
template
< template <typename...> class U
, typename Enable = void
>
struct maybe_variant_transfer
//If U is not a variant, simply transfer to U.
{ using type=U<T...>;
static void trace_tmpl()
{
; boost::trace_scope ts(stringify(":__LINE__=",__LINE__))
; std::cout<<":type="<<demangle_fmt_type<type>()<<";\n";
;}
};
template
< template <typename...> class U
>
struct maybe_variant_transfer
< U
, typename boost::enable_if
< typename x3::traits::is_variant
< U
< void//anything, just to allow is_variant to work.
>
>
>::type
>
//If U is a variant, assure the types are unique.
{
using mp_list_T=mp11::mp_list<T...>
;
using unique_t=mp11::mp_unique<mp_list_T>
;
template
< typename S
>
struct unpack_transfer
;
template
< typename... S
>
struct unpack_transfer
< mp11::mp_list<S...>
>
{ using type=U<S...>;
};
using type=typename unpack_transfer< unique_t>::type
;
static void trace_tmpl()
{
; boost::trace_scope ts(stringify(":__LINE__=",__LINE__))
; std::cout<<":type="<<demangle_fmt_type<type>()<<";\n";
;}
};
template <template <typename...> class U>
using maybe_transfer = maybe_variant_transfer<U>;
template <template <typename...> class U>
using transfer_to = typename maybe_transfer<U>::type;
template<template <typename...> class U>
static void trace_tmpl()
{
; boost::trace_scope ts(stringify(":__LINE__=",__LINE__))
; std::cout<<":transfer_to=\n"<<demangle_fmt_type<transfer_to<U>>()<<";\n"
; std::cout<<":maybe_transfer<U>=\n"<<demangle_fmt_type<maybe_transfer<U>>()<<";\n"
; std::cout<<":maybe_transfer<U>::trace_tmpl():\n"
; maybe_transfer<U>::trace_tmpl()
;}
#else
template <template <typename...> class U>
using transfer_to = U<T...>;
static void trace_tmpl()
{
; boost::trace_scope ts(stringify(":__LINE__=",__LINE__))
;}
#endif//USE_TRANSFER_VARIANT_UNIQUE
};//type_sequence
template
< typename...
>
struct not_var
{};
int main()
{
boost::iostreams::indent_scoped_ostreambuf<char>
indent_outbuf(std::cout,2)
; using seq=type_sequence<int,double,int>;
; std::cout<<":seq=\n"<<demangle_fmt_type<seq>()<<";\n"
; using xfr_var=typename seq::template transfer_to<boost::variant>;
; std::cout<<":xfr_var=\n"<<demangle_fmt_type<xfr_var>()<<";\n"
; std::cout<<":seq::trace_tmpl<xfr_var>():\n";
; seq::trace_tmpl<boost::variant>()
; using xfr_not=typename seq::template transfer_to<not_var>;
; std::cout<<":xfr_not=\n"<<demangle_fmt_type<xfr_not>()<<";\n"
; std::cout<<":seq::trace_tmpl<not_var>():\n";
; seq::trace_tmpl<not_var>()
;} |
Any workaround for this? |
Repeated types not being unified is much older thing #610, so I doubt it is the cause. Reversed order was reported in #721 though matching the order does not help this example. There is a meta issue that affects alternative parser #707 (comment) and highly likely the source of this bug too. |
Fix boostorg#721, boostorg#722. Experimental: use optional<variant>
This and #721 seem to be the consequence of the changes done in #702, combined with the issue described in #610. I've implemented a prototype (crude) fix here: https://github.com/eido79/spirit/tree/variant_substitute |
Another functionality that has changed in 78. When having a disjunction A|A it is no longer simplified into a single A, the synthesized attribute is variant<A,A>. Is this expected?
https://godbolt.org/z/Mjoc9aKMa
The text was updated successfully, but these errors were encountered: