public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Improve _Safe_iterator _M_distance_to
@ 2019-09-16 20:31 François Dumont
  2019-09-27 11:46 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: François Dumont @ 2019-09-16 20:31 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2995 bytes --]

     Here is the patch to improve _Safe_iterator<>::_M_get_distance_to 
implementation.

I introduced a new _Distance_precision  __sp_sign_max_size for occasions 
where we can't find out the exact size of a range but still get the max 
size of it. Thanks to this the performance tests are much better when 
dealing with list iterators:

Normal mode:

copy_backward_deque_iterators.cc    deque 2 list 5616r 5616u    
0s         0mem    0pf
copy_backward_deque_iterators.cc    list 2 deque 1586r 1586u    
0s         0mem    0pf
copy_deque_iterators.cc      deque 2 list                 5495r 5495u    
0s         0mem    0pf
copy_deque_iterators.cc      list 2 deque                 2400r 2400u    
0s         0mem    0pf

Debug mode:

copy_backward_deque_iterators.cc    deque 2 list 5789r 5785u    
1s         0mem    0pf
copy_backward_deque_iterators.cc    list 2 deque 1656r 1655u    
0s         0mem    0pf
copy_deque_iterators.cc      deque 2 list                 5792r 5793u    
0s         0mem    0pf
copy_deque_iterators.cc      list 2 deque                 2636r 2636u    
0s         0mem    0pf

Tested under Linux x86_64.

I'll commit once other patches are in.


     * include/debug/forward_list
(_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign
     distance when not empty.
     * include/debug/list
     (_Sequence_traits<__debug::list<>>::_S_size): Likewise.
     * include/debug/helper_functions.h (__dp_sign_max_size): New
     _Distance_precision enum entry.
     * include/debug/safe_iterator.h
     (__copy_move_a(_II, _II, const _Safe_iterator<>&)): Check for output
     iterator _M_can_advance as soon as input range distance precision is
     strictly higher than __dp_size.
     (__copy_move_a(const _Safe_iterator<>&, const _Safe_iterator<>&,
     const _Safe_iterator<>&)): Likewise.
     (__copy_move_backward_a(_II, _II, const _Safe_iterator<>&)): Likewise.
     (__copy_move_backward_a(const _Safe_iterator<>&,
     const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
     (__equal_aux(_II, _II, const _Safe_iterator<>&)): Likewise.
     (__equal_aux(const _Safe_iterator<>&,
     const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.

François


[-- Attachment #2: distance_to.patch --]
[-- Type: text/x-patch, Size: 7848 bytes --]

diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index e30b000009e..f1756ddec9d 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -911,7 +911,7 @@ namespace __gnu_debug
       _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
       {
 	return __seq.empty()
-	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality);
+	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
       }
     };
 
diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h
index b7aeafef12a..9429bb90a55 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -50,10 +50,11 @@ namespace __gnu_debug
    */
   enum _Distance_precision
     {
-      __dp_none,	// Not even an iterator type
-      __dp_equality,	//< Can compare iterator equality, only
-      __dp_sign,	//< Can determine equality and ordering
-      __dp_exact	//< Can determine distance precisely
+      __dp_none,		// Not even an iterator type
+      __dp_equality,		//< Can compare iterator equality, only
+      __dp_sign,		//< Can determine equality and ordering
+      __dp_sign_max_size,	//< __dp_sign and gives max range size
+      __dp_exact		//< Can determine distance precisely
     };
 
   template<typename _Iterator,
@@ -141,6 +142,7 @@ namespace __gnu_debug
 	    return true;
 	  break;
 	case __dp_sign:
+	case __dp_sign_max_size:
 	case __dp_exact:
 	  return __dist.first >= 0;
 	}
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 5eb9a6094e3..140546a633e 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -916,7 +916,7 @@ namespace __gnu_debug
       _S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
       {
 	return __seq.empty()
-	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality);
+	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
       }
     };
 #endif
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index 1665c95f5df..584f8eec5b0 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -984,7 +984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_check_valid_range2(__first, __last, __dist);
       __glibcxx_check_can_increment(__result, __dist.first);
 
-      if (__dist.second == ::__gnu_debug::__dp_exact
+      if (__dist.second > ::__gnu_debug::__dp_sign
 	  && __result._M_can_advance(__dist.first, true))
 	return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
 		std::__copy_move_a<_IsMove>(__first, __last, __result.base()),
@@ -1008,7 +1008,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       if (__dist.second > ::__gnu_debug::__dp_equality)
 	{
-	  if (__dist.second == ::__gnu_debug::__dp_exact
+	  if (__dist.second > ::__gnu_debug::__dp_sign
 	      && __result._M_can_advance(__dist.first, true))
 	    return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
 	      std::__copy_move_a<_IsMove>(__first.base(), __last.base(),
@@ -1051,7 +1051,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_check_valid_range2(__first, __last, __dist);
       __glibcxx_check_can_increment(__result, -__dist.first);
 
-      if (__dist.second == ::__gnu_debug::__dp_exact
+      if (__dist.second > ::__gnu_debug::__dp_sign
 	  && __result._M_can_advance(-__dist.first, true))
 	return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>(
 		std::__copy_move_backward_a<_IsMove>(__first, __last,
@@ -1076,7 +1076,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       if (__dist.second > ::__gnu_debug::__dp_equality)
 	{
-	  if (__dist.second == ::__gnu_debug::__dp_exact
+	  if (__dist.second > ::__gnu_debug::__dp_sign
 	      && __result._M_can_advance(-__dist.first, true))
 	    return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>(
 	      std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(),
@@ -1154,7 +1154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __glibcxx_check_valid_range2(__first1, __last1, __dist);
       __glibcxx_check_can_increment(__first2, __dist.first);
 
-      if (__dist.second == ::__gnu_debug::__dp_exact
+      if (__dist.second > ::__gnu_debug::__dp_sign
 	  && __first2._M_can_advance(__dist.first, true))
 	return std::__equal_aux(__first1, __last1, __first2.base());
 
@@ -1175,7 +1175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       if (__dist.second > ::__gnu_debug::__dp_equality)
 	{
-	  if (__dist.second == ::__gnu_debug::__dp_exact &&
+	  if (__dist.second > ::__gnu_debug::__dp_sign &&
 	      __first2._M_can_advance(__dist.first, true))
 	    return std::__equal_aux(__first1.base(), __last1.base(),
 				    __first2.base());
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
index 3d30029dd25..99757f58269 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -113,18 +113,22 @@ namespace __gnu_debug
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_get_distance_to(const _Safe_iterator& __rhs) const
     {
-      typedef typename _Distance_traits<_Iterator>::__type _Diff;
+      typedef typename _Distance_traits<_Iterator>::__type _Dist;
       typedef _Sequence_traits<_Sequence> _SeqTraits;
 
-      if (this->base() == __rhs.base())
-	return std::make_pair(0, __dp_exact);
+      _Dist __base_dist = __get_distance(this->base(), __rhs.base());
+      if (__base_dist.second == __dp_exact)
+	return __base_dist;
 
+      _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
       if (this->_M_is_before_begin())
 	{
 	  if (__rhs._M_is_begin())
 	    return std::make_pair(1, __dp_exact);
 
-	  return std::make_pair(1, __dp_sign);
+	  return __seq_dist.second == __dp_exact
+	    ? std::make_pair(__seq_dist.first + 1, __dp_exact)
+	    : __seq_dist;
 	}
 
       if (this->_M_is_begin())
@@ -133,30 +137,42 @@ namespace __gnu_debug
 	    return std::make_pair(-1, __dp_exact);
 
 	  if (__rhs._M_is_end())
-	    return _SeqTraits::_S_size(*this->_M_get_sequence());
+	    return __seq_dist;
 
-	  return std::make_pair(1, __dp_sign);
+	  return std::make_pair(__seq_dist.first,
+				__seq_dist.second == __dp_exact
+				? __dp_sign_max_size : __seq_dist.second);
 	}
 
       if (this->_M_is_end())
 	{
 	  if (__rhs._M_is_before_begin())
-	    return std::make_pair(-1, __dp_exact);
+	    return __seq_dist.second == __dp_exact
+	      ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
+	      : std::make_pair(-__seq_dist.first, __dp_sign);
 
 	  if (__rhs._M_is_begin())
-	    {
-	      _Diff __diff = _SeqTraits::_S_size(*this->_M_get_sequence());
-	      return std::make_pair(-__diff.first, __diff.second);
-	    }
+	    return std::make_pair(-__seq_dist.first, __seq_dist.second);
 
-	  return std::make_pair(-1, __dp_sign);
+	  return std::make_pair(-__seq_dist.first,
+				__seq_dist.second == __dp_exact
+				? __dp_sign_max_size : __seq_dist.second);
 	}
 
-      if (__rhs._M_is_before_begin() || __rhs._M_is_begin())
-	return std::make_pair(-1, __dp_sign);
+      if (__rhs._M_is_before_begin())
+	return __seq_dist.second == __dp_exact
+	  ? std::make_pair(__seq_dist.first - 1, __dp_exact)
+	  : std::make_pair(-__seq_dist.first, __dp_sign);
+
+      if (__rhs._M_is_begin())
+	return std::make_pair(-__seq_dist.first,
+			      __seq_dist.second == __dp_exact
+			      ? __dp_sign_max_size : __seq_dist.second);
 
       if (__rhs._M_is_end())
-	return std::make_pair(1, __dp_sign);
+	return std::make_pair(__seq_dist.first,
+			      __seq_dist.second == __dp_exact
+			      ? __dp_sign_max_size : __seq_dist.second);
 
       return std::make_pair(1, __dp_equality);
     }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Improve _Safe_iterator _M_distance_to
  2019-09-16 20:31 [PATCH] Improve _Safe_iterator _M_distance_to François Dumont
@ 2019-09-27 11:46 ` Jonathan Wakely
  2019-10-04 20:31   ` François Dumont
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2019-09-27 11:46 UTC (permalink / raw)
  To: François Dumont; +Cc: libstdc++, gcc-patches

On 16/09/19 22:31 +0200, François Dumont wrote:
>    Here is the patch to improve _Safe_iterator<>::_M_get_distance_to 
>implementation.
>
>I introduced a new _Distance_precision  __sp_sign_max_size for 
>occasions where we can't find out the exact size of a range but still 
>get the max size of it. Thanks to this the performance tests are much 
>better when dealing with list iterators:
>
>Normal mode:
>
>copy_backward_deque_iterators.cc    deque 2 list 5616r 5616u    
>0s         0mem    0pf
>copy_backward_deque_iterators.cc    list 2 deque 1586r 1586u    
>0s         0mem    0pf
>copy_deque_iterators.cc      deque 2 list                 5495r 
>5495u    0s         0mem    0pf
>copy_deque_iterators.cc      list 2 deque                 2400r 
>2400u    0s         0mem    0pf
>
>Debug mode:
>
>copy_backward_deque_iterators.cc    deque 2 list 5789r 5785u    
>1s         0mem    0pf
>copy_backward_deque_iterators.cc    list 2 deque 1656r 1655u    
>0s         0mem    0pf
>copy_deque_iterators.cc      deque 2 list                 5792r 
>5793u    0s         0mem    0pf
>copy_deque_iterators.cc      list 2 deque                 2636r 
>2636u    0s         0mem    0pf
>
>Tested under Linux x86_64.
>
>I'll commit once other patches are in.
>
>
>    * include/debug/forward_list
>(_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign
>    distance when not empty.
>    * include/debug/list
>    (_Sequence_traits<__debug::list<>>::_S_size): Likewise.
>    * include/debug/helper_functions.h (__dp_sign_max_size): New
>    _Distance_precision enum entry.
>    * include/debug/safe_iterator.h
>    (__copy_move_a(_II, _II, const _Safe_iterator<>&)): Check for output
>    iterator _M_can_advance as soon as input range distance precision is
>    strictly higher than __dp_size.
>    (__copy_move_a(const _Safe_iterator<>&, const _Safe_iterator<>&,
>    const _Safe_iterator<>&)): Likewise.
>    (__copy_move_backward_a(_II, _II, const _Safe_iterator<>&)): Likewise.
>    (__copy_move_backward_a(const _Safe_iterator<>&,
>    const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
>    (__equal_aux(_II, _II, const _Safe_iterator<>&)): Likewise.
>    (__equal_aux(const _Safe_iterator<>&,
>    const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.

The patch looks OK, but the safe_iterator.tcc changes are not listed
in the changelog, and those are the most complex part of the patch.

Please add a changelog entry for the _M_get_distance_to changes. OK
for trunk after that, thanks.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Improve _Safe_iterator _M_distance_to
  2019-09-27 11:46 ` Jonathan Wakely
@ 2019-10-04 20:31   ` François Dumont
  0 siblings, 0 replies; 3+ messages in thread
From: François Dumont @ 2019-10-04 20:31 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 3526 bytes --]

I eventually committed the attach patch.

The usage of __dp_sign_max_size will come later.

François

On 9/27/19 1:45 PM, Jonathan Wakely wrote:
> On 16/09/19 22:31 +0200, François Dumont wrote:
>>     Here is the patch to improve _Safe_iterator<>::_M_get_distance_to 
>> implementation.
>>
>> I introduced a new _Distance_precision  __sp_sign_max_size for 
>> occasions where we can't find out the exact size of a range but still 
>> get the max size of it. Thanks to this the performance tests are much 
>> better when dealing with list iterators:
>>
>> Normal mode:
>>
>> copy_backward_deque_iterators.cc    deque 2 list 5616r 5616u 
>> 0s         0mem    0pf
>> copy_backward_deque_iterators.cc    list 2 deque 1586r 1586u 
>> 0s         0mem    0pf
>> copy_deque_iterators.cc      deque 2 list                 5495r 
>> 5495u    0s         0mem    0pf
>> copy_deque_iterators.cc      list 2 deque                 2400r 
>> 2400u    0s         0mem    0pf
>>
>> Debug mode:
>>
>> copy_backward_deque_iterators.cc    deque 2 list 5789r 5785u 
>> 1s         0mem    0pf
>> copy_backward_deque_iterators.cc    list 2 deque 1656r 1655u 
>> 0s         0mem    0pf
>> copy_deque_iterators.cc      deque 2 list                 5792r 
>> 5793u    0s         0mem    0pf
>> copy_deque_iterators.cc      list 2 deque                 2636r 
>> 2636u    0s         0mem    0pf
>>
>> Tested under Linux x86_64.
>>
>> I'll commit once other patches are in.
>>
>>
>>     * include/debug/forward_list
>> (_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign
>>     distance when not empty.
>>     * include/debug/list
>>     (_Sequence_traits<__debug::list<>>::_S_size): Likewise.
>>     * include/debug/helper_functions.h (__dp_sign_max_size): New
>>     _Distance_precision enum entry.
>>     * include/debug/safe_iterator.h
>>     (__copy_move_a(_II, _II, const _Safe_iterator<>&)): Check for output
>>     iterator _M_can_advance as soon as input range distance precision is
>>     strictly higher than __dp_size.
>>     (__copy_move_a(const _Safe_iterator<>&, const _Safe_iterator<>&,
>>     const _Safe_iterator<>&)): Likewise.
>>     (__copy_move_backward_a(_II, _II, const _Safe_iterator<>&)): 
>> Likewise.
>>     (__copy_move_backward_a(const _Safe_iterator<>&,
>>     const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
>>     (__equal_aux(_II, _II, const _Safe_iterator<>&)): Likewise.
>>     (__equal_aux(const _Safe_iterator<>&,
>>     const _Safe_iterator<>&, const _Safe_iterator<>&)): Likewise.
>
> The patch looks OK, but the safe_iterator.tcc changes are not listed
> in the changelog, and those are the most complex part of the patch.
>
> Please add a changelog entry for the _M_get_distance_to changes. OK
> for trunk after that, thanks.
>
>
>


[-- Attachment #2: distance_to.patch --]
[-- Type: text/x-patch, Size: 5099 bytes --]

diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index e30b000009e..f1756ddec9d 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -911,7 +911,7 @@ namespace __gnu_debug
       _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq)
       {
 	return __seq.empty()
-	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality);
+	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
       }
     };
 
diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h
index 475fdda1d7b..5a920bb9a6f 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -50,10 +50,11 @@ namespace __gnu_debug
    */
   enum _Distance_precision
     {
-      __dp_none,	// Not even an iterator type
-      __dp_equality,	//< Can compare iterator equality, only
-      __dp_sign,	//< Can determine equality and ordering
-      __dp_exact	//< Can determine distance precisely
+      __dp_none,		// Not even an iterator type
+      __dp_equality,		//< Can compare iterator equality, only
+      __dp_sign,		//< Can determine equality and ordering
+      __dp_sign_max_size,	//< __dp_sign and gives max range size
+      __dp_exact		//< Can determine distance precisely
     };
 
   template<typename _Iterator,
@@ -176,6 +177,7 @@ namespace __gnu_debug
 	    return true;
 	  break;
 	case __dp_sign:
+	case __dp_sign_max_size:
 	case __dp_exact:
 	  return __dist.first >= 0;
 	}
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 5eb9a6094e3..140546a633e 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -916,7 +916,7 @@ namespace __gnu_debug
       _S_size(const std::__debug::list<_Tp, _Alloc>& __seq)
       {
 	return __seq.empty()
-	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality);
+	  ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign);
       }
     };
 #endif
diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc
index 581c51c9607..1750bc473d2 100644
--- a/libstdc++-v3/include/debug/safe_iterator.tcc
+++ b/libstdc++-v3/include/debug/safe_iterator.tcc
@@ -113,18 +113,22 @@ namespace __gnu_debug
     _Safe_iterator<_Iterator, _Sequence, _Category>::
     _M_get_distance_to(const _Safe_iterator& __rhs) const
     {
-      typedef typename _Distance_traits<_Iterator>::__type _Diff;
+      typedef typename _Distance_traits<_Iterator>::__type _Dist;
       typedef _Sequence_traits<_Sequence> _SeqTraits;
 
-      if (this->base() == __rhs.base())
-	return std::make_pair(0, __dp_exact);
+      _Dist __base_dist = __get_distance(this->base(), __rhs.base());
+      if (__base_dist.second == __dp_exact)
+	return __base_dist;
 
+      _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence());
       if (this->_M_is_before_begin())
 	{
 	  if (__rhs._M_is_begin())
 	    return std::make_pair(1, __dp_exact);
 
-	  return std::make_pair(1, __dp_sign);
+	  return __seq_dist.second == __dp_exact
+	    ? std::make_pair(__seq_dist.first + 1, __dp_exact)
+	    : __seq_dist;
 	}
 
       if (this->_M_is_begin())
@@ -133,30 +137,42 @@ namespace __gnu_debug
 	    return std::make_pair(-1, __dp_exact);
 
 	  if (__rhs._M_is_end())
-	    return _SeqTraits::_S_size(*this->_M_get_sequence());
+	    return __seq_dist;
 
-	  return std::make_pair(1, __dp_sign);
+	  return std::make_pair(__seq_dist.first,
+				__seq_dist.second == __dp_exact
+				? __dp_sign_max_size : __seq_dist.second);
 	}
 
       if (this->_M_is_end())
 	{
 	  if (__rhs._M_is_before_begin())
-	    return std::make_pair(-1, __dp_exact);
+	    return __seq_dist.second == __dp_exact
+	      ? std::make_pair(-__seq_dist.first - 1, __dp_exact)
+	      : std::make_pair(-__seq_dist.first, __dp_sign);
 
 	  if (__rhs._M_is_begin())
-	    {
-	      _Diff __diff = _SeqTraits::_S_size(*this->_M_get_sequence());
-	      return std::make_pair(-__diff.first, __diff.second);
-	    }
+	    return std::make_pair(-__seq_dist.first, __seq_dist.second);
 
-	  return std::make_pair(-1, __dp_sign);
+	  return std::make_pair(-__seq_dist.first,
+				__seq_dist.second == __dp_exact
+				? __dp_sign_max_size : __seq_dist.second);
 	}
 
-      if (__rhs._M_is_before_begin() || __rhs._M_is_begin())
-	return std::make_pair(-1, __dp_sign);
+      if (__rhs._M_is_before_begin())
+	return __seq_dist.second == __dp_exact
+	  ? std::make_pair(__seq_dist.first - 1, __dp_exact)
+	  : std::make_pair(-__seq_dist.first, __dp_sign);
+
+      if (__rhs._M_is_begin())
+	return std::make_pair(-__seq_dist.first,
+			      __seq_dist.second == __dp_exact
+			      ? __dp_sign_max_size : __seq_dist.second);
 
       if (__rhs._M_is_end())
-	return std::make_pair(1, __dp_sign);
+	return std::make_pair(__seq_dist.first,
+			      __seq_dist.second == __dp_exact
+			      ? __dp_sign_max_size : __seq_dist.second);
 
       return std::make_pair(1, __dp_equality);
     }

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-10-04 20:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-16 20:31 [PATCH] Improve _Safe_iterator _M_distance_to François Dumont
2019-09-27 11:46 ` Jonathan Wakely
2019-10-04 20:31   ` François Dumont

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).