Fixes #334 ("Wrong overload resolution protection in implementation of P2363R5") and adds tests with transparent comparator for associative containers.

This commit is contained in:
Ion Gaztañaga
2026-03-22 17:26:15 +01:00
parent 0f99763ea7
commit ce12d2aec5
6 changed files with 88 additions and 33 deletions
+8 -6
View File
@@ -411,7 +411,7 @@ class flat_set
flat_set& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
this->tree_t::insert_unique_range(il.begin(), il.end());
return *this;
}
#endif
@@ -737,10 +737,12 @@ class flat_set
template <class K>
inline BOOST_CONTAINER_DOC1ST
( iterator
, typename dtl::enable_if_transparent< key_compare
BOOST_MOVE_I K
BOOST_MOVE_I iterator
>::type) //transparent
, typename dtl::enable_if_c<
dtl::is_transparent<key_compare>::value && //transparent
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
BOOST_MOVE_I iterator
>::type)
insert(const_iterator p, K &&x)
{ return this->tree_t::insert_unique(p, boost::forward<K>(x)); }
@@ -1549,7 +1551,7 @@ class flat_multiset
flat_multiset& operator=(std::initializer_list<value_type> il)
{
this->clear();
this->insert(il.begin(), il.end());
this->tree_t::insert_equal_range(il.begin(), il.end());
return *this;
}
#endif
+6 -4
View File
@@ -656,10 +656,12 @@ class set
template <class K>
inline BOOST_CONTAINER_DOC1ST
( iterator
, typename dtl::enable_if_transparent< key_compare
BOOST_MOVE_I K
BOOST_MOVE_I iterator
>::type) //transparent
, typename dtl::enable_if_c<
dtl::is_transparent<key_compare>::value && //transparent
!dtl::is_convertible<K BOOST_MOVE_I iterator>::value && //not convertible to iterator
!dtl::is_convertible<K BOOST_MOVE_I const_iterator>::value //not convertible to const_iterator
BOOST_MOVE_I iterator
>::type)
insert(const_iterator p, K &&x)
{ return this->base_t::insert_unique_hint_convertible(p, boost::forward<K>(x)); }
+14 -14
View File
@@ -193,7 +193,7 @@ bool constructor_template_auto_deduction_test()
}}}
template<class VoidAllocatorOrContainer>
template<class VoidAllocatorOrContainer, bool Transparent = false>
struct GetMapContainer
{
template<class ValueType>
@@ -202,21 +202,21 @@ struct GetMapContainer
typedef std::pair<ValueType, ValueType> type_t;
typedef flat_map< ValueType
, ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
> map_type;
typedef flat_multimap< ValueType
, ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, type_t>::type
> multimap_type;
};
};
//To test default parameters
template<>
struct GetMapContainer<void>
template<bool Transparent>
struct GetMapContainer<void, Transparent>
{
template<class ValueType>
struct apply
@@ -389,15 +389,6 @@ int main()
return 1;
}
if (0 != test::flat_map_test
< GetMapContainer<void>::apply<int>::map_type
, MyStdMap
, GetMapContainer<void>::apply<int>::multimap_type
, MyStdMultiMap>()) {
std::cout << "Error in flat_map_test<new_allocator<void> >" << std::endl;
return 1;
}
if (0 != test::flat_map_test
< GetMapContainer<new_allocator<void> >::apply<int>::map_type
, MyStdMap
@@ -433,6 +424,15 @@ int main()
std::cout << "Error in flat_map_test<new_allocator<void> >" << std::endl;
return 1;
}
if (0 != test::flat_map_test
< GetMapContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::map_type
, MyStdMap
, GetMapContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::multimap_type
, MyStdMultiMap>()) {
std::cout << "Error in flat_map_test<new_allocator<void>, transparent >" << std::endl;
return 1;
}
}
if(!boost::container::test::test_map_support_for_initialization_list_for<flat_map<int, int> >())
+12 -3
View File
@@ -532,19 +532,19 @@ bool test_heterogeneous_lookup_by_partial_key()
}}}
template<class VoidAllocatorOrContainer>
template<class VoidAllocatorOrContainer, bool Transparent = false>
struct GetSetContainer
{
template<class ValueType>
struct apply
{
typedef flat_set < ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
> set_type;
typedef flat_multiset < ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename boost::container::dtl::container_or_allocator_rebind<VoidAllocatorOrContainer, ValueType>::type
> multiset_type;
};
@@ -733,6 +733,15 @@ int main()
std::cout << "Error in set_test<new_allocator<void> >" << std::endl;
return 1;
}
if (0 != test::set_test
< GetSetContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::set_type
, MyStdSet
, GetSetContainer<new_allocator<void>, true>::apply<test::movable_and_copyable_int>::multiset_type
, MyStdMultiSet>()) {
std::cout << "Error in set_test<new_allocator<void> >>, transparent" << std::endl;
return 1;
}
}
////////////////////////////////////
+12 -3
View File
@@ -220,7 +220,7 @@ bool node_type_test()
return true;
}
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value, bool Transparent = false>
struct GetAllocatorMap
{
template<class ValueType>
@@ -228,7 +228,7 @@ struct GetAllocatorMap
{
typedef map< ValueType
, ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename allocator_traits<VoidAllocator>
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
, typename boost::container::tree_assoc_options
@@ -238,7 +238,7 @@ struct GetAllocatorMap
typedef multimap< ValueType
, ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename allocator_traits<VoidAllocator>
::template portable_rebind_alloc< std::pair<const ValueType, ValueType> >::type
, typename boost::container::tree_assoc_options
@@ -489,6 +489,15 @@ int main ()
std::cout << "Error in map_test<new_allocator<void>, red_black_tree>" << std::endl;
return 1;
}
if (0 != test::map_test
< GetAllocatorMap<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::map_type
, MyStdMap
, GetAllocatorMap<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::multimap_type
, MyStdMultiMap>()) {
std::cout << "Error in map_test<new_allocator<void>, red_black_tree>>, transparent" << std::endl;
return 1;
}
}
////////////////////////////////////
+36 -3
View File
@@ -1,3 +1,4 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
@@ -346,14 +347,14 @@ bool constructor_template_auto_deduction_test()
}}} //boost::container::test
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value>
template<class VoidAllocator, boost::container::tree_type_enum tree_type_value, bool Transparent = false>
struct GetAllocatorSet
{
template<class ValueType>
struct apply
{
typedef set < ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename allocator_traits<VoidAllocator>
::template portable_rebind_alloc<ValueType>::type
, typename boost::container::tree_assoc_options
@@ -362,7 +363,7 @@ struct GetAllocatorSet
> set_type;
typedef multiset < ValueType
, std::less<ValueType>
, typename dtl::if_c<Transparent, test::less_transparent, std::less<ValueType> >::type
, typename allocator_traits<VoidAllocator>
::template portable_rebind_alloc<ValueType>::type
, typename boost::container::tree_assoc_options
@@ -504,6 +505,24 @@ int main ()
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
return 1;
}
if (0 != test::set_test
< GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::moveconstruct_int>::set_type
, MyStdSet
, GetAllocatorSet<new_allocator<void>, red_black_tree>::apply<test::moveconstruct_int>::multiset_type
, MyStdMultiSet>()) {
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>" << std::endl;
return 1;
}
if (0 != test::set_test
< GetAllocatorSet<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::set_type
, MyStdSet
, GetAllocatorSet<new_allocator<void>, red_black_tree, true>::apply<test::movable_and_copyable_int>::multiset_type
, MyStdMultiSet>()) {
std::cout << "Error in set_test<new_allocator<void>, red_black_tree>>, transparent" << std::endl;
return 1;
}
}
////////////////////////////////////
@@ -621,3 +640,17 @@ int main ()
return 0;
}
/*
#include <boost/container/set.hpp>
#include <functional>
int main()
{
using set = boost::container::set<int, std::less<>>;
set s;
const set cs;
s.insert(cs.begin(), cs.end());
}
*/