[libcxx-commits] [libcxx] 295b951 - [lib++][ranges][NFC] Refactor `iterator_operations.h` to use tags.

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 12 17:54:13 PDT 2022


Author: Konstantin Varlamov
Date: 2022-07-12T17:53:58-07:00
New Revision: 295b951ebcfea8d1fedf8abf4ffd449a83a551fd

URL: https://github.com/llvm/llvm-project/commit/295b951ebcfea8d1fedf8abf4ffd449a83a551fd
DIFF: https://github.com/llvm/llvm-project/commit/295b951ebcfea8d1fedf8abf4ffd449a83a551fd.diff

LOG: [lib++][ranges][NFC] Refactor `iterator_operations.h` to use tags.

Change the mechanism in `iterator_operations.h` to pass around a generic
policy tag indicating whether an internal function is being invoked from
a "classic" STL algorithm or a ranges algorithm. `IterOps` is now
a template class specialized on the policy tag.

The advantage is that this mechanism is more generic and allows defining
arbitrary conditions in a clean manner.

Also add a few more iterator functions to `IterOps`.

Differential Revision: https://reviews.llvm.org/D129390

Added: 
    

Modified: 
    libcxx/include/__algorithm/equal_range.h
    libcxx/include/__algorithm/iterator_operations.h
    libcxx/include/__algorithm/lower_bound.h
    libcxx/include/__algorithm/ranges_binary_search.h
    libcxx/include/__algorithm/ranges_lower_bound.h
    libcxx/include/__algorithm/ranges_set_intersection.h
    libcxx/include/__algorithm/ranges_upper_bound.h
    libcxx/include/__algorithm/set_intersection.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__algorithm/equal_range.h b/libcxx/include/__algorithm/equal_range.h
index cbfcd3c1ec1aa..f30f55be64fc7 100644
--- a/libcxx/include/__algorithm/equal_range.h
+++ b/libcxx/include/__algorithm/equal_range.h
@@ -55,7 +55,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va
             _ForwardIterator __mp1 = __m;
             return pair<_ForwardIterator, _ForwardIterator>
                    (
-                      _VSTD::__lower_bound_impl<_StdIterOps>(__first, __m, __value, __comp, __proj),
+                      _VSTD::__lower_bound_impl<_ClassicAlgPolicy>(__first, __m, __value, __comp, __proj),
                       _VSTD::__upper_bound<_Compare>(++__mp1, __last, __value, __comp)
                    );
         }

diff  --git a/libcxx/include/__algorithm/iterator_operations.h b/libcxx/include/__algorithm/iterator_operations.h
index 3d86f35f5998c..bccac368f3022 100644
--- a/libcxx/include/__algorithm/iterator_operations.h
+++ b/libcxx/include/__algorithm/iterator_operations.h
@@ -6,14 +6,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
-#define _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
+#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
+#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
 
+#include <__algorithm/iter_swap.h>
 #include <__config>
 #include <__iterator/advance.h>
 #include <__iterator/distance.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -21,35 +27,63 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _AlgPolicy> struct _IterOps;
+
 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
-struct _RangesIterOps {
+struct _RangeAlgPolicy {};
+
+template <>
+struct _IterOps<_RangeAlgPolicy> {
   static constexpr auto advance = ranges::advance;
   static constexpr auto distance = ranges::distance;
+  static constexpr auto __iter_move = ranges::iter_move;
+  static constexpr auto iter_swap = ranges::iter_swap;
   static constexpr auto next = ranges::next;
 };
 #endif
 
-struct _StdIterOps {
+struct _ClassicAlgPolicy {};
+
+template <>
+struct _IterOps<_ClassicAlgPolicy> {
 
-  template <class _Iterator, class _Distance>
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 void advance(_Iterator& __iter, _Distance __count) {
-    return std::advance(__iter, __count);
+  // advance
+  template <class _Iter, class _Distance>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+  static void advance(_Iter& __iter, _Distance __count) {
+    std::advance(__iter, __count);
   }
 
-  template <class _Iterator>
-  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
-  typename iterator_traits<_Iterator>::
diff erence_type distance(_Iterator __first, _Iterator __last) {
+  // distance
+  template <class _Iter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+  static typename iterator_traits<_Iter>::
diff erence_type distance(_Iter __first, _Iter __last) {
     return std::distance(__first, __last);
   }
 
+  // iter_move
+  template <class _Iter>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+  // Declaring the return type is necessary for the C++03 mode (which doesn't support placeholder return types).
+  static typename iterator_traits<__uncvref_t<_Iter> >::value_type&& __iter_move(_Iter&& __i) {
+    return std::move(*std::forward<_Iter>(__i));
+  }
+
+  // iter_swap
+  template <class _Iter1, class _Iter2>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
+  static void iter_swap(_Iter1&& __a, _Iter2&& __b) {
+    std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b));
+  }
+
+  // next
   template <class _Iterator>
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11
   _Iterator next(_Iterator, _Iterator __last) {
     return __last;
   }
-
 };
 
 _LIBCPP_END_NAMESPACE_STD
 
-#endif // _LIBCPP___ALGORIHTM_ITERATOR_OPERATIONS_H
+#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H

diff  --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index 431ac92a64610..2c92f715265ab 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -19,6 +19,7 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__type_traits/is_callable.h>
+#include <__type_traits/remove_reference.h>
 #include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -27,15 +28,15 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-template <class _IterOps, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
+template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
 _Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
-  auto __len = _IterOps::distance(__first, __last);
+  auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
 
   while (__len != 0) {
     auto __l2 = std::__half_positive(__len);
     _Iter __m = __first;
-    _IterOps::advance(__m, __l2);
+    _IterOps<_AlgPolicy>::advance(__m, __l2);
     if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) {
       __first = ++__m;
       __len -= __l2 + 1;
@@ -52,7 +53,7 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last,
   static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value,
                 "The comparator has to be callable");
   auto __proj = std::__identity();
-  return std::__lower_bound_impl<_StdIterOps>(__first, __last, __value, __comp, __proj);
+  return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
 }
 
 template <class _ForwardIterator, class _Tp>

diff  --git a/libcxx/include/__algorithm/ranges_binary_search.h b/libcxx/include/__algorithm/ranges_binary_search.h
index 68359fb1388f0..6da68834aa3b8 100644
--- a/libcxx/include/__algorithm/ranges_binary_search.h
+++ b/libcxx/include/__algorithm/ranges_binary_search.h
@@ -35,7 +35,7 @@ struct __fn {
             indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
   _LIBCPP_HIDE_FROM_ABI constexpr
   bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+    auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
     return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
   }
 
@@ -45,7 +45,7 @@ struct __fn {
   bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
     auto __first = ranges::begin(__r);
     auto __last = ranges::end(__r);
-    auto __ret = std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+    auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
     return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__first));
   }
 };

diff  --git a/libcxx/include/__algorithm/ranges_lower_bound.h b/libcxx/include/__algorithm/ranges_lower_bound.h
index a73470465cfda..1a9ae204a1ee2 100644
--- a/libcxx/include/__algorithm/ranges_lower_bound.h
+++ b/libcxx/include/__algorithm/ranges_lower_bound.h
@@ -39,7 +39,7 @@ struct __fn {
             indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
   _LIBCPP_HIDE_FROM_ABI constexpr
   _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
-    return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp, __proj);
+    return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
   }
 
   template <forward_range _Range, class _Type, class _Proj = identity,
@@ -49,7 +49,7 @@ struct __fn {
                                          const _Type& __value,
                                          _Comp __comp = {},
                                          _Proj __proj = {}) const {
-    return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
+    return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj);
   }
 };
 } // namespace __lower_bound

diff  --git a/libcxx/include/__algorithm/ranges_set_intersection.h b/libcxx/include/__algorithm/ranges_set_intersection.h
index 04405129ac16b..dac35cf27060e 100644
--- a/libcxx/include/__algorithm/ranges_set_intersection.h
+++ b/libcxx/include/__algorithm/ranges_set_intersection.h
@@ -59,7 +59,7 @@ struct __fn {
       _Comp __comp   = {},
       _Proj1 __proj1 = {},
       _Proj2 __proj2 = {}) const {
-    auto __ret = std::__set_intersection<_RangesIterOps>(
+    auto __ret = std::__set_intersection<_RangeAlgPolicy>(
         std::move(__first1),
         std::move(__last1),
         std::move(__first2),
@@ -93,7 +93,7 @@ struct __fn {
         _Comp __comp   = {},
         _Proj1 __proj1 = {},
         _Proj2 __proj2 = {}) const {
-    auto __ret = std::__set_intersection<_RangesIterOps>(
+    auto __ret = std::__set_intersection<_RangeAlgPolicy>(
         ranges::begin(__range1),
         ranges::end(__range1),
         ranges::begin(__range2),

diff  --git a/libcxx/include/__algorithm/ranges_upper_bound.h b/libcxx/include/__algorithm/ranges_upper_bound.h
index 94b5269c86aff..3c63249248fac 100644
--- a/libcxx/include/__algorithm/ranges_upper_bound.h
+++ b/libcxx/include/__algorithm/ranges_upper_bound.h
@@ -40,7 +40,7 @@ struct __fn {
       return !std::invoke(__comp, __rhs, __lhs);
     };
 
-    return std::__lower_bound_impl<_RangesIterOps>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
+    return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj);
   }
 
   template <forward_range _Range, class _Type, class _Proj = identity,
@@ -54,7 +54,7 @@ struct __fn {
       return !std::invoke(__comp, __rhs, __lhs);
     };
 
-    return std::__lower_bound_impl<_RangesIterOps>(ranges::begin(__r),
+    return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r),
                                                    ranges::end(__r),
                                                    __value,
                                                    __comp_lhs_rhs_swapped,

diff  --git a/libcxx/include/__algorithm/set_intersection.h b/libcxx/include/__algorithm/set_intersection.h
index 837f9af01d536..6507057032191 100644
--- a/libcxx/include/__algorithm/set_intersection.h
+++ b/libcxx/include/__algorithm/set_intersection.h
@@ -34,7 +34,7 @@ struct __set_intersection_result {
       : in1(std::move(__in_iter1)), in2(std::move(__in_iter2)), out(std::move(__out_iter)) {}
 };
 
-template < class _IterOper, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
+template <class _AlgPolicy, class _Compare, class _InIter1, class _Sent1, class _InIter2, class _Sent2, class _OutIter>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 __set_intersection_result<_InIter1, _InIter2, _OutIter>
 __set_intersection(
     _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) {
@@ -52,8 +52,8 @@ __set_intersection(
   }
 
   return __set_intersection_result<_InIter1, _InIter2, _OutIter>(
-      _IterOper::next(std::move(__first1), std::move(__last1)),
-      _IterOper::next(std::move(__first2), std::move(__last2)),
+      _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)),
+      _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)),
       std::move(__result));
 }
 
@@ -66,7 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_i
     _OutputIterator __result,
     _Compare __comp) {
   typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
-  return std::__set_intersection<_StdIterOps, _Comp_ref>(
+  return std::__set_intersection<_ClassicAlgPolicy, _Comp_ref>(
              std::move(__first1),
              std::move(__last1),
              std::move(__first2),
@@ -83,7 +83,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator set_i
     _InputIterator2 __first2,
     _InputIterator2 __last2,
     _OutputIterator __result) {
-  return std::__set_intersection<_StdIterOps>(
+  return std::__set_intersection<_ClassicAlgPolicy>(
              std::move(__first1),
              std::move(__last1),
              std::move(__first2),


        


More information about the libcxx-commits mailing list