Skip to content

Commit ce12d2a

Browse files
committed
Fixes #334 ("Wrong overload resolution protection in implementation of P2363R5") and adds tests with transparent comparator for associative containers.
1 parent 0f99763 commit ce12d2a

File tree

6 files changed

+88
-33
lines changed

6 files changed

+88
-33
lines changed

include/boost/container/flat_set.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ class flat_set
411411
flat_set& operator=(std::initializer_list<value_type> il)
412412
{
413413
this->clear();
414-
this->insert(il.begin(), il.end());
414+
this->tree_t::insert_unique_range(il.begin(), il.end());
415415
return *this;
416416
}
417417
#endif
@@ -737,10 +737,12 @@ class flat_set
737737
template <class K>
738738
inline BOOST_CONTAINER_DOC1ST
739739
( iterator
740-
, typename dtl::enable_if_transparent< key_compare
741-
BOOST_MOVE_I K
742-
BOOST_MOVE_I iterator
743-
>::type) //transparent
740+
, typename dtl::enable_if_c<
741+
dtl::is_transparent<key_compare>::value && //transparent
742+
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
743+
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
744+
BOOST_MOVE_I iterator
745+
>::type)
744746
insert(const_iterator p, K &&x)
745747
{ return this->tree_t::insert_unique(p, boost::forward<K>(x)); }
746748

@@ -1549,7 +1551,7 @@ class flat_multiset
15491551
flat_multiset& operator=(std::initializer_list<value_type> il)
15501552
{
15511553
this->clear();
1552-
this->insert(il.begin(), il.end());
1554+
this->tree_t::insert_equal_range(il.begin(), il.end());
15531555
return *this;
15541556
}
15551557
#endif

include/boost/container/set.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,12 @@ class set
656656
template <class K>
657657
inline BOOST_CONTAINER_DOC1ST
658658
( iterator
659-
, typename dtl::enable_if_transparent< key_compare
660-
BOOST_MOVE_I K
661-
BOOST_MOVE_I iterator
662-
>::type) //transparent
659+
, typename dtl::enable_if_c<
660+
dtl::is_transparent<key_compare>::value && //transparent
661+
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
662+
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
663+
BOOST_MOVE_I iterator
664+
>::type)
663665
insert(const_iterator p, K &&x)
664666
{ return this->base_t::insert_unique_hint_convertible(p, boost::forward<K>(x)); }
665667

test/flat_map_test.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ bool constructor_template_auto_deduction_test()
193193

194194
}}}
195195

196-
template<class VoidAllocatorOrContainer>
196+
template<class VoidAllocatorOrContainer, bool Transparent = false>
197197
struct GetMapContainer
198198
{
199199
template<class ValueType>
@@ -202,21 +202,21 @@ struct GetMapContainer
202202
typedef std::pair<ValueType, ValueType> type_t;
203203
typedef flat_map< ValueType
204204
, ValueType
205-
, std::less<ValueType>
205+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
206206
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
207207
> map_type;
208208

209209
typedef flat_multimap< ValueType
210210
, ValueType
211-
, std::less<ValueType>
211+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
212212
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
213213
> multimap_type;
214214
};
215215
};
216216

217217
//To test default parameters
218-
template<>
219-
struct GetMapContainer<void>
218+
template<bool Transparent>
219+
struct GetMapContainer<void, Transparent>
220220
{
221221
template<class ValueType>
222222
struct apply
@@ -389,15 +389,6 @@ int main()
389389
return 1;
390390
}
391391

392-
if (0 != test::flat_map_test
393-
< GetMapContainer<void>::apply<int>::map_type
394-
, MyStdMap
395-
, GetMapContainer<void>::apply<int>::multimap_type
396-
, MyStdMultiMap>()) {
397-
std::cout << "Error in flat_map_test<new_allocator<void> >" << std::endl;
398-
return 1;
399-
}
400-
401392
if (0 != test::flat_map_test
402393
< GetMapContainer<new_allocator<void> >::apply<int>::map_type
403394
, MyStdMap
@@ -433,6 +424,15 @@ int main()
433424
std::cout << "Error in flat_map_test<new_allocator<void> >" << std::endl;
434425
return 1;
435426
}
427+
428+
if (0 != test::flat_map_test
429+
< GetMapContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::map_type
430+
, MyStdMap
431+
, GetMapContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::multimap_type
432+
, MyStdMultiMap>()) {
433+
std::cout << "Error in flat_map_test<new_allocator<void>, transparent >" << std::endl;
434+
return 1;
435+
}
436436
}
437437

438438
if(!boost::container::test::test_map_support_for_initialization_list_for<flat_map<int, int> >())

test/flat_set_test.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,19 +532,19 @@ bool test_heterogeneous_lookup_by_partial_key()
532532

533533
}}}
534534

535-
template<class VoidAllocatorOrContainer>
535+
template<class VoidAllocatorOrContainer, bool Transparent = false>
536536
struct GetSetContainer
537537
{
538538
template<class ValueType>
539539
struct apply
540540
{
541541
typedef flat_set < ValueType
542-
, std::less<ValueType>
542+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
543543
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
544544
> set_type;
545545

546546
typedef flat_multiset < ValueType
547-
, std::less<ValueType>
547+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
548548
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
549549
> multiset_type;
550550
};
@@ -733,6 +733,15 @@ int main()
733733
std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
734734
return 1;
735735
}
736+
737+
if (0 != test::set_test
738+
< GetSetContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::set_type
739+
, MyStdSet
740+
, GetSetContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::multiset_type
741+
, MyStdMultiSet>()) {
742+
std::cout << "Error in set_test<new_allocator<void> >>, transparent" << std::endl;
743+
return 1;
744+
}
736745
}
737746

738747
////////////////////////////////////

test/map_test.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,15 +220,15 @@ bool node_type_test()
220220
return true;
221221
}
222222

223-
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
223+
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value, bool Transparent = false>
224224
struct GetAllocatorMap
225225
{
226226
template<class ValueType>
227227
struct apply
228228
{
229229
typedef map< ValueType
230230
, ValueType
231-
, std::less<ValueType>
231+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
232232
, typename allocator_traits<VoidAllocator>
233233
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
234234
, typename boost::container::tree_assoc_options
@@ -238,7 +238,7 @@ struct GetAllocatorMap
238238

239239
typedef multimap< ValueType
240240
, ValueType
241-
, std::less<ValueType>
241+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
242242
, typename allocator_traits<VoidAllocator>
243243
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
244244
, typename boost::container::tree_assoc_options
@@ -489,6 +489,15 @@ int main ()
489489
std::cout << "Error in map_test<new_allocator<void>, red_black_tree>" << std::endl;
490490
return 1;
491491
}
492+
493+
if (0 != test::map_test
494+
< GetAllocatorMap<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::map_type
495+
, MyStdMap
496+
, GetAllocatorMap<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::multimap_type
497+
, MyStdMultiMap>()) {
498+
std::cout << "Error in map_test<new_allocator<void>, red_black_tree>>, transparent" << std::endl;
499+
return 1;
500+
}
492501
}
493502

494503
////////////////////////////////////

test/set_test.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
//////////////////////////////////////////////////////////////////////////////
23
//
34
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
@@ -346,14 +347,14 @@ bool constructor_template_auto_deduction_test()
346347

347348
}}} //boost::container::test
348349

349-
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
350+
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value, bool Transparent = false>
350351
struct GetAllocatorSet
351352
{
352353
template<class ValueType>
353354
struct apply
354355
{
355356
typedef set < ValueType
356-
, std::less<ValueType>
357+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
357358
, typename allocator_traits<VoidAllocator>
358359
::template portable_rebind_alloc<ValueType>::type
359360
, typename boost::container::tree_assoc_options
@@ -362,7 +363,7 @@ struct GetAllocatorSet
362363
> set_type;
363364

364365
typedef multiset < ValueType
365-
, std::less<ValueType>
366+
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
366367
, typename allocator_traits<VoidAllocator>
367368
::template portable_rebind_alloc<ValueType>::type
368369
, typename boost::container::tree_assoc_options
@@ -504,6 +505,24 @@ int main ()
504505
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
505506
return 1;
506507
}
508+
509+
if (0 != test::set_test
510+
< GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::moveconstruct_int>::set_type
511+
, MyStdSet
512+
, GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::moveconstruct_int>::multiset_type
513+
, MyStdMultiSet>()) {
514+
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
515+
return 1;
516+
}
517+
518+
if (0 != test::set_test
519+
< GetAllocatorSet<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::set_type
520+
, MyStdSet
521+
, GetAllocatorSet<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::multiset_type
522+
, MyStdMultiSet>()) {
523+
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>>, transparent" << std::endl;
524+
return 1;
525+
}
507526
}
508527

509528
////////////////////////////////////
@@ -621,3 +640,17 @@ int main ()
621640

622641
return 0;
623642
}
643+
644+
/*
645+
#include <boost/container/set.hpp>
646+
#include <functional>
647+
648+
int main()
649+
{
650+
using set = boost::container::set<int, std::less<>>;
651+
652+
set s;
653+
const set cs;
654+
s.insert(cs.begin(), cs.end());
655+
}
656+
*/

0 commit comments

Comments
 (0)