Skip to content

Commit 25d7076

Browse files
authored
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 #8827, - and the upstream gcc bug entry https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119859
2 parents 70d5fce + 190313e commit 25d7076

File tree

1 file changed

+36
-61
lines changed

1 file changed

+36
-61
lines changed

STL_Extension/include/CGAL/iterator.h

Lines changed: 36 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,10 +1286,10 @@ struct Output_visitor {
12861286

12871287
namespace internal {
12881288

1289-
template < typename D, typename V = std::tuple<>, typename O = std::tuple<> >
1289+
template < typename D, bool with_drop, typename V = std::tuple<>, typename O = std::tuple<> >
12901290
struct Derivator
12911291
{
1292-
typedef Derivator<D, V, O> Self;
1292+
typedef Derivator<D, with_drop, V, O> Self;
12931293
Derivator() = default;
12941294
Derivator(const Self&) = default;
12951295
Self& operator=(const Self&) = delete;
@@ -1298,12 +1298,25 @@ struct Derivator
12981298
{}
12991299
};
13001300

1301-
template < typename D, typename V1, typename O1, typename... V, typename... O>
1302-
struct Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> >
1303-
: public Derivator<D, std::tuple<V...>, std::tuple<O...> >
1301+
template < typename D>
1302+
struct Derivator<D, true, std::tuple<>, std::tuple<>>
13041303
{
1305-
typedef Derivator<D, std::tuple<V1, V...>, std::tuple<O1, O...> > Self;
1306-
typedef Derivator<D, std::tuple<V...>, std::tuple<O...> > Base;
1304+
typedef Derivator<D, true, std::tuple<>, std::tuple<>> Self;
1305+
Derivator() = default;
1306+
Derivator(const Self&) = default;
1307+
Self& operator=(const Self&) = delete;
1308+
template <class Tuple>
1309+
void tuple_dispatch(const Tuple&){}
1310+
template <class T>
1311+
Self& operator=(const T&) { return *this; } // dropping value
1312+
};
1313+
1314+
template < typename D, bool with_drop, typename V1, typename O1, typename... V, typename... O>
1315+
struct Derivator<D, with_drop, std::tuple<V1, V...>, std::tuple<O1, O...> >
1316+
: public Derivator<D, with_drop, std::tuple<V...>, std::tuple<O...> >
1317+
{
1318+
typedef Derivator<D, with_drop, std::tuple<V1, V...>, std::tuple<O1, O...> > Self;
1319+
typedef Derivator<D, with_drop, std::tuple<V...>, std::tuple<O...> > Base;
13071320

13081321
Derivator() = default;
13091322
Derivator(const Self&) = default;
@@ -1339,20 +1352,20 @@ auto to_tuple(std::tuple<Args...> &t, std::index_sequence<Is...>)
13391352

13401353
// OutputIterator which accepts several types in *o++= and dispatches,
13411354
// wraps several other output iterators, and dispatches accordingly.
1342-
template < typename V, typename O >
1343-
class Dispatch_output_iterator;
1355+
template < typename V, typename O, bool drop_unknown_value_types>
1356+
class Dispatch_output_iterator_impl;
13441357

1345-
template < typename... V, typename... O >
1346-
class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
1347-
: private internal::Derivator<Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >, std::tuple<V...>, std::tuple<O...> >
1358+
template < typename... V, typename... O, bool drop_unknown_value_types>
1359+
class Dispatch_output_iterator_impl < std::tuple<V...>, std::tuple<O...>, drop_unknown_value_types>
1360+
: 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...> >
13481361
, public std::tuple<O...>
13491362
{
13501363
static_assert(sizeof...(V) == sizeof...(O),
13511364
"The number of explicit template parameters has to match the number of arguments");
13521365

13531366
static const int size = sizeof...(V);
13541367

1355-
template <typename D, typename V_, typename O_>
1368+
template <typename D, bool with_drop, typename V_, typename O_>
13561369
friend struct internal::Derivator;
13571370

13581371
public:
@@ -1368,18 +1381,18 @@ class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
13681381

13691382
private:
13701383

1371-
typedef Dispatch_output_iterator Self;
1372-
typedef internal::Derivator<Self, Value_type_tuple, Iterator_tuple > Base;
1384+
typedef Dispatch_output_iterator_impl Self;
1385+
typedef internal::Derivator<Self, drop_unknown_value_types, Value_type_tuple, Iterator_tuple > Base;
13731386

13741387
public:
13751388

13761389
using Base::operator=;
13771390
using Base::tuple_dispatch;
13781391

1379-
Dispatch_output_iterator(O... o) : std::tuple<O...>(o...) {}
1392+
Dispatch_output_iterator_impl(O... o) : std::tuple<O...>(o...) {}
13801393

13811394

1382-
Dispatch_output_iterator(const Dispatch_output_iterator&)=default;
1395+
Dispatch_output_iterator_impl(const Dispatch_output_iterator_impl&)=default;
13831396

13841397
Self& operator=(const Self& s)
13851398
{
@@ -1424,6 +1437,10 @@ class Dispatch_output_iterator < std::tuple<V...>, std::tuple<O...> >
14241437
}
14251438
};
14261439

1440+
1441+
template<class V, class O>
1442+
using Dispatch_output_iterator = Dispatch_output_iterator_impl<V,O,false>;
1443+
14271444
template < typename... V, typename... O>
14281445
Dispatch_output_iterator<std::tuple<V...>, std::tuple<O...> >
14291446
dispatch_output(O... o)
@@ -1435,50 +1452,8 @@ dispatch_output(O... o)
14351452
// Same as Dispatch_output_iterator, but has a dummy *o++= for all other types
14361453
// that drops the data (same as Emptyset_iterator).
14371454

1438-
template < typename V, typename O >
1439-
class Dispatch_or_drop_output_iterator;
1440-
1441-
template < typename... V, typename... O >
1442-
class Dispatch_or_drop_output_iterator < std::tuple<V...>, std::tuple<O...> >
1443-
: public Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> >
1444-
{
1445-
typedef Dispatch_or_drop_output_iterator Self;
1446-
typedef Dispatch_output_iterator< std::tuple<V...>, std::tuple<O...> > Base;
1447-
1448-
template <typename D, typename V_, typename O_>
1449-
friend struct internal::Derivator;
1450-
1451-
public:
1452-
1453-
Dispatch_or_drop_output_iterator(O... o) : Base(o...) {}
1454-
1455-
Dispatch_or_drop_output_iterator(const Dispatch_or_drop_output_iterator&)=default;
1456-
Dispatch_or_drop_output_iterator& operator=(const Dispatch_or_drop_output_iterator&)=default;
1457-
1458-
using Base::operator=;
1459-
1460-
Self& operator*() { return *this; }
1461-
Self& operator++() { return *this; }
1462-
Self& operator++(int) { return *this; }
1463-
1464-
template <class T>
1465-
Self& operator=(const T&) { return *this; }
1466-
1467-
template<typename ... T>
1468-
Self& operator=(const std::variant< T ... >& t) {
1469-
internal::Output_visitor<Self> visitor(this);
1470-
std::visit(visitor, t);
1471-
return *this;
1472-
}
1473-
1474-
template<typename ... T>
1475-
Self& operator=(const std::optional< std::variant< T ... > >& t) {
1476-
internal::Output_visitor<Self> visitor(this);
1477-
if(t) std::visit(visitor, *t);
1478-
return *this;
1479-
}
1480-
};
1481-
1455+
template<class V, class O>
1456+
using Dispatch_or_drop_output_iterator = Dispatch_output_iterator_impl<V,O,true>;
14821457

14831458
template < typename... V, typename... O>
14841459
inline

0 commit comments

Comments
 (0)