From: Jonathan Wakely Date: Tue, 20 Jan 2015 11:50:58 +0000 (+0000) Subject: Implement N3657: heterogeneous lookup in associative containers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91c78ea5b6532c06298ffb6483a25ee573a52ed0;p=gcc.git 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 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7410bbccfe0..3274825b593 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2015-01-20 Jonathan Wakely + + * 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 * config/abi/pre/gnu.ver: Export new constructors. diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 3bac4e08982..df18973931e 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 friend bool operator==(const map<_K1, _T1, _C1, _A1>&, diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 5a81f8ffad6..f3d21ab8bea 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 friend bool operator==(const multimap<_K1, _T1, _C1, _A1>&, diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index be04221bd12..7e92836aaec 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -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 + 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 + auto + find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x)) + { return _M_t._M_find_tr(__x); } + + template + 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 + auto + lower_bound(const _Kt& __x) + -> decltype(_M_t._M_lower_bound_tr(__x)) + { return _M_t._M_lower_bound_tr(__x); } + + template + 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 + auto + upper_bound(const _Kt& __x) + -> decltype(_M_t._M_upper_bound_tr(__x)) + { return _M_t._M_upper_bound_tr(__x); } + + template + 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 equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } + +#if __cplusplus > 201103L + template + auto + equal_range(const _Kt& __x) + -> decltype(_M_t._M_equal_range_tr(__x)) + { return _M_t._M_equal_range_tr(__x); } + + template + 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 diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 3944bcd52f7..51892343570 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -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 + 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 + auto + find(const _Kt& __x) -> decltype(_M_t._M_find_tr(__x)) + { return _M_t._M_find_tr(__x); } + + template + 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 + auto + lower_bound(const _Kt& __x) + -> decltype(_M_t._M_lower_bound_tr(__x)) + { return _M_t._M_lower_bound_tr(__x); } + + template + 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 + auto + upper_bound(const _Kt& __x) + -> decltype(_M_t._M_upper_bound_tr(__x)) + { return _M_t._M_upper_bound_tr(__x); } + + template + 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 equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } + +#if __cplusplus > 201103L + template + auto + equal_range(const _Kt& __x) + -> decltype(_M_t._M_equal_range_tr(__x)) + { return _M_t._M_equal_range_tr(__x); } + + template + 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 diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index e78b2db1726..5ca8e28ef43 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1118,6 +1118,137 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION pair equal_range(const key_type& __k) const; +#if __cplusplus > 201103L + template> + struct __is_transparent { }; + + template + struct + __is_transparent<_Cmp, _Kt, __void_t> + { 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 + 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 + 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::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::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::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::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::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::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::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::type> + pair + _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::type> + pair + _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; diff --git a/libstdc++-v3/testsuite/23_containers/map/operations/2.cc b/libstdc++-v3/testsuite/23_containers/map/operations/2.cc new file mode 100644 index 00000000000..6cc277aedce --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/map/operations/2.cc @@ -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 +// . + +// { dg-options "-std=gnu++14" } + +#include +#include + +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; + +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(); +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/operations/2.cc b/libstdc++-v3/testsuite/23_containers/multimap/operations/2.cc new file mode 100644 index 00000000000..67c3bfd60a3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multimap/operations/2.cc @@ -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 +// . + +// { dg-options "-std=gnu++14" } + +#include +#include + +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; + +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(); +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/operations/2.cc b/libstdc++-v3/testsuite/23_containers/multiset/operations/2.cc new file mode 100644 index 00000000000..ff2748f713a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/multiset/operations/2.cc @@ -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 +// . + +// { dg-options "-std=gnu++14" } + +#include +#include + +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; + +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(); +} diff --git a/libstdc++-v3/testsuite/23_containers/set/operations/2.cc b/libstdc++-v3/testsuite/23_containers/set/operations/2.cc new file mode 100644 index 00000000000..752bc7dd7a6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/set/operations/2.cc @@ -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 +// . + +// { dg-options "-std=gnu++14" } + +#include +#include + +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; + +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(); +}