diff mbox

[C++14] Implement N3657: heterogeneous lookup in associative containers.

Message ID 54C0287C.5020502@gmail.com
State New
Headers show

Commit Message

François Dumont Jan. 21, 2015, 10:30 p.m. UTC
On 20/01/2015 13:00, Jonathan Wakely wrote:
> On 19/01/15 17:16 +0000, Jonathan Wakely wrote:
>> This is the last missing piece of the C++14 library, as proposed in
>> http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2013/n3657.htm
>>
>> Tested x86_64-linux, *not* committed.
>
> Now committed to trunk.
>
Is it ok then to commit attached patch to do the same for debug mode ?

And also for profile mode later when I have it ready (this WE I think) ?

2015-01-22  François Dumont  <fdumont@gcc.gnu.org>

     * include/debug/stl_map.h (map::find<>,
     map::lower_bound<>, map::upper_bound<>, map::equal_range<>): New
     member function templates to perform heterogeneous lookup.
     * include/debug/stl_multimap.h (multimap::find<>,
     multimap::lower_bound<>, multimap::upper_bound<>,
     multimap::equal_range<>): Likewise.
     * include/debug/stl_multiset.h (multiset::find<>,
     multiset::lower_bound<>, multiset::upper_bound<>,
     multiset::equal_range<>): Likewise.
     * include/debug/stl_set.h (set::find<>,
     set::lower_bound<>, set::upper_bound<>, set::equal_range<>): Likewise.

Tested under Linux x86_64 debug mode.

François

Comments

Jonathan Wakely Jan. 22, 2015, 2:03 a.m. UTC | #1
On 21/01/15 23:30 +0100, François Dumont wrote:
>On 20/01/2015 13:00, Jonathan Wakely wrote:
>>On 19/01/15 17:16 +0000, Jonathan Wakely wrote:
>>>This is the last missing piece of the C++14 library, as proposed in
>>>http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2013/n3657.htm
>>>
>>>Tested x86_64-linux, *not* committed.
>>
>>Now committed to trunk.
>>
>Is it ok then to commit attached patch to do the same for debug mode ?

Definitely not like that, your patch adds the functions
unconditionally, but they must not participate in overload resolution
unless the comparison function defines an is_transparent member type.

I won't be too concerned if these new functions aren't available in
Debug Mode for the next release, we can add them later.
Jonathan Wakely Jan. 22, 2015, 2:07 a.m. UTC | #2
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} };
    }
diff mbox

Patch

Index: include/debug/map.h
===================================================================
--- include/debug/map.h	(revision 219967)
+++ 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>
+	iterator
+	find(const _Kt& __x)
+	{ return iterator(_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>
+	const_iterator
+	find(const _Kt& __x) const
+	{ return const_iterator(_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>
+	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>
+	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>
+	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>
+	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,18 @@ 
 			      iterator(__res.second, this));
       }
 
+#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));
+	}
+#endif
+
       std::pair<const_iterator,const_iterator>
       equal_range(const key_type& __x) const
       {
@@ -452,6 +506,18 @@ 
 			      const_iterator(__res.second, this));
       }
 
+#if __cplusplus > 201103L
+      template<typename _Kt>
+	std::pair<const_iterator, const_iterator>
+	equal_range(const _Kt& __x) const
+	{
+	  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));
+	}
+#endif
+
       _Base&
       _M_base() _GLIBCXX_NOEXCEPT	{ return *this; }
 
Index: include/debug/multimap.h
===================================================================
--- include/debug/multimap.h	(revision 219967)
+++ 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>
+	iterator
+	find(const _Kt& __x)
+	{ return iterator(_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>
+	const_iterator
+	find(const _Kt& __x) const
+	{ return const_iterator(_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>
+	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>
+	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>
+	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>
+	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)
       {
@@ -424,6 +466,18 @@ 
 			      iterator(__res.second, this));
       }
 
+#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));
+	}
+#endif
+
       std::pair<const_iterator,const_iterator>
       equal_range(const key_type& __x) const
       {
@@ -433,6 +487,18 @@ 
 			      const_iterator(__res.second, this));
       }
 
+#if __cplusplus > 201103L
+      template<typename _Kt>
+	std::pair<const_iterator, const_iterator>
+	equal_range(const _Kt& __x) const
+	{
+	  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));
+	}
+#endif
+
       _Base&
       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
 
Index: include/debug/set.h
===================================================================
--- include/debug/set.h	(revision 219967)
+++ 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>
+	iterator
+	find(const _Kt& __x)
+	{ return iterator(_Base::find(__x), this); }
+
+      template<typename _Kt>
+	const_iterator
+	find(const _Kt& __x) const
+	{ return const_iterator(_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>
+	iterator
+	lower_bound(const _Kt& __x)
+	{ return iterator(_Base::lower_bound(__x), this); }
+
+      template<typename _Kt>
+	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); }
@@ -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>
+	iterator
+	upper_bound(const _Kt& __x)
+	{ return iterator(_Base::upper_bound(__x), this); }
+
+      template<typename _Kt>
+	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)
       {
@@ -429,12 +465,34 @@ 
       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>
+	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));
+	}
+
+      template<typename _Kt>
+	std::pair<const_iterator, const_iterator>
+	equal_range(const _Kt& __x) const
+	{
+	  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));
+	}
+#endif
+
       _Base&
       _M_base() _GLIBCXX_NOEXCEPT	{ return *this; }
 
Index: include/debug/multiset.h
===================================================================
--- include/debug/multiset.h	(revision 219967)
+++ 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>
+	iterator
+	find(const _Kt& __x)
+	{ return iterator(_Base::find(__x), this); }
+
+      template<typename _Kt>
+	const_iterator
+	find(const _Kt& __x) const
+	{ return const_iterator(_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>
+	iterator
+	lower_bound(const _Kt& __x)
+	{ return iterator(_Base::lower_bound(__x), this); }
+
+      template<typename _Kt>
+	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); }
@@ -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>
+	iterator
+	upper_bound(const _Kt& __x)
+	{ return iterator(_Base::upper_bound(__x), this); }
+
+      template<typename _Kt>
+	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)
       {
@@ -428,6 +464,28 @@ 
 			      const_iterator(__res.second, this));
       }
 
+#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));
+	}
+
+      template<typename _Kt>
+	std::pair<const_iterator, const_iterator>
+	equal_range(const _Kt& __x) const
+	{
+	  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));
+	}
+#endif
+
       _Base&
       _M_base() _GLIBCXX_NOEXCEPT { return *this; }