mirror of https://github.com/CGAL/cgal
Avoid ambiguous overloads of operator= with optional and variant (#8879)
Does not replace #8854 that is a better implementation but currently not fully compatible with older compilers. Also loops around the issue with gcc-15, and fixes issue #8827. See: - the CGAL https://github.com/CGAL/cgal/issues/8827, - and the upstream gcc bug entry https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119859
This commit is contained in:
commit
25d7076791
|
|
@ -1286,10 +1286,10 @@ struct Output_visitor {
|
|||
|
||||
namespace internal {
|
||||
|
||||
template < typename D, typename V = std::tuple<>, typename O = std::tuple<> >
|
||||
template < typename D, bool with_drop, typename V = std::tuple<>, typename O = std::tuple<> >
|
||||
struct Derivator
|
||||
{
|
||||
typedef Derivator<D, V, O> Self;
|
||||
typedef Derivator<D, with_drop, V, O> Self;
|
||||
Derivator() = default;
|
||||
Derivator(const Self&) = default;
|
||||
Self& operator=(const Self&) = delete;
|
||||
|
|
@ -1298,12 +1298,25 @@ struct Derivator
|
|||
{}
|
||||
};
|
||||
|
||||
template < typename D, typename V1, typename O1, typename... V, typename... O>
|
||||
struct Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> >
|
||||
: public Derivator<D, std::tuple<V...>, std::tuple<O...> >
|
||||
template < typename D>
|
||||
struct Derivator<D, true, std::tuple<>, std::tuple<>>
|
||||
{
|
||||
typedef Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> > Self;
|
||||
typedef Derivator<D, std::tuple<V...>, std::tuple<O...> > Base;
|
||||
typedef Derivator<D, true, std::tuple<>, std::tuple<>> Self;
|
||||
Derivator() = default;
|
||||
Derivator(const Self&) = default;
|
||||
Self& operator=(const Self&) = delete;
|
||||
template <class Tuple>
|
||||
void tuple_dispatch(const Tuple&){}
|
||||
template <class T>
|
||||
Self& operator=(const T&) { return *this; } // dropping value
|
||||
};
|
||||
|
||||
template < typename D, bool with_drop, typename V1, typename O1, typename... V, typename... O>
|
||||
struct Derivator<D, with_drop, std::tuple<V1, V...>, std::tuple<O1, O...> >
|
||||
: public Derivator<D, with_drop, std::tuple<V...>, std::tuple<O...> >
|
||||
{
|
||||
typedef Derivator<D, with_drop, std::tuple<V1, V...>, std::tuple<O1, O...> > Self;
|
||||
typedef Derivator<D, with_drop, std::tuple<V...>, std::tuple<O...> > Base;
|
||||
|
||||
Derivator() = default;
|
||||
Derivator(const Self&) = default;
|
||||
|
|
@ -1339,12 +1352,12 @@ auto to_tuple(std::tuple<Args...> &t, std::index_sequence<Is...>)
|
|||
|
||||
// OutputIterator which accepts several types in *o++= and dispatches,
|
||||
// wraps several other output iterators, and dispatches accordingly.
|
||||
template < typename V, typename O >
|
||||
class Dispatch_output_iterator;
|
||||
template < typename V, typename O, bool drop_unknown_value_types>
|
||||
class Dispatch_output_iterator_impl;
|
||||
|
||||
template < typename... V, typename... O >
|
||||
class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
|
||||
: private internal::Derivator<Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >, std::tuple<V...>, std::tuple<O...> >
|
||||
template < typename... V, typename... O, bool drop_unknown_value_types>
|
||||
class Dispatch_output_iterator_impl < std::tuple<V...>, std::tuple<O...>, drop_unknown_value_types>
|
||||
: private internal::Derivator<Dispatch_output_iterator_impl< std::tuple<V...>, std::tuple<O...>, drop_unknown_value_types >, drop_unknown_value_types, std::tuple<V...>, std::tuple<O...> >
|
||||
, public std::tuple<O...>
|
||||
{
|
||||
static_assert(sizeof...(V) == sizeof...(O),
|
||||
|
|
@ -1352,7 +1365,7 @@ class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
|
|||
|
||||
static const int size = sizeof...(V);
|
||||
|
||||
template <typename D, typename V_, typename O_>
|
||||
template <typename D, bool with_drop, typename V_, typename O_>
|
||||
friend struct internal::Derivator;
|
||||
|
||||
public:
|
||||
|
|
@ -1368,18 +1381,18 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
typedef Dispatch_output_iterator Self;
|
||||
typedef internal::Derivator<Self, Value_type_tuple, Iterator_tuple > Base;
|
||||
typedef Dispatch_output_iterator_impl Self;
|
||||
typedef internal::Derivator<Self, drop_unknown_value_types, Value_type_tuple, Iterator_tuple > Base;
|
||||
|
||||
public:
|
||||
|
||||
using Base::operator=;
|
||||
using Base::tuple_dispatch;
|
||||
|
||||
Dispatch_output_iterator(O... o) : std::tuple<O...>(o...) {}
|
||||
Dispatch_output_iterator_impl(O... o) : std::tuple<O...>(o...) {}
|
||||
|
||||
|
||||
Dispatch_output_iterator(const Dispatch_output_iterator&)=default;
|
||||
Dispatch_output_iterator_impl(const Dispatch_output_iterator_impl&)=default;
|
||||
|
||||
Self& operator=(const Self& s)
|
||||
{
|
||||
|
|
@ -1424,6 +1437,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template<class V, class O>
|
||||
using Dispatch_output_iterator = Dispatch_output_iterator_impl<V,O,false>;
|
||||
|
||||
template < typename... V, typename... O>
|
||||
Dispatch_output_iterator<std::tuple<V...>, std::tuple<O...> >
|
||||
dispatch_output(O... o)
|
||||
|
|
@ -1435,50 +1452,8 @@ dispatch_output(O... o)
|
|||
// Same as Dispatch_output_iterator, but has a dummy *o++= for all other types
|
||||
// that drops the data (same as Emptyset_iterator).
|
||||
|
||||
template < typename V, typename O >
|
||||
class Dispatch_or_drop_output_iterator;
|
||||
|
||||
template < typename... V, typename... O >
|
||||
class Dispatch_or_drop_output_iterator < std::tuple<V...>, std::tuple<O...> >
|
||||
: public Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >
|
||||
{
|
||||
typedef Dispatch_or_drop_output_iterator Self;
|
||||
typedef Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> > Base;
|
||||
|
||||
template <typename D, typename V_, typename O_>
|
||||
friend struct internal::Derivator;
|
||||
|
||||
public:
|
||||
|
||||
Dispatch_or_drop_output_iterator(O... o) : Base(o...) {}
|
||||
|
||||
Dispatch_or_drop_output_iterator(const Dispatch_or_drop_output_iterator&)=default;
|
||||
Dispatch_or_drop_output_iterator& operator=(const Dispatch_or_drop_output_iterator&)=default;
|
||||
|
||||
using Base::operator=;
|
||||
|
||||
Self& operator*() { return *this; }
|
||||
Self& operator++() { return *this; }
|
||||
Self& operator++(int) { return *this; }
|
||||
|
||||
template <class T>
|
||||
Self& operator=(const T&) { return *this; }
|
||||
|
||||
template<typename ... T>
|
||||
Self& operator=(const std::variant< T ... >& t) {
|
||||
internal::Output_visitor<Self> visitor(this);
|
||||
std::visit(visitor, t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename ... T>
|
||||
Self& operator=(const std::optional< std::variant< T ... > >& t) {
|
||||
internal::Output_visitor<Self> visitor(this);
|
||||
if(t) std::visit(visitor, *t);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<class V, class O>
|
||||
using Dispatch_or_drop_output_iterator = Dispatch_output_iterator_impl<V,O,true>;
|
||||
|
||||
template < typename... V, typename... O>
|
||||
inline
|
||||
|
|
|
|||
Loading…
Reference in New Issue