Implement N3657: heterogeneous lookup in associative containers.

* include/bits/stl_map.h (map::find<>, map::count<>,
	map::lower_bound<>, map::upper_bound<>, map::equal_range<>): New
	member function templates to perform heterogeneous lookup.
	* include/bits/stl_multimap.h (multimap::find<>, multimap::count<>,
	multimap::lower_bound<>, multimap::upper_bound<>,
	multimap::equal_range<>): Likewise.
	* include/bits/stl_multiset.h (multiset::find<>, multiset::count<>,
	multiset::lower_bound<>, multiset::upper_bound<>,
	multiset::equal_range<>): Likewise.
	* include/bits/stl_set.h (set::find<>, set::count<>,
	set::lower_bound<>, set::upper_bound<>, set::equal_range<>): Likewise.
	* include/bits/stl_tree.h (_Rb_tree::_S_lower_bound_tr,
	_Rb_tree::_S_upper_bound_tr, _Rb_tree::_M_find_tr,
	_Rb_tree::_M_count_tr, _Rb_tree::_M_lower_bound_tr,
	_Rb_tree::_M_upper_bound_tr, _Rb_tree::_M_equal_range_tr): Likewise.
	* testsuite/23_containers/map/operations/2.cc: New.
	* testsuite/23_containers/multimap/operations/2.cc: New.
	* testsuite/23_containers/multiset/operations/2.cc: New.
	* testsuite/23_containers/set/operations/2.cc: New.

From-SVN: r219888
This commit is contained in:
Jonathan Wakely 2015-01-20 11:50:58 +00:00 committed by Jonathan Wakely
parent 71a16cd8bc
commit 91c78ea5b6
10 changed files with 1020 additions and 0 deletions

View File

@ -1,3 +1,25 @@
2015-01-20 Jonathan Wakely <jwakely@redhat.com>
* include/bits/stl_map.h (map::find<>, map::count<>,
map::lower_bound<>, map::upper_bound<>, map::equal_range<>): New
member function templates to perform heterogeneous lookup.
* include/bits/stl_multimap.h (multimap::find<>, multimap::count<>,
multimap::lower_bound<>, multimap::upper_bound<>,
multimap::equal_range<>): Likewise.
* include/bits/stl_multiset.h (multiset::find<>, multiset::count<>,
multiset::lower_bound<>, multiset::upper_bound<>,
multiset::equal_range<>): Likewise.
* include/bits/stl_set.h (set::find<>, set::count<>,
set::lower_bound<>, set::upper_bound<>, set::equal_range<>): Likewise.
* include/bits/stl_tree.h (_Rb_tree::_S_lower_bound_tr,
_Rb_tree::_S_upper_bound_tr, _Rb_tree::_M_find_tr,
_Rb_tree::_M_count_tr, _Rb_tree::_M_lower_bound_tr,
_Rb_tree::_M_upper_bound_tr, _Rb_tree::_M_equal_range_tr): Likewise.
* testsuite/23_containers/map/operations/2.cc: New.
* testsuite/23_containers/multimap/operations/2.cc: New.
* testsuite/23_containers/multiset/operations/2.cc: New.
* testsuite/23_containers/set/operations/2.cc: New.
2015-01-20 Jonathan Wakely <jwakely@redhat.com>
* config/abi/pre/gnu.ver: Export new constructors.

View File

@ -824,6 +824,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return value_compare(_M_t.key_comp()); }
// [23.3.1.3] map operations
//@{
/**
* @brief Tries to locate an element in a %map.
* @param __x Key of (key, value) %pair to be located.
@ -835,10 +837,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* pointing to the sought after %pair. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
iterator
find(const key_type& __x)
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
/**
* @brief Tries to locate an element in a %map.
* @param __x Key of (key, value) %pair to be located.
@ -850,10 +862,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* iterator pointing to the sought after %pair. If unsuccessful it
* returns the past-the-end ( @c end() ) iterator.
*/
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of (key, value) pairs to be located.
@ -866,6 +888,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
#if __cplusplus > 201103L
template<typename _Kt>
auto
count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
{ return _M_t._M_find_tr(__x) == _M_t.end() ? 0 : 1; }
#endif
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -881,6 +912,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -896,6 +937,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -906,6 +957,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -916,6 +977,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@ -935,6 +1006,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x)
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@ -954,6 +1035,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const map<_K1, _T1, _C1, _A1>&,

View File

@ -734,6 +734,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
{ return value_compare(_M_t.key_comp()); }
// multimap operations
//@{
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
@ -749,6 +751,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
find(const key_type& __x)
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
/**
* @brief Tries to locate an element in a %multimap.
* @param __x Key of (key, value) pair to be located.
@ -764,6 +775,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
find(const key_type& __x) const
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of (key, value) pairs to be located.
@ -773,6 +793,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.count(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
{ return _M_t._M_count_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -788,6 +817,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x)
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -803,6 +842,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -813,6 +862,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x)
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds the end of a subsequence matching given key.
* @param __x Key of (key, value) pair to be located.
@ -823,6 +882,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@ -840,6 +909,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x)
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
//@{
/**
* @brief Finds a subsequence matching given key.
* @param __x Key of (key, value) pairs to be located.
@ -857,6 +936,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const multimap<_K1, _T1, _C1, _A1>&,

View File

@ -636,6 +636,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// multiset operations:
//@{
/**
* @brief Finds the number of elements with given key.
* @param __x Key of elements to be located.
@ -645,6 +646,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.count(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
count(const _Kt& __x) const -> decltype(_M_t._M_count_tr(__x))
{ return _M_t._M_count_tr(__x); }
#endif
//@}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
@ -666,6 +675,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
template<typename _Kt>
auto
find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
@ -687,6 +708,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
@ -703,6 +738,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
@ -728,6 +777,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x)
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
template<typename _K1, typename _C1, typename _A1>

View File

@ -651,6 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// set operations:
//@{
/**
* @brief Finds the number of elements.
* @param __x Element to located.
@ -663,6 +664,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
#if __cplusplus > 201103L
template<typename _Kt>
auto
count(const _Kt& __x) const
-> decltype(_M_t._M_count_tr(__x))
{ return _M_t._M_find_tr(__x) == _M_t.end() ? 0 : 1; }
#endif
//@}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 214. set::find() missing const overload
//@{
@ -684,6 +694,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
template<typename _Kt>
auto
find(const _Kt& __x) const -> decltype(_M_t._M_find_tr(__x))
{ return _M_t._M_find_tr(__x); }
#endif
//@}
//@{
@ -705,6 +727,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
lower_bound(const key_type& __x) const
{ return _M_t.lower_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
lower_bound(const _Kt& __x)
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
template<typename _Kt>
auto
lower_bound(const _Kt& __x) const
-> decltype(_M_t._M_lower_bound_tr(__x))
{ return _M_t._M_lower_bound_tr(__x); }
#endif
//@}
//@{
@ -721,6 +757,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
const_iterator
upper_bound(const key_type& __x) const
{ return _M_t.upper_bound(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
upper_bound(const _Kt& __x)
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
template<typename _Kt>
auto
upper_bound(const _Kt& __x) const
-> decltype(_M_t._M_upper_bound_tr(__x))
{ return _M_t._M_upper_bound_tr(__x); }
#endif
//@}
//@{
@ -746,6 +796,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
#if __cplusplus > 201103L
template<typename _Kt>
auto
equal_range(const _Kt& __x)
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
template<typename _Kt>
auto
equal_range(const _Kt& __x) const
-> decltype(_M_t._M_equal_range_tr(__x))
{ return _M_t._M_equal_range_tr(__x); }
#endif
//@}
template<typename _K1, typename _C1, typename _A1>

View File

@ -1118,6 +1118,137 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pair<const_iterator, const_iterator>
equal_range(const key_type& __k) const;
#if __cplusplus > 201103L
template<typename _Cmp, typename _Kt, typename = __void_t<>>
struct __is_transparent { };
template<typename _Cmp, typename _Kt>
struct
__is_transparent<_Cmp, _Kt, __void_t<typename _Cmp::is_transparent>>
{ typedef void type; };
static auto _S_iter(_Link_type __x) { return iterator(__x); }
static auto _S_iter(_Const_Link_type __x) { return const_iterator(__x); }
template<typename _Cmp, typename _Link, typename _Kt>
static auto
_S_lower_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
{
while (__x != 0)
if (!__cmp(_S_key(__x), __k))
__y = __x, __x = _S_left(__x);
else
__x = _S_right(__x);
return _S_iter(__y);
}
template<typename _Cmp, typename _Link, typename _Kt>
static auto
_S_upper_bound_tr(_Cmp& __cmp, _Link __x, _Link __y, const _Kt& __k)
{
while (__x != 0)
if (__cmp(__k, _S_key(__x)))
__y = __x, __x = _S_left(__x);
else
__x = _S_right(__x);
return _S_iter(__y);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
iterator
_M_find_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
? end() : __j;
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
const_iterator
_M_find_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
auto __j = _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
return (__j == end() || __cmp(__k, _S_key(__j._M_node)))
? end() : __j;
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
size_type
_M_count_tr(const _Kt& __k) const
{
auto __p = _M_equal_range_tr(__k);
return std::distance(__p.first, __p.second);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
iterator
_M_lower_bound_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
const_iterator
_M_lower_bound_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
iterator
_M_upper_bound_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
const_iterator
_M_upper_bound_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
pair<iterator, iterator>
_M_equal_range_tr(const _Kt& __k)
{
auto __low = _M_lower_bound_tr(__k);
auto __high = __low;
auto& __cmp = _M_impl._M_key_compare;
while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
++__high;
return { __low, __high };
}
template<typename _Kt,
typename _Req = typename __is_transparent<_Compare, _Kt>::type>
pair<const_iterator, const_iterator>
_M_equal_range_tr(const _Kt& __k) const
{
auto __low = _M_lower_bound_tr(__k);
auto __high = __low;
auto& __cmp = _M_impl._M_key_compare;
while (__high != end() && !__cmp(__k, _S_key(__high._M_node)))
++__high;
return { __low, __high };
}
#endif
// Debugging.
bool
__rb_verify() const;

View File

@ -0,0 +1,140 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++14" }
#include <map>
#include <testsuite_hooks.h>
struct Cmp
{
typedef void is_transparent;
bool operator()(int i, long l) const { return i < l; }
bool operator()(long l, int i) const { return l < i; }
bool operator()(int i, int j) const { ++count; return i < j; }
static int count;
};
int Cmp::count = 0;
using test_type = std::map<int, char, Cmp>;
test_type x{ { 1, '2' }, { 3, '4' } };
const test_type& cx = x;
void
test01()
{
Cmp::count = 0;
auto it = x.find(1L);
VERIFY( it != x.end() && it->second == '2' );
it = x.find(2L);
VERIFY( it == x.end() );
auto cit = cx.find(3L);
VERIFY( cit != cx.end() && cit->second == '4' );
cit = cx.find(2L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test02()
{
Cmp::count = 0;
auto n = x.count(1L);
VERIFY( n == 1 );
n = x.count(2L);
VERIFY( n == 0 );
auto cn = cx.count(3L);
VERIFY( cn == 1 );
cn = cx.count(2L);
VERIFY( cn == 0 );
VERIFY( Cmp::count == 0);
}
void
test03()
{
Cmp::count = 0;
auto it = x.lower_bound(1L);
VERIFY( it != x.end() && it->second == '2' );
it = x.lower_bound(2L);
VERIFY( it != x.end() && it->second == '4' );
auto cit = cx.lower_bound(1L);
VERIFY( cit != cx.end() && cit->second == '2' );
cit = cx.lower_bound(2L);
VERIFY( cit != cx.end() && cit->second == '4' );
VERIFY( Cmp::count == 0);
}
void
test04()
{
Cmp::count = 0;
auto it = x.upper_bound(1L);
VERIFY( it != x.end() && it->second == '4' );
it = x.upper_bound(3L);
VERIFY( it == x.end() );
auto cit = cx.upper_bound(1L);
VERIFY( cit != cx.end() && cit->second == '4' );
cit = cx.upper_bound(3L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test05()
{
Cmp::count = 0;
auto it = x.equal_range(1L);
VERIFY( it.first != it.second && it.first->second == '2' );
it = x.equal_range(2L);
VERIFY( it.first == it.second && it.first != x.end() );
auto cit = cx.equal_range(1L);
VERIFY( cit.first != cit.second && cit.first->second == '2' );
cit = cx.equal_range(2L);
VERIFY( cit.first == cit.second && cit.first != cx.end() );
VERIFY( Cmp::count == 0);
}
int
main()
{
test01();
test02();
test03();
test04();
test05();
}

View File

@ -0,0 +1,141 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++14" }
#include <map>
#include <testsuite_hooks.h>
struct Cmp
{
typedef void is_transparent;
bool operator()(int i, long l) const { return i < l; }
bool operator()(long l, int i) const { return l < i; }
bool operator()(int i, int j) const { ++count; return i < j; }
static int count;
};
int Cmp::count = 0;
using test_type = std::multimap<int, char, Cmp>;
test_type x{ { 1, '2' }, { 3, '4' }, { 3, '5' } };
const test_type& cx = x;
void
test01()
{
Cmp::count = 0;
auto it = x.find(1L);
VERIFY( it != x.end() && it->second == '2' );
it = x.find(2L);
VERIFY( it == x.end() );
auto cit = cx.find(3L);
VERIFY( cit != cx.end() && cit->second == '4' );
cit = cx.find(2L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test02()
{
Cmp::count = 0;
auto n = x.count(1L);
VERIFY( n == 1 );
n = x.count(2L);
VERIFY( n == 0 );
auto cn = cx.count(3L);
VERIFY( cn == 2 );
cn = cx.count(2L);
VERIFY( cn == 0 );
VERIFY( Cmp::count == 0);
}
void
test03()
{
Cmp::count = 0;
auto it = x.lower_bound(1L);
VERIFY( it != x.end() && it->second == '2' );
it = x.lower_bound(2L);
VERIFY( it != x.end() && it->second == '4' );
auto cit = cx.lower_bound(1L);
VERIFY( cit != cx.end() && cit->second == '2' );
cit = cx.lower_bound(2L);
VERIFY( cit != cx.end() && cit->second == '4' );
VERIFY( Cmp::count == 0);
}
void
test04()
{
Cmp::count = 0;
auto it = x.upper_bound(1L);
VERIFY( it != x.end() && it->second == '4' );
it = x.upper_bound(3L);
VERIFY( it == x.end() );
auto cit = cx.upper_bound(1L);
VERIFY( cit != cx.end() && cit->second == '4' );
cit = cx.upper_bound(3L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test05()
{
Cmp::count = 0;
auto it = x.equal_range(1L);
VERIFY( it.first != it.second && it.first->second == '2' );
it = x.equal_range(2L);
VERIFY( it.first == it.second && it.first != x.end() );
auto cit = cx.equal_range(3L);
VERIFY( cit.first != cit.second && cit.first->second == '4' );
VERIFY( std::distance(cit.first, cit.second) == 2 );
cit = cx.equal_range(2L);
VERIFY( cit.first == cit.second && cit.first != cx.end() );
VERIFY( Cmp::count == 0);
}
int
main()
{
test01();
test02();
test03();
test04();
test05();
}

View File

@ -0,0 +1,141 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++14" }
#include <set>
#include <testsuite_hooks.h>
struct Cmp
{
typedef void is_transparent;
bool operator()(int i, long l) const { return i < l; }
bool operator()(long l, int i) const { return l < i; }
bool operator()(int i, int j) const { ++count; return i < j; }
static int count;
};
int Cmp::count = 0;
using test_type = std::multiset<int, Cmp>;
test_type x{ 1, 3, 3, 5 };
const test_type& cx = x;
void
test01()
{
Cmp::count = 0;
auto it = x.find(1L);
VERIFY( it != x.end() && *it == 1 );
it = x.find(2L);
VERIFY( it == x.end() );
auto cit = cx.find(3L);
VERIFY( cit != cx.end() && *cit == 3 );
cit = cx.find(2L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test02()
{
Cmp::count = 0;
auto n = x.count(1L);
VERIFY( n == 1 );
n = x.count(2L);
VERIFY( n == 0 );
auto cn = cx.count(3L);
VERIFY( cn == 2 );
cn = cx.count(2L);
VERIFY( cn == 0 );
VERIFY( Cmp::count == 0);
}
void
test03()
{
Cmp::count = 0;
auto it = x.lower_bound(1L);
VERIFY( it != x.end() && *it == 1 );
it = x.lower_bound(2L);
VERIFY( it != x.end() && *it == 3 );
auto cit = cx.lower_bound(1L);
VERIFY( cit != cx.end() && *cit == 1 );
cit = cx.lower_bound(2L);
VERIFY( cit != cx.end() && *cit == 3 );
VERIFY( Cmp::count == 0);
}
void
test04()
{
Cmp::count = 0;
auto it = x.upper_bound(1L);
VERIFY( it != x.end() && *it == 3 );
it = x.upper_bound(5L);
VERIFY( it == x.end() );
auto cit = cx.upper_bound(1L);
VERIFY( cit != cx.end() && *cit == 3 );
cit = cx.upper_bound(5L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test05()
{
Cmp::count = 0;
auto it = x.equal_range(1L);
VERIFY( it.first != it.second && *it.first == 1 );
it = x.equal_range(2L);
VERIFY( it.first == it.second && it.first != x.end() );
auto cit = cx.equal_range(3L);
VERIFY( cit.first != cit.second && *cit.first == 3 );
VERIFY( std::distance(cit.first, cit.second) == 2 );
cit = cx.equal_range(2L);
VERIFY( cit.first == cit.second && cit.first != cx.end() );
VERIFY( Cmp::count == 0);
}
int
main()
{
test01();
test02();
test03();
test04();
test05();
}

View File

@ -0,0 +1,140 @@
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++14" }
#include <set>
#include <testsuite_hooks.h>
struct Cmp
{
typedef void is_transparent;
bool operator()(int i, long l) const { return i < l; }
bool operator()(long l, int i) const { return l < i; }
bool operator()(int i, int j) const { ++count; return i < j; }
static int count;
};
int Cmp::count = 0;
using test_type = std::set<int, Cmp>;
test_type x{ 1, 3, 5 };
const test_type& cx = x;
void
test01()
{
Cmp::count = 0;
auto it = x.find(1L);
VERIFY( it != x.end() && *it == 1 );
it = x.find(2L);
VERIFY( it == x.end() );
auto cit = cx.find(3L);
VERIFY( cit != cx.end() && *cit == 3 );
cit = cx.find(2L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test02()
{
Cmp::count = 0;
auto n = x.count(1L);
VERIFY( n == 1 );
n = x.count(2L);
VERIFY( n == 0 );
auto cn = cx.count(3L);
VERIFY( cn == 1 );
cn = cx.count(2L);
VERIFY( cn == 0 );
VERIFY( Cmp::count == 0);
}
void
test03()
{
Cmp::count = 0;
auto it = x.lower_bound(1L);
VERIFY( it != x.end() && *it == 1 );
it = x.lower_bound(2L);
VERIFY( it != x.end() && *it == 3 );
auto cit = cx.lower_bound(1L);
VERIFY( cit != cx.end() && *cit == 1 );
cit = cx.lower_bound(2L);
VERIFY( cit != cx.end() && *cit == 3 );
VERIFY( Cmp::count == 0);
}
void
test04()
{
Cmp::count = 0;
auto it = x.upper_bound(1L);
VERIFY( it != x.end() && *it == 3 );
it = x.upper_bound(5L);
VERIFY( it == x.end() );
auto cit = cx.upper_bound(1L);
VERIFY( cit != cx.end() && *cit == 3 );
cit = cx.upper_bound(5L);
VERIFY( cit == cx.end() );
VERIFY( Cmp::count == 0);
}
void
test05()
{
Cmp::count = 0;
auto it = x.equal_range(1L);
VERIFY( it.first != it.second && *it.first == 1 );
it = x.equal_range(2L);
VERIFY( it.first == it.second && it.first != x.end() );
auto cit = cx.equal_range(1L);
VERIFY( cit.first != cit.second && *cit.first == 1 );
cit = cx.equal_range(2L);
VERIFY( cit.first == cit.second && cit.first != cx.end() );
VERIFY( Cmp::count == 0);
}
int
main()
{
test01();
test02();
test03();
test04();
test05();
}