diff --git a/include/__functional_base b/include/__functional_base index 8ecc35b7..72da7597 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -68,6 +68,7 @@ struct _LIBCPP_TYPE_VIS_ONLY less template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -501,6 +502,20 @@ template void cref(const _Tp&&);// = delete; #endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 11 +template +struct __is_transparent +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename _Up::is_transparent* = 0); +public: + static const bool value = sizeof(__test<_Tp1>(0)) == 1; +}; +#endif + + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL_BASE diff --git a/include/functional b/include/functional index 287bf72e..1486a8e0 100644 --- a/include/functional +++ b/include/functional @@ -515,6 +515,7 @@ struct _LIBCPP_TYPE_VIS_ONLY plus template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -537,6 +538,7 @@ struct _LIBCPP_TYPE_VIS_ONLY minus template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -559,6 +561,7 @@ struct _LIBCPP_TYPE_VIS_ONLY multiplies template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -581,6 +584,7 @@ struct _LIBCPP_TYPE_VIS_ONLY divides template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -603,6 +607,7 @@ struct _LIBCPP_TYPE_VIS_ONLY modulus template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -625,6 +630,7 @@ struct _LIBCPP_TYPE_VIS_ONLY negate template _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const { return -_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; }; #endif @@ -647,6 +653,7 @@ struct _LIBCPP_TYPE_VIS_ONLY equal_to template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -669,6 +676,7 @@ struct _LIBCPP_TYPE_VIS_ONLY not_equal_to template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -691,6 +699,7 @@ struct _LIBCPP_TYPE_VIS_ONLY greater template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -715,6 +724,7 @@ struct _LIBCPP_TYPE_VIS_ONLY greater_equal template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -737,6 +747,7 @@ struct _LIBCPP_TYPE_VIS_ONLY less_equal template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -759,6 +770,7 @@ struct _LIBCPP_TYPE_VIS_ONLY logical_and template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -781,6 +793,7 @@ struct _LIBCPP_TYPE_VIS_ONLY logical_or template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -803,6 +816,7 @@ struct _LIBCPP_TYPE_VIS_ONLY logical_not template _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const { return !_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; }; #endif @@ -825,6 +839,7 @@ struct _LIBCPP_TYPE_VIS_ONLY bit_and template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -847,6 +862,7 @@ struct _LIBCPP_TYPE_VIS_ONLY bit_or template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -869,6 +885,7 @@ struct _LIBCPP_TYPE_VIS_ONLY bit_xor template _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } + typedef void is_transparent; }; #endif @@ -887,6 +904,7 @@ struct _LIBCPP_TYPE_VIS_ONLY bit_not template _LIBCPP_INLINE_VISIBILITY auto operator()(_Tp&& __x) const { return ~_VSTD::forward<_Tp>(__x); } + typedef void is_transparent; }; #endif diff --git a/include/set b/include/set index d714c1ac..70b8d28f 100644 --- a/include/set +++ b/include/set @@ -129,13 +129,33 @@ public: // set operations: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template + iterator find(const K& x); + template + const_iterator find(const K& x) const; // C++14 + template + size_type count(const K& x) const; // C++14 + size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); const_iterator lower_bound(const key_type& k) const; + template + iterator lower_bound(const K& x); // C++14 + template + const_iterator lower_bound(const K& x) const; // C++14 + iterator upper_bound(const key_type& k); const_iterator upper_bound(const key_type& k) const; + template + iterator upper_bound(const K& x); // C++14 + template + const_iterator upper_bound(const K& x) const; // C++14 pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; + template + pair equal_range(const K& x); // C++14 + template + pair equal_range(const K& x) const; // C++14 }; template @@ -285,13 +305,32 @@ public: // set operations: iterator find(const key_type& k); const_iterator find(const key_type& k) const; + template + iterator find(const K& x); + template + const_iterator find(const K& x) const; // C++14 + size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); const_iterator lower_bound(const key_type& k) const; + template + iterator lower_bound(const K& x); // C++14 + template + const_iterator lower_bound(const K& x) const; // C++14 + iterator upper_bound(const key_type& k); const_iterator upper_bound(const key_type& k) const; + template + iterator upper_bound(const K& x); // C++14 + template + const_iterator upper_bound(const K& x) const; // C++14 + pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; + template + pair equal_range(const K& x); // C++14 + template + pair equal_range(const K& x) const; // C++14 }; template @@ -579,6 +618,17 @@ public: iterator find(const key_type& __k) {return __tree_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __tree_.find(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + find(const _K2& __k) {return __tree_.find(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + find(const _K2& __k) const {return __tree_.find(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_unique(__k);} @@ -588,18 +638,51 @@ public: _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const key_type& __k) const {return __tree_.lower_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} + + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const key_type& __k) {return __tree_.upper_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const key_type& __k) const {return __tree_.upper_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type + upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type + upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __tree_.__equal_range_unique(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __tree_.__equal_range_unique(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);} +#endif }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -917,27 +1000,72 @@ public: iterator find(const key_type& __k) {return __tree_.find(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator find(const key_type& __k) const {return __tree_.find(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type + find(const _K2& __k) {return __tree_.find(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type + find(const _K2& __k) const {return __tree_.find(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_multi(__k);} + _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const key_type& __k) const {return __tree_.lower_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type + lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} + + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type + lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const key_type& __k) {return __tree_.upper_bound(__k);} _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const key_type& __k) const {return __tree_.upper_bound(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,iterator>::type + upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,const_iterator>::type + upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} +#endif + _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) {return __tree_.__equal_range_multi(__k);} _LIBCPP_INLINE_VISIBILITY pair equal_range(const key_type& __k) const {return __tree_.__equal_range_multi(__k);} +#if _LIBCPP_STD_VER > 11 + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} + template + _LIBCPP_INLINE_VISIBILITY + typename _VSTD::enable_if<_VSTD::__is_transparent<_Compare, _K2>::value,pair>::type + equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} +#endif }; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/test/containers/associative/multiset/equal_range.pass.cpp b/test/containers/associative/multiset/equal_range.pass.cpp index fee94bc9..37acec8f 100644 --- a/test/containers/associative/multiset/equal_range.pass.cpp +++ b/test/containers/associative/multiset/equal_range.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -179,4 +180,84 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::multiset> M; + typedef std::pair R; + V ar[] = + { + 5, + 5, + 5, + 7, + 7, + 7, + 9, + 9, + 9 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.equal_range(4); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 0)); + r = m.equal_range(5); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(6); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(7); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(8); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(9); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 9)); + r = m.equal_range(10); + assert(r.first == next(m.begin(), 9)); + assert(r.second == next(m.begin(), 9)); + } + + { + typedef PrivateConstructor V; + typedef std::multiset> M; + typedef std::pair R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + + R r = m.equal_range(4); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 0)); + r = m.equal_range(5); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(6); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(7); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(8); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(9); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 9)); + r = m.equal_range(10); + assert(r.first == next(m.begin(), 9)); + assert(r.second == next(m.begin(), 9)); + } +#endif } diff --git a/test/containers/associative/multiset/find.pass.cpp b/test/containers/associative/multiset/find.pass.cpp index 53b1844e..b4963e9d 100644 --- a/test/containers/associative/multiset/find.pass.cpp +++ b/test/containers/associative/multiset/find.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -163,4 +164,77 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::multiset> M; + typedef M::iterator R; + + V ar[] = + { + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.find(5); + assert(r == m.begin()); + r = m.find(6); + assert(r == next(m.begin())); + r = m.find(7); + assert(r == next(m.begin(), 2)); + r = m.find(8); + assert(r == next(m.begin(), 3)); + r = m.find(9); + assert(r == next(m.begin(), 4)); + r = m.find(10); + assert(r == next(m.begin(), 5)); + r = m.find(11); + assert(r == next(m.begin(), 6)); + r = m.find(12); + assert(r == next(m.begin(), 7)); + r = m.find(4); + assert(r == next(m.begin(), 8)); + } + + { + typedef PrivateConstructor V; + typedef std::multiset> M; + typedef M::iterator R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 6 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 8 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 10 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 12 )); + + R r = m.find(5); + assert(r == m.begin()); + r = m.find(6); + assert(r == next(m.begin())); + r = m.find(7); + assert(r == next(m.begin(), 2)); + r = m.find(8); + assert(r == next(m.begin(), 3)); + r = m.find(9); + assert(r == next(m.begin(), 4)); + r = m.find(10); + assert(r == next(m.begin(), 5)); + r = m.find(11); + assert(r == next(m.begin(), 6)); + r = m.find(12); + assert(r == next(m.begin(), 7)); + r = m.find(4); + assert(r == next(m.begin(), 8)); + } +#endif } diff --git a/test/containers/associative/multiset/lower_bound.pass.cpp b/test/containers/associative/multiset/lower_bound.pass.cpp index 537ccd3a..48e297ac 100644 --- a/test/containers/associative/multiset/lower_bound.pass.cpp +++ b/test/containers/associative/multiset/lower_bound.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -151,4 +152,72 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::multiset> M; + + typedef M::iterator R; + V ar[] = + { + 5, + 5, + 5, + 7, + 7, + 7, + 9, + 9, + 9 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + + R r = m.lower_bound(4); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(5); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(6); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(7); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(8); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(9); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(11); + assert(r == next(m.begin(), 9)); + } + + { + typedef PrivateConstructor V; + typedef std::multiset> M; + typedef M::iterator R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + + R r = m.lower_bound(4); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(5); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(6); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(7); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(8); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(9); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(11); + assert(r == next(m.begin(), 9)); + } +#endif } diff --git a/test/containers/associative/multiset/upper_bound.pass.cpp b/test/containers/associative/multiset/upper_bound.pass.cpp index 332254ee..932ab0b1 100644 --- a/test/containers/associative/multiset/upper_bound.pass.cpp +++ b/test/containers/associative/multiset/upper_bound.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -151,4 +152,71 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::multiset> M; + + typedef M::iterator R; + V ar[] = + { + 5, + 5, + 5, + 7, + 7, + 7, + 9, + 9, + 9 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.upper_bound(4); + assert(r == next(m.begin(), 0)); + r = m.upper_bound(5); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(6); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(7); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(8); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(9); + assert(r == next(m.begin(), 9)); + r = m.upper_bound(11); + assert(r == next(m.begin(), 9)); + } + + { + typedef PrivateConstructor V; + typedef std::multiset> M; + + typedef M::iterator R; + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + + R r = m.upper_bound(4); + assert(r == next(m.begin(), 0)); + r = m.upper_bound(5); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(6); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(7); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(8); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(9); + assert(r == next(m.begin(), 9)); + r = m.upper_bound(11); + assert(r == next(m.begin(), 9)); + } +#endif } diff --git a/test/containers/associative/set/equal_range.pass.cpp b/test/containers/associative/set/equal_range.pass.cpp index 95a933ef..5b83887e 100644 --- a/test/containers/associative/set/equal_range.pass.cpp +++ b/test/containers/associative/set/equal_range.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -227,4 +228,143 @@ int main() assert(r.second == next(m.begin(), 8)); } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::set> M; + { + typedef std::pair R; + V ar[] = + { + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.equal_range(5); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 1)); + r = m.equal_range(7); + assert(r.first == next(m.begin(), 1)); + assert(r.second == next(m.begin(), 2)); + r = m.equal_range(9); + assert(r.first == next(m.begin(), 2)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(11); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 4)); + r = m.equal_range(13); + assert(r.first == next(m.begin(), 4)); + assert(r.second == next(m.begin(), 5)); + r = m.equal_range(15); + assert(r.first == next(m.begin(), 5)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(17); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 7)); + r = m.equal_range(19); + assert(r.first == next(m.begin(), 7)); + assert(r.second == next(m.begin(), 8)); + r = m.equal_range(4); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 0)); + r = m.equal_range(6); + assert(r.first == next(m.begin(), 1)); + assert(r.second == next(m.begin(), 1)); + r = m.equal_range(8); + assert(r.first == next(m.begin(), 2)); + assert(r.second == next(m.begin(), 2)); + r = m.equal_range(10); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(12); + assert(r.first == next(m.begin(), 4)); + assert(r.second == next(m.begin(), 4)); + r = m.equal_range(14); + assert(r.first == next(m.begin(), 5)); + assert(r.second == next(m.begin(), 5)); + r = m.equal_range(16); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(18); + assert(r.first == next(m.begin(), 7)); + assert(r.second == next(m.begin(), 7)); + r = m.equal_range(20); + assert(r.first == next(m.begin(), 8)); + assert(r.second == next(m.begin(), 8)); + } + } + { + typedef PrivateConstructor V; + typedef std::set> M; + typedef std::pair R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 13 )); + m.insert ( V::make ( 15 )); + m.insert ( V::make ( 17 )); + m.insert ( V::make ( 19 )); + + R r = m.equal_range(5); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 1)); + r = m.equal_range(7); + assert(r.first == next(m.begin(), 1)); + assert(r.second == next(m.begin(), 2)); + r = m.equal_range(9); + assert(r.first == next(m.begin(), 2)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(11); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 4)); + r = m.equal_range(13); + assert(r.first == next(m.begin(), 4)); + assert(r.second == next(m.begin(), 5)); + r = m.equal_range(15); + assert(r.first == next(m.begin(), 5)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(17); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 7)); + r = m.equal_range(19); + assert(r.first == next(m.begin(), 7)); + assert(r.second == next(m.begin(), 8)); + r = m.equal_range(4); + assert(r.first == next(m.begin(), 0)); + assert(r.second == next(m.begin(), 0)); + r = m.equal_range(6); + assert(r.first == next(m.begin(), 1)); + assert(r.second == next(m.begin(), 1)); + r = m.equal_range(8); + assert(r.first == next(m.begin(), 2)); + assert(r.second == next(m.begin(), 2)); + r = m.equal_range(10); + assert(r.first == next(m.begin(), 3)); + assert(r.second == next(m.begin(), 3)); + r = m.equal_range(12); + assert(r.first == next(m.begin(), 4)); + assert(r.second == next(m.begin(), 4)); + r = m.equal_range(14); + assert(r.first == next(m.begin(), 5)); + assert(r.second == next(m.begin(), 5)); + r = m.equal_range(16); + assert(r.first == next(m.begin(), 6)); + assert(r.second == next(m.begin(), 6)); + r = m.equal_range(18); + assert(r.first == next(m.begin(), 7)); + assert(r.second == next(m.begin(), 7)); + r = m.equal_range(20); + assert(r.first == next(m.begin(), 8)); + assert(r.second == next(m.begin(), 8)); + } +#endif } diff --git a/test/containers/associative/set/find.pass.cpp b/test/containers/associative/set/find.pass.cpp index b661898a..6ce47f8d 100644 --- a/test/containers/associative/set/find.pass.cpp +++ b/test/containers/associative/set/find.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -163,4 +164,77 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::set> M; + typedef M::iterator R; + + V ar[] = + { + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.find(5); + assert(r == m.begin()); + r = m.find(6); + assert(r == next(m.begin())); + r = m.find(7); + assert(r == next(m.begin(), 2)); + r = m.find(8); + assert(r == next(m.begin(), 3)); + r = m.find(9); + assert(r == next(m.begin(), 4)); + r = m.find(10); + assert(r == next(m.begin(), 5)); + r = m.find(11); + assert(r == next(m.begin(), 6)); + r = m.find(12); + assert(r == next(m.begin(), 7)); + r = m.find(4); + assert(r == next(m.begin(), 8)); + } + + { + typedef PrivateConstructor V; + typedef std::set> M; + typedef M::iterator R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 6 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 8 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 10 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 12 )); + + R r = m.find(5); + assert(r == m.begin()); + r = m.find(6); + assert(r == next(m.begin())); + r = m.find(7); + assert(r == next(m.begin(), 2)); + r = m.find(8); + assert(r == next(m.begin(), 3)); + r = m.find(9); + assert(r == next(m.begin(), 4)); + r = m.find(10); + assert(r == next(m.begin(), 5)); + r = m.find(11); + assert(r == next(m.begin(), 6)); + r = m.find(12); + assert(r == next(m.begin(), 7)); + r = m.find(4); + assert(r == next(m.begin(), 8)); + } +#endif } diff --git a/test/containers/associative/set/lower_bound.pass.cpp b/test/containers/associative/set/lower_bound.pass.cpp index 072a5879..1562dfa9 100644 --- a/test/containers/associative/set/lower_bound.pass.cpp +++ b/test/containers/associative/set/lower_bound.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -227,4 +228,110 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::set> M; + typedef M::iterator R; + + V ar[] = + { + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.lower_bound(5); + assert(r == m.begin()); + r = m.lower_bound(7); + assert(r == next(m.begin())); + r = m.lower_bound(9); + assert(r == next(m.begin(), 2)); + r = m.lower_bound(11); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(13); + assert(r == next(m.begin(), 4)); + r = m.lower_bound(15); + assert(r == next(m.begin(), 5)); + r = m.lower_bound(17); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(19); + assert(r == next(m.begin(), 7)); + r = m.lower_bound(4); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(6); + assert(r == next(m.begin(), 1)); + r = m.lower_bound(8); + assert(r == next(m.begin(), 2)); + r = m.lower_bound(10); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(12); + assert(r == next(m.begin(), 4)); + r = m.lower_bound(14); + assert(r == next(m.begin(), 5)); + r = m.lower_bound(16); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(18); + assert(r == next(m.begin(), 7)); + r = m.lower_bound(20); + assert(r == next(m.begin(), 8)); + } + + { + typedef PrivateConstructor V; + typedef std::set> M; + typedef M::iterator R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 13 )); + m.insert ( V::make ( 15 )); + m.insert ( V::make ( 17 )); + m.insert ( V::make ( 19 )); + + R r = m.lower_bound(5); + assert(r == m.begin()); + r = m.lower_bound(7); + assert(r == next(m.begin())); + r = m.lower_bound(9); + assert(r == next(m.begin(), 2)); + r = m.lower_bound(11); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(13); + assert(r == next(m.begin(), 4)); + r = m.lower_bound(15); + assert(r == next(m.begin(), 5)); + r = m.lower_bound(17); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(19); + assert(r == next(m.begin(), 7)); + r = m.lower_bound(4); + assert(r == next(m.begin(), 0)); + r = m.lower_bound(6); + assert(r == next(m.begin(), 1)); + r = m.lower_bound(8); + assert(r == next(m.begin(), 2)); + r = m.lower_bound(10); + assert(r == next(m.begin(), 3)); + r = m.lower_bound(12); + assert(r == next(m.begin(), 4)); + r = m.lower_bound(14); + assert(r == next(m.begin(), 5)); + r = m.lower_bound(16); + assert(r == next(m.begin(), 6)); + r = m.lower_bound(18); + assert(r == next(m.begin(), 7)); + r = m.lower_bound(20); + assert(r == next(m.begin(), 8)); + } +#endif + } diff --git a/test/containers/associative/set/upper_bound.pass.cpp b/test/containers/associative/set/upper_bound.pass.cpp index 3d000d88..5e889d28 100644 --- a/test/containers/associative/set/upper_bound.pass.cpp +++ b/test/containers/associative/set/upper_bound.pass.cpp @@ -18,6 +18,7 @@ #include #include "../../min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -227,4 +228,109 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::set> M; + typedef M::iterator R; + + V ar[] = + { + 5, + 7, + 9, + 11, + 13, + 15, + 17, + 19 + }; + M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.upper_bound(5); + assert(r == next(m.begin(), 1)); + r = m.upper_bound(7); + assert(r == next(m.begin(), 2)); + r = m.upper_bound(9); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(11); + assert(r == next(m.begin(), 4)); + r = m.upper_bound(13); + assert(r == next(m.begin(), 5)); + r = m.upper_bound(15); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(17); + assert(r == next(m.begin(), 7)); + r = m.upper_bound(19); + assert(r == next(m.begin(), 8)); + r = m.upper_bound(4); + assert(r == next(m.begin(), 0)); + r = m.upper_bound(6); + assert(r == next(m.begin(), 1)); + r = m.upper_bound(8); + assert(r == next(m.begin(), 2)); + r = m.upper_bound(10); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(12); + assert(r == next(m.begin(), 4)); + r = m.upper_bound(14); + assert(r == next(m.begin(), 5)); + r = m.upper_bound(16); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(18); + assert(r == next(m.begin(), 7)); + r = m.upper_bound(20); + assert(r == next(m.begin(), 8)); + } + + { + typedef PrivateConstructor V; + typedef std::set> M; + typedef M::iterator R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 13 )); + m.insert ( V::make ( 15 )); + m.insert ( V::make ( 17 )); + m.insert ( V::make ( 19 )); + + R r = m.upper_bound(5); + assert(r == next(m.begin(), 1)); + r = m.upper_bound(7); + assert(r == next(m.begin(), 2)); + r = m.upper_bound(9); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(11); + assert(r == next(m.begin(), 4)); + r = m.upper_bound(13); + assert(r == next(m.begin(), 5)); + r = m.upper_bound(15); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(17); + assert(r == next(m.begin(), 7)); + r = m.upper_bound(19); + assert(r == next(m.begin(), 8)); + r = m.upper_bound(4); + assert(r == next(m.begin(), 0)); + r = m.upper_bound(6); + assert(r == next(m.begin(), 1)); + r = m.upper_bound(8); + assert(r == next(m.begin(), 2)); + r = m.upper_bound(10); + assert(r == next(m.begin(), 3)); + r = m.upper_bound(12); + assert(r == next(m.begin(), 4)); + r = m.upper_bound(14); + assert(r == next(m.begin(), 5)); + r = m.upper_bound(16); + assert(r == next(m.begin(), 6)); + r = m.upper_bound(18); + assert(r == next(m.begin(), 7)); + r = m.upper_bound(20); + assert(r == next(m.begin(), 8)); + } +#endif } diff --git a/test/support/private_constructor.hpp b/test/support/private_constructor.hpp new file mode 100644 index 00000000..3f6f0d3d --- /dev/null +++ b/test/support/private_constructor.hpp @@ -0,0 +1,22 @@ +#ifndef __PRIVATE_CONSTRUCTOR__H +#define __PRIVATE_CONSTRUCTOR__H + +#include + +struct PrivateConstructor { + + PrivateConstructor static make ( int v ) { return PrivateConstructor(v); } + int get () const { return val; } +private: + PrivateConstructor ( int v ) : val(v) {} + int val; + }; + +bool operator < ( const PrivateConstructor &lhs, const PrivateConstructor &rhs ) { return lhs.get() < rhs.get(); } + +bool operator < ( const PrivateConstructor &lhs, int rhs ) { return lhs.get() < rhs; } +bool operator < ( int lhs, const PrivateConstructor &rhs ) { return lhs < rhs.get(); } + +std::ostream & operator << ( std::ostream &os, const PrivateConstructor &foo ) { return os << foo.get (); } + +#endif