Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
libcxx/include/__algorithm/ranges_find_last_if.h
- This file was added.
//===----------------------------------------------------------------------===// | |||||||||
// | |||||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||||||||
// See https://llvm.org/LICENSE.txt for license information. | |||||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||||||||
// | |||||||||
//===----------------------------------------------------------------------===// | |||||||||
#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H | |||||||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H | |||||||||
#include <__config> | |||||||||
#include <__functional/identity.h> | |||||||||
#include <__functional/invoke.h> | |||||||||
#include <__functional/ranges_operations.h> | |||||||||
#include <__iterator/concepts.h> | |||||||||
#include <__iterator/projected.h> | |||||||||
#include <__ranges/access.h> | |||||||||
#include <__ranges/concepts.h> | |||||||||
#include <__ranges/dangling.h> | |||||||||
#include <__ranges/range_adaptor.h> | |||||||||
#include <__ranges/subrange.h> | |||||||||
#include <__utility/move.h> | |||||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |||||||||
# pragma GCC system_header | |||||||||
#endif | |||||||||
#if _LIBCPP_STD_VER >= 23 | |||||||||
_LIBCPP_BEGIN_NAMESPACE_STD | |||||||||
namespace ranges { | |||||||||
template <class _Ip, class _Sp, class _Pred, class _Proj> | |||||||||
_LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Ip> | |||||||||
__find_last_if_impl(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj) { | |||||||||
huixie90: There are several issues.
1. In general `__last` is a sentinel (as supposed to be an iterator). | |||||||||
_Ip __current = __first; | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsNormally we simply increment __first, no need to create a separate variable. var-const: Normally we simply increment `__first`, no need to create a separate variable. | |||||||||
subrange<_Ip> __result{__last, __last}; | |||||||||
Please don't use auto everywhere, this just makes things harder to read. Mordante: Please don't use `auto` everywhere, this just makes things harder to read.
Please make sure all… | |||||||||
while (__current != __last) { | |||||||||
if (std::invoke(__pred, std::invoke(__proj, *__current))) { | |||||||||
__result = {__current, __last}; | |||||||||
} | |||||||||
++__current; | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsFor a bidirectional common range, it seems more efficient to iterate from the end -- then you can return as soon as you find an element satisfying the predicate. For a bidirectional non-common range, it might still be more efficient to create an iterator from the sentinel and go from the end (though this is debatable). var-const: For a bidirectional common range, it seems more efficient to iterate from the end -- then you… | |||||||||
} | |||||||||
return __result; | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsRecreating the whole __result each time seems a little wasteful, consider: _Ip __result = __last; while (__first != __last) { if (std::invoke(__pred, std::invoke(__proj, * __first))) { __result = __first; } ++__first; } return {__result, __last}; var-const: Recreating the whole `__result` each time seems a little wasteful, consider:
```
_Ip __result… | |||||||||
} | |||||||||
namespace __find_last_if { | |||||||||
struct __fn { | |||||||||
template <forward_range _Rp, | |||||||||
class _Proj = identity, | |||||||||
indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> | |||||||||
_LIBCPP_NODISCARD_EXT constexpr borrowed_subrange_t<_Rp> | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsMissing _LIBCPP_HIDE_FROM_ABI. var-const: Missing `_LIBCPP_HIDE_FROM_ABI`. | |||||||||
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { | |||||||||
return ranges::__find_last_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); | |||||||||
} | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsPlease add a newline after this line. var-const: Please add a newline after this line. | |||||||||
template <forward_iterator _Ip, | |||||||||
sentinel_for<_Ip> _Sp, | |||||||||
class _Proj = identity, | |||||||||
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred> | |||||||||
_LIBCPP_NODISCARD_EXT constexpr subrange<_Ip> | |||||||||
var-constUnsubmitted Not Done ReplyInline ActionsMissing _LIBCPP_HIDE_FROM_ABI. var-const: Missing `_LIBCPP_HIDE_FROM_ABI`. | |||||||||
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { | |||||||||
return ranges::__find_last_if_impl(std::move(__first), std::move(__last), __pred, __proj); | |||||||||
} | |||||||||
}; | |||||||||
} // namespace __find_last_if | |||||||||
inline namespace __cpo { | |||||||||
inline constexpr auto find_last_if = __find_last_if::__fn{}; | |||||||||
} // namespace __cpo | |||||||||
} // namespace ranges | |||||||||
_LIBCPP_END_NAMESPACE_STD | |||||||||
#endif // _LIBCPP_STD_VER > 23 | |||||||||
var-constUnsubmitted Not Done ReplyInline Actions>= 23. var-const: `>= 23`. | |||||||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_IF_H | |||||||||
No newline at end of file |
There are several issues.