[libcxx-commits] [PATCH] D127194: [libc++][ranges] Implement `ranges::is_permutation`
Konstantin Varlamov via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 4 03:22:04 PDT 2022
var-const added inline comments.
================
Comment at: libcxx/include/__algorithm/is_permutation.h:34
- // __first1 != __last1 && *__first1 != *__first2
- typedef typename iterator_traits<_ForwardIterator1>::difference_type _D1;
- _D1 __l1 = _VSTD::distance(__first1, __last1);
- if (__l1 == _D1(1))
- return false;
- _ForwardIterator2 __last2 = _VSTD::next(__first2, __l1);
- // For each element in [f1, l1) see if there are the same number of
- // equal elements in [f2, l2)
- for (_ForwardIterator1 __i = __first1; __i != __last1; ++__i) {
+#if _LIBCPP_STD_VER > 17
+
----------------
ldionne wrote:
> Is this `#if` wrong, or is the `#endif` comment wrong?
Fixed. I think the `#if` is correct -- we only guard `sized_sentinel_for` with the language version, so it's okay to use regardless of whether ranges are enabled, and it covers more cases than the more simplistic check in the `#else` branch.
================
Comment at: libcxx/include/__algorithm/is_permutation.h:101-107
+ for (; __first1 != __last1; ++__first1, (void)++__first2) {
+ if (!__pred(*__first1, *__first2))
+ break;
+ }
+
+ if (__first1 == __last1)
+ return true;
----------------
ldionne wrote:
> FWIW I think this is a reimplementation of `std::mismatch`.
>
> I don't mind whether we refactor this now or after (or not at all if it turns out not to be a good idea). But we should at least look into it.
I'd like to try it out, but would leave it to a follow-up patch.
================
Comment at: libcxx/include/__algorithm/is_permutation.h:175-181
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 bool
+__is_permutation4(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2,
+ _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
+ return std::__is_permutation4<_AlgPolicy>(
+ std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
+ __pred, __proj1, __proj2,
+ _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>());
----------------
ldionne wrote:
> Instead, why not have just two versions of `__is_permutation4` and use `enable_if_t`? I don't think you need this function at all.
The `_ConstTimeDistance == true` overload relies on the ability to delegate to the `_ConstTimeDistance == false` overload (which is easy because it can pass `false_type` directly instead of using the trait). It seems like it would be more difficult to achieve with `enable_if` (unless there's some approach I didn't think of).
================
Comment at: libcxx/include/__algorithm/ranges_is_permutation.h:41
+ _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+ return std::__is_permutation4<_RangeAlgPolicy>(
+ std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2),
----------------
ldionne wrote:
> I would suggest looking into naming `__is_permutation4` and `__is_permutation3` just `__is_permutation`. That way, they can be called as `std::__is_permutation<Policy>`, which is nicely consistent with what we do for other algorithms.
Done. I found myself getting confused between all the different overloads, but it's a good point that having a single name would be consistent with other algorithms.
================
Comment at: libcxx/include/__algorithm/ranges_is_permutation.h:68-71
+ if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
+ if (ranges::distance(__range1) != ranges::distance(__range2))
+ return false;
+ }
----------------
ldionne wrote:
> Is this still needed here, or do we handle this in `__is_permutation`?
Unfortunately, I think it's still necessary. It's possible for the range to be a `sized_range` without the sentinel satisfying `sized_sentinel_for` -- e.g. the range type could define `size()` member function but the sentinel is just a forward iterator that doesn't support subtracting (on which `sized_sentinel_for` relies).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D127194/new/
https://reviews.llvm.org/D127194
More information about the libcxx-commits
mailing list