Sorry, I hadn't notice the condition to expose the new methods. It was
hidden within the _Rb_tree type that I hadn't check (and I do not often
check the Standard directly for my limited patches).
On my side I am surprised you didn't reuse your code to detect member
types. I am also surprised that it is not using enable_if, IMHO it makes
the code clearer. Here is a proposal to use both extended to the debug
mode too.
François
On 22/01/2015 03:07, Jonathan Wakely wrote:
On 21/01/15 23:30 +0100, François Dumont wrote:
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ std::pair<iterator, iterator>
+ equal_range(const _Kt& __x)
+ {
+ std::pair<_Base_iterator, _Base_iterator> __res =
+ _Base::equal_range(__x);
+ return std::make_pair(iterator(__res.first, this),
+ iterator(__res.second, this));
+ }
BTW, this is C++14 code, what's wrong with:
template<typename _Kt>
std::pair<const_iterator, const_iterator>
equal_range(const _Kt& __x) const
{
auto __res = _Base::equal_range(__x);
return { iterator(__res.first, this), iterator(__res.second,
this) };
}
Or even:
template<typename _Kt>
std::pair<const_iterator, const_iterator>
equal_range(const _Kt& __x) const
{
auto __res = _Base::equal_range(__x);
return { { __res.first, this }, {__res.second, this} };
}
Index: include/bits/stl_tree.h
===================================================================
--- include/bits/stl_tree.h (revision 220078)
+++ include/bits/stl_tree.h (working copy)
@@ -342,6 +342,9 @@
_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
_Rb_tree_node_base& __header) throw ();
+#if __cplusplus > 201103L
+ _GLIBCXX_HAS_NESTED_TYPE(is_transparent)
+#endif
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = allocator<_Val> >
@@ -1119,14 +1122,6 @@
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); }
@@ -1155,9 +1150,8 @@
return _S_iter(__y);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
_M_find_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1166,9 +1160,8 @@
? end() : __j;
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- const_iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
_M_find_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1177,9 +1170,8 @@
? end() : __j;
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- size_type
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, size_type>
_M_count_tr(const _Kt& __k) const
{
auto __p = _M_equal_range_tr(__k);
@@ -1186,9 +1178,8 @@
return std::distance(__p.first, __p.second);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
_M_lower_bound_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1195,9 +1186,8 @@
return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- const_iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
_M_lower_bound_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1204,9 +1194,8 @@
return _S_lower_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
_M_upper_bound_tr(const _Kt& __k)
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1213,9 +1202,8 @@
return _S_upper_bound_tr(__cmp, _M_begin(), _M_end(), __k);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- const_iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
_M_upper_bound_tr(const _Kt& __k) const
{
auto& __cmp = _M_impl._M_key_compare;
@@ -1222,9 +1210,9 @@
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>
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ pair<iterator, iterator>>
_M_equal_range_tr(const _Kt& __k)
{
auto __low = _M_lower_bound_tr(__k);
@@ -1235,9 +1223,9 @@
return { __low, __high };
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- pair<const_iterator, const_iterator>
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ pair<const_iterator, const_iterator>>
_M_equal_range_tr(const _Kt& __k) const
{
auto __low = _M_lower_bound_tr(__k);
Index: include/debug/map.h
===================================================================
--- include/debug/map.h (revision 220078)
+++ include/debug/map.h (working copy)
@@ -412,10 +412,24 @@
find(const key_type& __x)
{ return iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ find(const _Kt& __x)
+ { return { _Base::find(__x), this }; }
+#endif
+
const_iterator
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ find(const _Kt& __x) const
+ { return { _Base::find(__x), this }; }
+#endif
+
using _Base::count;
iterator
@@ -422,18 +436,46 @@
lower_bound(const key_type& __x)
{ return iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ lower_bound(const _Kt& __x)
+ { return iterator(_Base::lower_bound(__x), this); }
+#endif
+
const_iterator
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ lower_bound(const _Kt& __x) const
+ { return const_iterator(_Base::lower_bound(__x), this); }
+#endif
+
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ upper_bound(const _Kt& __x)
+ { return iterator(_Base::upper_bound(__x), this); }
+#endif
+
const_iterator
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ upper_bound(const _Kt& __x) const
+ { return const_iterator(_Base::upper_bound(__x), this); }
+#endif
+
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
@@ -443,6 +485,17 @@
iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<iterator, iterator>>
+ equal_range(const _Kt& __x)
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
@@ -452,6 +505,17 @@
const_iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<const_iterator, const_iterator>>
+ equal_range(const _Kt& __x) const
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
_Base&
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
Index: include/debug/multimap.h
===================================================================
--- include/debug/multimap.h (revision 220078)
+++ include/debug/multimap.h (working copy)
@@ -393,10 +393,24 @@
find(const key_type& __x)
{ return iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ find(const _Kt& __x)
+ { return { _Base::find(__x), this }; }
+#endif
+
const_iterator
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ find(const _Kt& __x) const
+ { return { _Base::find(__x), this }; }
+#endif
+
using _Base::count;
iterator
@@ -403,18 +417,46 @@
lower_bound(const key_type& __x)
{ return iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ lower_bound(const _Kt& __x)
+ { return { _Base::lower_bound(__x), this }; }
+#endif
+
const_iterator
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ lower_bound(const _Kt& __x) const
+ { return { _Base::lower_bound(__x), this }; }
+#endif
+
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ upper_bound(const _Kt& __x)
+ { return { _Base::upper_bound(__x), this }; }
+#endif
+
const_iterator
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ upper_bound(const _Kt& __x) const
+ { return { _Base::upper_bound(__x), this }; }
+#endif
+
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
@@ -424,6 +466,17 @@
iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<iterator, iterator>>
+ equal_range(const _Kt& __x)
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
@@ -433,6 +486,17 @@
const_iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<const_iterator, const_iterator>>
+ equal_range(const _Kt& __x) const
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
_Base&
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
Index: include/debug/set.h
===================================================================
--- include/debug/set.h (revision 220078)
+++ include/debug/set.h (working copy)
@@ -393,6 +393,18 @@
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ find(const _Kt& __x)
+ { return { _Base::find(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ find(const _Kt& __x) const
+ { return { _Base::find(__x), this }; }
+#endif
+
using _Base::count;
iterator
@@ -405,6 +417,18 @@
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ lower_bound(const _Kt& __x)
+ { return { _Base::lower_bound(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ lower_bound(const _Kt& __x) const
+ { return { _Base::lower_bound(__x), this }; }
+#endif
+
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x), this); }
@@ -415,6 +439,18 @@
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ upper_bound(const _Kt& __x)
+ { return { _Base::upper_bound(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ upper_bound(const _Kt& __x) const
+ { return { _Base::upper_bound(__x), this }; }
+#endif
+
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
@@ -429,12 +465,32 @@
std::pair<const_iterator,const_iterator>
equal_range(const key_type& __x) const
{
- std::pair<_Base_iterator, _Base_iterator> __res =
+ std::pair<_Base_const_iterator, _Base_const_iterator> __res =
_Base::equal_range(__x);
return std::make_pair(const_iterator(__res.first, this),
const_iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<iterator, iterator>>
+ equal_range(const _Kt& __x)
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<const_iterator, const_iterator>>
+ equal_range(const _Kt& __x) const
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
_Base&
_M_base() _GLIBCXX_NOEXCEPT { return *this; }
Index: include/debug/multiset.h
===================================================================
--- include/debug/multiset.h (revision 220078)
+++ include/debug/multiset.h (working copy)
@@ -386,6 +386,18 @@
find(const key_type& __x) const
{ return const_iterator(_Base::find(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ find(const _Kt& __x)
+ { return { _Base::find(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ find(const _Kt& __x) const
+ { return { _Base::find(__x), this }; }
+#endif
+
using _Base::count;
iterator
@@ -398,6 +410,18 @@
lower_bound(const key_type& __x) const
{ return const_iterator(_Base::lower_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ lower_bound(const _Kt& __x)
+ { return { _Base::lower_bound(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ lower_bound(const _Kt& __x) const
+ { return { _Base::lower_bound(__x), this }; }
+#endif
+
iterator
upper_bound(const key_type& __x)
{ return iterator(_Base::upper_bound(__x), this); }
@@ -408,6 +432,18 @@
upper_bound(const key_type& __x) const
{ return const_iterator(_Base::upper_bound(__x), this); }
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
+ upper_bound(const _Kt& __x)
+ { return { _Base::upper_bound(__x), this }; }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, const_iterator>
+ upper_bound(const _Kt& __x) const
+ { return { _Base::upper_bound(__x), this }; }
+#endif
+
std::pair<iterator,iterator>
equal_range(const key_type& __x)
{
@@ -428,6 +464,26 @@
const_iterator(__res.second, this));
}
+#if __cplusplus > 201103L
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<iterator, iterator>>
+ equal_range(const _Kt& __x)
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value,
+ std::pair<const_iterator, const_iterator>>
+ equal_range(const _Kt& __x) const
+ {
+ auto __res = _Base::equal_range(__x);
+ return { { __res.first, this }, { __res.second, this } };
+ }
+#endif
+
_Base&
_M_base() _GLIBCXX_NOEXCEPT { return *this; }