mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 00:16:30 +00:00
This reverts commit 68c04b0ae62d8431d72d8b47fc13008002ee4387. This disables the IWYU mapping that caused the failure, since the headers aren't reachable for now. This is the first part of the "Freezing C++03 headers" proposal explained in https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc/77319/58. This patch mechanically copies the headers as of the LLVM 19.1 release into a subdirectory of libc++ so that we can start using these headers when building in C++03 mode. We are going to be backporting important changes to that copy of the headers until the LLVM 21 release. After the LLVM 21 release, only critical bugfixes will be fixed in the C++03 copy of the headers. This patch only performs a copy of the headers -- these headers are still unused by the rest of the codebase.
This commit is contained in:
parent
c9199700b8
commit
e78f53d1e8
1092
libcxx/include/__cxx03/CMakeLists.txt
Normal file
1092
libcxx/include/__cxx03/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
58
libcxx/include/__cxx03/__algorithm/adjacent_find.h
Normal file
58
libcxx/include/__cxx03/__algorithm/adjacent_find.h
Normal file
@ -0,0 +1,58 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ADJACENT_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter, class _Sent, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
|
||||
__adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) {
|
||||
if (__first == __last)
|
||||
return __first;
|
||||
_Iter __i = __first;
|
||||
while (++__i != __last) {
|
||||
if (__pred(*__first, *__i))
|
||||
return __first;
|
||||
__first = __i;
|
||||
}
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) {
|
||||
return std::__adjacent_find(std::move(__first), std::move(__last), __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
adjacent_find(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::adjacent_find(std::move(__first), std::move(__last), __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H
|
32
libcxx/include/__cxx03/__algorithm/all_of.h
Normal file
32
libcxx/include/__cxx03/__algorithm/all_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ALL_OF_H
|
||||
#define _LIBCPP___ALGORITHM_ALL_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ALL_OF_H
|
32
libcxx/include/__cxx03/__algorithm/any_of.h
Normal file
32
libcxx/include/__cxx03/__algorithm/any_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ANY_OF_H
|
||||
#define _LIBCPP___ALGORITHM_ANY_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ANY_OF_H
|
39
libcxx/include/__cxx03/__algorithm/binary_search.h
Normal file
39
libcxx/include/__cxx03/__algorithm/binary_search.h
Normal file
@ -0,0 +1,39 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_BINARY_SEARCH_H
|
||||
#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
|
||||
__first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp);
|
||||
return __first != __last && !__comp(__value, *__first);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::binary_search(__first, __last, __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H
|
44
libcxx/include/__cxx03/__algorithm/clamp.h
Normal file
44
libcxx/include/__cxx03/__algorithm/clamp.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_CLAMP_H
|
||||
#define _LIBCPP___ALGORITHM_CLAMP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
template <class _Tp, class _Compare>
|
||||
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
|
||||
clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v,
|
||||
_LIBCPP_LIFETIMEBOUND const _Tp& __lo,
|
||||
_LIBCPP_LIFETIMEBOUND const _Tp& __hi,
|
||||
_Compare __comp) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(!__comp(__hi, __lo), "Bad bounds passed to std::clamp");
|
||||
return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&
|
||||
clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v,
|
||||
_LIBCPP_LIFETIMEBOUND const _Tp& __lo,
|
||||
_LIBCPP_LIFETIMEBOUND const _Tp& __hi) {
|
||||
return std::clamp(__v, __lo, __hi, __less<>());
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_CLAMP_H
|
49
libcxx/include/__cxx03/__algorithm/comp.h
Normal file
49
libcxx/include/__cxx03/__algorithm/comp.h
Normal file
@ -0,0 +1,49 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COMP_H
|
||||
#define _LIBCPP___ALGORITHM_COMP_H
|
||||
|
||||
#include <__config>
|
||||
#include <__type_traits/desugars_to.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
struct __equal_to {
|
||||
template <class _T1, class _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _T1& __x, const _T2& __y) const {
|
||||
return __x == __y;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline const bool __desugars_to_v<__equal_tag, __equal_to, _Tp, _Up> = true;
|
||||
|
||||
// The definition is required because __less is part of the ABI, but it's empty
|
||||
// because all comparisons should be transparent.
|
||||
template <class _T1 = void, class _T2 = _T1>
|
||||
struct __less {};
|
||||
|
||||
template <>
|
||||
struct __less<void, void> {
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const {
|
||||
return __lhs < __rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COMP_H
|
67
libcxx/include/__cxx03/__algorithm/comp_ref_type.h
Normal file
67
libcxx/include/__cxx03/__algorithm/comp_ref_type.h
Normal file
@ -0,0 +1,67 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COMP_REF_TYPE_H
|
||||
#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__utility/declval.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare>
|
||||
struct __debug_less {
|
||||
_Compare& __comp_;
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Up& __y) {
|
||||
bool __r = __comp_(__x, __y);
|
||||
if (__r)
|
||||
__do_compare_assert(0, __y, __x);
|
||||
return __r;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(_Tp& __x, _Up& __y) {
|
||||
bool __r = __comp_(__x, __y);
|
||||
if (__r)
|
||||
__do_compare_assert(0, __y, __x);
|
||||
return __r;
|
||||
}
|
||||
|
||||
template <class _LHS, class _RHS>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 inline
|
||||
_LIBCPP_HIDE_FROM_ABI decltype((void)std::declval<_Compare&>()(std::declval<_LHS&>(), std::declval<_RHS&>()))
|
||||
__do_compare_assert(int, _LHS& __l, _RHS& __r) {
|
||||
_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering");
|
||||
(void)__l;
|
||||
(void)__r;
|
||||
}
|
||||
|
||||
template <class _LHS, class _RHS>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI void __do_compare_assert(long, _LHS&, _RHS&) {}
|
||||
};
|
||||
|
||||
// Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference.
|
||||
#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
|
||||
template <class _Comp>
|
||||
using __comp_ref_type = __debug_less<_Comp>;
|
||||
#else
|
||||
template <class _Comp>
|
||||
using __comp_ref_type = _Comp&;
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H
|
123
libcxx/include/__cxx03/__algorithm/copy.h
Normal file
123
libcxx/include/__cxx03/__algorithm/copy.h
Normal file
@ -0,0 +1,123 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/for_each_segment.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __copy_impl {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
while (__first != __last) {
|
||||
*__result = *__first;
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
struct _CopySegment {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
|
||||
_OutIter& __result_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _CopySegment(_OutIter& __result)
|
||||
: __result_(__result) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
||||
__result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result));
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
|
||||
auto __local_first = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_last = _Traits::__end(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iters = std::__copy<_AlgPolicy>(__first, __first + __size, __local_first);
|
||||
__first = std::move(__iters.first);
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
|
||||
|
||||
__local_first = _Traits::__begin(++__segment_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
__copy(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
return std::__copy_move_unwrap_iters<__copy_impl<_AlgPolicy> >(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_H
|
137
libcxx/include/__cxx03/__algorithm/copy_backward.h
Normal file
137
libcxx/include/__cxx03/__algorithm/copy_backward.h
Normal file
@ -0,0 +1,137 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
|
||||
__copy_backward(_InIter __first, _Sent __last, _OutIter __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __copy_backward_impl {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
auto __original_last_iter = __last_iter;
|
||||
|
||||
while (__first != __last_iter) {
|
||||
*--__result = *--__last_iter;
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
if (__sfirst == __slast) {
|
||||
auto __iters =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
||||
return std::make_pair(__last, __iters.second);
|
||||
}
|
||||
|
||||
__result =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
while (__sfirst != __slast) {
|
||||
__result =
|
||||
std::__copy_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
}
|
||||
__result = std::__copy_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
auto __orig_last = __last;
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
|
||||
// When the range contains no elements, __result might not be a valid iterator
|
||||
if (__first == __last)
|
||||
return std::make_pair(__first, __result);
|
||||
|
||||
auto __local_last = _Traits::__local(__result);
|
||||
while (true) {
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
auto __local_first = _Traits::__begin(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iter = std::__copy_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
|
||||
__last -= __size;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
|
||||
--__segment_iterator;
|
||||
__local_last = _Traits::__end(__segment_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_backward_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
|
||||
return std::__copy_move_unwrap_iters<__copy_backward_impl<_AlgPolicy> >(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
|
||||
copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
|
||||
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
|
||||
std::is_copy_constructible<_BidirectionalIterator1>::value,
|
||||
"Iterators must be copy constructible.");
|
||||
|
||||
return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H
|
34
libcxx/include/__cxx03/__algorithm/copy_if.h
Normal file
34
libcxx/include/__cxx03/__algorithm/copy_if.h
Normal file
@ -0,0 +1,34 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_IF_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_IF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _OutputIterator, class _Predicate>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (__pred(*__first)) {
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_IF_H
|
114
libcxx/include/__cxx03/__algorithm/copy_move_common.h
Normal file
114
libcxx/include/__cxx03/__algorithm/copy_move_common.h
Normal file
@ -0,0 +1,114 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_MOVE_COMMON_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__algorithm/unwrap_range.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/pointer_traits.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_always_bitcastable.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__type_traits/is_trivially_assignable.h>
|
||||
#include <__type_traits/is_volatile.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Type traits.
|
||||
|
||||
template <class _From, class _To>
|
||||
struct __can_lower_copy_assignment_to_memmove {
|
||||
static const bool value =
|
||||
// If the types are always bitcastable, it's valid to do a bitwise copy between them.
|
||||
__is_always_bitcastable<_From, _To>::value &&
|
||||
// Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays).
|
||||
is_trivially_assignable<_To&, const _From&>::value &&
|
||||
// `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case.
|
||||
!is_volatile<_From>::value && !is_volatile<_To>::value;
|
||||
};
|
||||
|
||||
template <class _From, class _To>
|
||||
struct __can_lower_move_assignment_to_memmove {
|
||||
static const bool value =
|
||||
__is_always_bitcastable<_From, _To>::value && is_trivially_assignable<_To&, _From&&>::value &&
|
||||
!is_volatile<_From>::value && !is_volatile<_To>::value;
|
||||
};
|
||||
|
||||
// `memmove` algorithms implementation.
|
||||
|
||||
template <class _In, class _Out>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
__copy_trivial_impl(_In* __first, _In* __last, _Out* __result) {
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
|
||||
std::__constexpr_memmove(__result, __first, __element_count(__n));
|
||||
|
||||
return std::make_pair(__last, __result + __n);
|
||||
}
|
||||
|
||||
template <class _In, class _Out>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
__copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) {
|
||||
const size_t __n = static_cast<size_t>(__last - __first);
|
||||
__result -= __n;
|
||||
|
||||
std::__constexpr_memmove(__result, __first, __element_count(__n));
|
||||
|
||||
return std::make_pair(__last, __result);
|
||||
}
|
||||
|
||||
// Iterator unwrapping and dispatching to the correct overload.
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
struct __can_rewrap
|
||||
: integral_constant<bool, is_copy_constructible<_InIter>::value && is_copy_constructible<_OutIter>::value> {};
|
||||
|
||||
template <class _Algorithm,
|
||||
class _InIter,
|
||||
class _Sent,
|
||||
class _OutIter,
|
||||
__enable_if_t<__can_rewrap<_InIter, _OutIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
|
||||
__copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
|
||||
auto __range = std::__unwrap_range(__first, std::move(__last));
|
||||
auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first));
|
||||
return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)),
|
||||
std::__rewrap_iter(std::move(__out_first), std::move(__result.second)));
|
||||
}
|
||||
|
||||
template <class _Algorithm,
|
||||
class _InIter,
|
||||
class _Sent,
|
||||
class _OutIter,
|
||||
__enable_if_t<!__can_rewrap<_InIter, _OutIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter>
|
||||
__copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) {
|
||||
return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H
|
60
libcxx/include/__cxx03/__algorithm/copy_n.h
Normal file
60
libcxx/include/__cxx03/__algorithm/copy_n.h
Normal file
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_N_H
|
||||
#define _LIBCPP___ALGORITHM_COPY_N_H
|
||||
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator,
|
||||
class _Size,
|
||||
class _OutputIterator,
|
||||
__enable_if_t<__has_input_iterator_category<_InputIterator>::value &&
|
||||
!__has_random_access_iterator_category<_InputIterator>::value,
|
||||
int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
|
||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
if (__n > 0) {
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
for (--__n; __n > 0; --__n) {
|
||||
++__first;
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _InputIterator,
|
||||
class _Size,
|
||||
class _OutputIterator,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InputIterator>::value, int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) {
|
||||
typedef typename iterator_traits<_InputIterator>::difference_type difference_type;
|
||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
return std::copy(__first, __first + difference_type(__n), __result);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COPY_N_H
|
92
libcxx/include/__cxx03/__algorithm/count.h
Normal file
92
libcxx/include/__cxx03/__algorithm/count.h
Normal file
@ -0,0 +1,92 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COUNT_H
|
||||
#define _LIBCPP___ALGORITHM_COUNT_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__bit/invert_if.h>
|
||||
#include <__bit/popcount.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__fwd/bit_reference.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// generic implementation
|
||||
template <class _AlgPolicy, class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>
|
||||
__count(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||
typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> __r(0);
|
||||
for (; __first != __last; ++__first)
|
||||
if (std::__invoke(__proj, *__first) == __value)
|
||||
++__r;
|
||||
return __r;
|
||||
}
|
||||
|
||||
// __bit_iterator implementation
|
||||
template <bool _ToCount, class _Cp, bool _IsConst>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bit_iterator<_Cp, _IsConst>::difference_type
|
||||
__count_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
|
||||
using _It = __bit_iterator<_Cp, _IsConst>;
|
||||
using __storage_type = typename _It::__storage_type;
|
||||
using difference_type = typename _It::difference_type;
|
||||
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
difference_type __r = 0;
|
||||
// do first partial word
|
||||
if (__first.__ctz_ != 0) {
|
||||
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
|
||||
__storage_type __dn = std::min(__clz_f, __n);
|
||||
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
|
||||
__r = std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
|
||||
__n -= __dn;
|
||||
++__first.__seg_;
|
||||
}
|
||||
// do middle whole words
|
||||
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
|
||||
__r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_));
|
||||
// do last partial word
|
||||
if (__n > 0) {
|
||||
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
|
||||
__r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
|
||||
}
|
||||
return __r;
|
||||
}
|
||||
|
||||
template <class, class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> >
|
||||
__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
|
||||
if (__value)
|
||||
return std::__count_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
|
||||
return std::__count_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator>
|
||||
count(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
||||
__identity __proj;
|
||||
return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COUNT_H
|
35
libcxx/include/__cxx03/__algorithm/count_if.h
Normal file
35
libcxx/include/__cxx03/__algorithm/count_if.h
Normal file
@ -0,0 +1,35 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COUNT_IF_H
|
||||
#define _LIBCPP___ALGORITHM_COUNT_IF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
typename iterator_traits<_InputIterator>::difference_type
|
||||
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
typename iterator_traits<_InputIterator>::difference_type __r(0);
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
++__r;
|
||||
return __r;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_COUNT_IF_H
|
133
libcxx/include/__cxx03/__algorithm/equal.h
Normal file
133
libcxx/include/__cxx03/__algorithm/equal.h
Normal file
@ -0,0 +1,133 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_EQUAL_H
|
||||
#define _LIBCPP___ALGORITHM_EQUAL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/desugars_to.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_equality_comparable.h>
|
||||
#include <__type_traits/is_volatile.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) {
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2)
|
||||
if (!__pred(*__first1, *__first2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _BinaryPredicate,
|
||||
__enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, _Tp, _Up> && !is_volatile<_Tp>::value &&
|
||||
!is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
|
||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
||||
return std::__equal_iter_impl(
|
||||
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
|
||||
return std::equal(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
|
||||
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
return false;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
return __first1 == __last1 && __first2 == __last2;
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
__enable_if_t<__desugars_to_v<__equal_tag, _Pred, _Tp, _Up> && __is_identity<_Proj1>::value &&
|
||||
__is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value &&
|
||||
__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
|
||||
return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
|
||||
__has_random_access_iterator_category<_InputIterator2>::value) {
|
||||
if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
|
||||
return false;
|
||||
}
|
||||
__identity __proj;
|
||||
return std::__equal_impl(
|
||||
std::__unwrap_iter(__first1),
|
||||
std::__unwrap_iter(__last1),
|
||||
std::__unwrap_iter(__first2),
|
||||
std::__unwrap_iter(__last2),
|
||||
__pred,
|
||||
__proj,
|
||||
__proj);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::equal(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 14
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_EQUAL_H
|
85
libcxx/include/__cxx03/__algorithm/equal_range.h
Normal file
85
libcxx/include/__cxx03/__algorithm/equal_range.h
Normal file
@ -0,0 +1,85 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_EQUAL_RANGE_H
|
||||
#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/upper_bound.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
|
||||
__equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp, _Proj&& __proj) {
|
||||
auto __len = _IterOps<_AlgPolicy>::distance(__first, __last);
|
||||
_Iter __end = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
while (__len != 0) {
|
||||
auto __half_len = std::__half_positive(__len);
|
||||
_Iter __mid = _IterOps<_AlgPolicy>::next(__first, __half_len);
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__mid), __value)) {
|
||||
__first = ++__mid;
|
||||
__len -= __half_len + 1;
|
||||
} else if (std::__invoke(__comp, __value, std::__invoke(__proj, *__mid))) {
|
||||
__end = __mid;
|
||||
__len = __half_len;
|
||||
} else {
|
||||
_Iter __mp1 = __mid;
|
||||
return pair<_Iter, _Iter>(std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj),
|
||||
std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj));
|
||||
}
|
||||
}
|
||||
return pair<_Iter, _Iter>(__first, __first);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable");
|
||||
static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible");
|
||||
return std::__equal_range<_ClassicAlgPolicy>(
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
__value,
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp),
|
||||
std::__identity());
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::equal_range(std::move(__first), std::move(__last), __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H
|
45
libcxx/include/__cxx03/__algorithm/fill.h
Normal file
45
libcxx/include/__cxx03/__algorithm/fill.h
Normal file
@ -0,0 +1,45 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FILL_H
|
||||
#define _LIBCPP___ALGORITHM_FILL_H
|
||||
|
||||
#include <__algorithm/fill_n.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) {
|
||||
for (; __first != __last; ++__first)
|
||||
*__first = __value;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) {
|
||||
std::fill_n(__first, __last - __first, __value);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FILL_H
|
98
libcxx/include/__cxx03/__algorithm/fill_n.h
Normal file
98
libcxx/include/__cxx03/__algorithm/fill_n.h
Normal file
@ -0,0 +1,98 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FILL_N_H
|
||||
#define _LIBCPP___ALGORITHM_FILL_N_H
|
||||
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__fwd/bit_reference.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/pointer_traits.h>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value);
|
||||
|
||||
template <bool _FillVal, class _Cp>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
|
||||
__fill_n_bool(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) {
|
||||
using _It = __bit_iterator<_Cp, false>;
|
||||
using __storage_type = typename _It::__storage_type;
|
||||
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
// do first partial word
|
||||
if (__first.__ctz_ != 0) {
|
||||
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
|
||||
__storage_type __dn = std::min(__clz_f, __n);
|
||||
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
|
||||
if (_FillVal)
|
||||
*__first.__seg_ |= __m;
|
||||
else
|
||||
*__first.__seg_ &= ~__m;
|
||||
__n -= __dn;
|
||||
++__first.__seg_;
|
||||
}
|
||||
// do middle whole words
|
||||
__storage_type __nw = __n / __bits_per_word;
|
||||
std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0);
|
||||
__n -= __nw * __bits_per_word;
|
||||
// do last partial word
|
||||
if (__n > 0) {
|
||||
__first.__seg_ += __nw;
|
||||
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
|
||||
if (_FillVal)
|
||||
*__first.__seg_ |= __m;
|
||||
else
|
||||
*__first.__seg_ &= ~__m;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Cp, class _Size>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false>
|
||||
__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) {
|
||||
if (__n > 0) {
|
||||
if (__value)
|
||||
std::__fill_n_bool<true>(__first, __n);
|
||||
else
|
||||
std::__fill_n_bool<false>(__first, __n);
|
||||
}
|
||||
return __first + __n;
|
||||
}
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
||||
for (; __n > 0; ++__first, (void)--__n)
|
||||
*__first = __value;
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Tp>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) {
|
||||
return std::__fill_n(__first, std::__convert_to_integral(__n), __value);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FILL_N_H
|
181
libcxx/include/__cxx03/__algorithm/find.h
Normal file
181
libcxx/include/__cxx03/__algorithm/find.h
Normal file
@ -0,0 +1,181 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_H
|
||||
|
||||
#include <__algorithm/find_segment_if.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__bit/countr.h>
|
||||
#include <__bit/invert_if.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__fwd/bit_reference.h>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__string/constexpr_c_functions.h>
|
||||
#include <__type_traits/is_integral.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__type_traits/is_signed.h>
|
||||
#include <__utility/move.h>
|
||||
#include <limits>
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
# include <cwchar>
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// generic implementation
|
||||
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
||||
__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (std::__invoke(__proj, *__first) == __value)
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
// trivially equality comparable implementations
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
sizeof(_Tp) == 1,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||
if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first))
|
||||
return __ret;
|
||||
return __last;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t),
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) {
|
||||
if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first))
|
||||
return __ret;
|
||||
return __last;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
|
||||
|
||||
// TODO: This should also be possible to get right with different signedness
|
||||
// cast integral types to allow vectorization
|
||||
template <class _Tp,
|
||||
class _Up,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_identity<_Proj>::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value &&
|
||||
is_integral<_Tp>::value && is_integral<_Up>::value &&
|
||||
is_signed<_Tp>::value == is_signed<_Up>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
|
||||
__find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
|
||||
if (__value < numeric_limits<_Tp>::min() || __value > numeric_limits<_Tp>::max())
|
||||
return __last;
|
||||
return std::__find(__first, __last, _Tp(__value), __proj);
|
||||
}
|
||||
|
||||
// __bit_iterator implementation
|
||||
template <bool _ToFind, class _Cp, bool _IsConst>
|
||||
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst>
|
||||
__find_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) {
|
||||
using _It = __bit_iterator<_Cp, _IsConst>;
|
||||
using __storage_type = typename _It::__storage_type;
|
||||
|
||||
const int __bits_per_word = _It::__bits_per_word;
|
||||
// do first partial word
|
||||
if (__first.__ctz_ != 0) {
|
||||
__storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_);
|
||||
__storage_type __dn = std::min(__clz_f, __n);
|
||||
__storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn));
|
||||
__storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_) & __m;
|
||||
if (__b)
|
||||
return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b)));
|
||||
if (__n == __dn)
|
||||
return __first + __n;
|
||||
__n -= __dn;
|
||||
++__first.__seg_;
|
||||
}
|
||||
// do middle whole words
|
||||
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) {
|
||||
__storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_);
|
||||
if (__b)
|
||||
return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b)));
|
||||
}
|
||||
// do last partial word
|
||||
if (__n > 0) {
|
||||
__storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
|
||||
__storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_) & __m;
|
||||
if (__b)
|
||||
return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b)));
|
||||
}
|
||||
return _It(__first.__seg_, static_cast<unsigned>(__n));
|
||||
}
|
||||
|
||||
template <class _Cp, bool _IsConst, class _Tp, class _Proj, __enable_if_t<__is_identity<_Proj>::value, int> = 0>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, _IsConst>
|
||||
__find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) {
|
||||
if (static_cast<bool>(__value))
|
||||
return std::__find_bool<true>(__first, static_cast<typename _Cp::size_type>(__last - __first));
|
||||
return std::__find_bool<false>(__first, static_cast<typename _Cp::size_type>(__last - __first));
|
||||
}
|
||||
|
||||
// segmented iterator implementation
|
||||
|
||||
template <class>
|
||||
struct __find_segment;
|
||||
|
||||
template <class _SegmentedIterator,
|
||||
class _Tp,
|
||||
class _Proj,
|
||||
__enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
||||
__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
|
||||
return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
struct __find_segment {
|
||||
const _Tp& __value_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __find_segment(const _Tp& __value) : __value_(__value) {}
|
||||
|
||||
template <class _InputIterator, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator
|
||||
operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const {
|
||||
return std::__find(__first, __last, __value_, __proj);
|
||||
}
|
||||
};
|
||||
|
||||
// public API
|
||||
template <class _InputIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find(_InputIterator __first, _InputIterator __last, const _Tp& __value) {
|
||||
__identity __proj;
|
||||
return std::__rewrap_iter(
|
||||
__first, std::__find(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_H
|
225
libcxx/include/__cxx03/__algorithm/find_end.h
Normal file
225
libcxx/include/__cxx03/__algorithm/find_end.h
Normal file
@ -0,0 +1,225 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_END_OF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_END_OF_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/search.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template < class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
forward_iterator_tag,
|
||||
forward_iterator_tag) {
|
||||
// modeled after search algorithm
|
||||
_Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer
|
||||
_Iter1 __match_last = __match_first;
|
||||
if (__first2 == __last2)
|
||||
return pair<_Iter1, _Iter1>(__match_last, __match_last);
|
||||
while (true) {
|
||||
while (true) {
|
||||
if (__first1 == __last1) // if source exhausted return last correct answer (or __last1 if never found)
|
||||
return pair<_Iter1, _Iter1>(__match_first, __match_last);
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
}
|
||||
// *__first1 matches *__first2, now match elements after here
|
||||
_Iter1 __m1 = __first1;
|
||||
_Iter2 __m2 = __first2;
|
||||
while (true) {
|
||||
if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one
|
||||
__match_first = __first1;
|
||||
__match_last = ++__m1;
|
||||
++__first1;
|
||||
break;
|
||||
}
|
||||
if (++__m1 == __last1) // Source exhausted, return last answer
|
||||
return pair<_Iter1, _Iter1>(__match_first, __match_last);
|
||||
// mismatch, restart with a new __first
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
|
||||
++__first1;
|
||||
break;
|
||||
} // else there is a match, check next elements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < class _IterOps,
|
||||
class _Pred,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __sent1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __sent2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
bidirectional_iterator_tag,
|
||||
bidirectional_iterator_tag) {
|
||||
auto __last1 = _IterOps::next(__first1, __sent1);
|
||||
auto __last2 = _IterOps::next(__first2, __sent2);
|
||||
// modeled after search algorithm (in reverse)
|
||||
if (__first2 == __last2)
|
||||
return __last1; // Everything matches an empty sequence
|
||||
_Iter1 __l1 = __last1;
|
||||
_Iter2 __l2 = __last2;
|
||||
--__l2;
|
||||
while (true) {
|
||||
// Find last element in sequence 1 that matchs *(__last2-1), with a mininum of loop checks
|
||||
while (true) {
|
||||
if (__first1 == __l1) // return __last1 if no element matches *__first2
|
||||
return __last1;
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||
break;
|
||||
}
|
||||
// *__l1 matches *__l2, now match elements before here
|
||||
_Iter1 __m1 = __l1;
|
||||
_Iter2 __m2 = __l2;
|
||||
while (true) {
|
||||
if (__m2 == __first2) // If pattern exhausted, __m1 is the answer (works for 1 element pattern)
|
||||
return __m1;
|
||||
if (__m1 == __first1) // Otherwise if source exhaused, pattern not found
|
||||
return __last1;
|
||||
|
||||
// if there is a mismatch, restart with a new __l1
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) {
|
||||
break;
|
||||
} // else there is a match, check next elements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < class _AlgPolicy,
|
||||
class _Pred,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __sent1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __sent2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
random_access_iterator_tag,
|
||||
random_access_iterator_tag) {
|
||||
typedef typename iterator_traits<_Iter1>::difference_type _D1;
|
||||
auto __last1 = _IterOps<_AlgPolicy>::next(__first1, __sent1);
|
||||
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __sent2);
|
||||
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
|
||||
auto __len2 = __last2 - __first2;
|
||||
if (__len2 == 0)
|
||||
return __last1;
|
||||
auto __len1 = __last1 - __first1;
|
||||
if (__len1 < __len2)
|
||||
return __last1;
|
||||
const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here
|
||||
_Iter1 __l1 = __last1;
|
||||
_Iter2 __l2 = __last2;
|
||||
--__l2;
|
||||
while (true) {
|
||||
while (true) {
|
||||
if (__s == __l1)
|
||||
return __last1;
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *--__l1), std::__invoke(__proj2, *__l2)))
|
||||
break;
|
||||
}
|
||||
_Iter1 __m1 = __l1;
|
||||
_Iter2 __m2 = __l2;
|
||||
while (true) {
|
||||
if (__m2 == __first2)
|
||||
return __m1;
|
||||
// no need to check range on __m1 because __s guarantees we have enough source
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(*--__m2))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic(
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate& __pred) {
|
||||
auto __proj = __identity();
|
||||
return std::__find_end_impl<_ClassicAlgPolicy>(
|
||||
__first1,
|
||||
__last1,
|
||||
__first2,
|
||||
__last2,
|
||||
__pred,
|
||||
__proj,
|
||||
__proj,
|
||||
typename iterator_traits<_ForwardIterator1>::iterator_category(),
|
||||
typename iterator_traits<_ForwardIterator2>::iterator_category())
|
||||
.first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end(
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
|
||||
find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::find_end(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H
|
55
libcxx/include/__cxx03/__algorithm/find_first_of.h
Normal file
55
libcxx/include/__cxx03/__algorithm/find_first_of.h
Normal file
@ -0,0 +1,55 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_FIRST_OF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate&& __pred) {
|
||||
for (; __first1 != __last1; ++__first1)
|
||||
for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j)
|
||||
if (__pred(*__first1, *__j))
|
||||
return __first1;
|
||||
return __last1;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of(
|
||||
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H
|
32
libcxx/include/__cxx03/__algorithm/find_if.h
Normal file
32
libcxx/include/__cxx03/__algorithm/find_if.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_IF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_IF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_IF_H
|
32
libcxx/include/__cxx03/__algorithm/find_if_not.h
Normal file
32
libcxx/include/__cxx03/__algorithm/find_if_not.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_IF_NOT_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H
|
62
libcxx/include/__cxx03/__algorithm/find_segment_if.h
Normal file
62
libcxx/include/__cxx03/__algorithm/find_segment_if.h
Normal file
@ -0,0 +1,62 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIND_SEGMENT_IF_H
|
||||
#define _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// __find_segment_if is a utility function for optimizing iteration over segmented iterators linearly.
|
||||
// [__first, __last) has to be a segmented range. __pred is expected to take a range of local iterators and the __proj.
|
||||
// It returns an iterator to the first element that satisfies the predicate, or a one-past-the-end iterator if there was
|
||||
// no match. __proj may be anything that should be passed to __pred, but is expected to be a projection to support
|
||||
// ranges algorithms, or __identity for classic algorithms.
|
||||
|
||||
template <class _SegmentedIterator, class _Pred, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
|
||||
__find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred __pred, _Proj& __proj) {
|
||||
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
|
||||
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
|
||||
// We are in a single segment, so we might not be at the beginning or end
|
||||
if (__sfirst == __slast)
|
||||
return _Traits::__compose(__sfirst, __pred(_Traits::__local(__first), _Traits::__local(__last), __proj));
|
||||
|
||||
{ // We have more than one segment. Iterate over the first segment, since we might not start at the beginning
|
||||
auto __llast = _Traits::__end(__sfirst);
|
||||
auto __liter = __pred(_Traits::__local(__first), __llast, __proj);
|
||||
if (__liter != __llast)
|
||||
return _Traits::__compose(__sfirst, __liter);
|
||||
}
|
||||
++__sfirst;
|
||||
|
||||
// Iterate over the segments which are guaranteed to be completely in the range
|
||||
while (__sfirst != __slast) {
|
||||
auto __llast = _Traits::__end(__sfirst);
|
||||
auto __liter = __pred(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __proj);
|
||||
if (__liter != __llast)
|
||||
return _Traits::__compose(__sfirst, __liter);
|
||||
++__sfirst;
|
||||
}
|
||||
|
||||
// Iterate over the last segment
|
||||
return _Traits::__compose(__sfirst, __pred(_Traits::__begin(__sfirst), _Traits::__local(__last), __proj));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H
|
128
libcxx/include/__cxx03/__algorithm/fold.h
Normal file
128
libcxx/include/__cxx03/__algorithm/fold.h
Normal file
@ -0,0 +1,128 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FOLD_H
|
||||
#define _LIBCPP___ALGORITHM_FOLD_H
|
||||
|
||||
#include <__concepts/assignable.h>
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__concepts/invocable.h>
|
||||
#include <__concepts/movable.h>
|
||||
#include <__config>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/reference_wrapper.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/invoke.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
namespace ranges {
|
||||
template <class _Ip, class _Tp>
|
||||
struct in_value_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Ip in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Tp value;
|
||||
|
||||
template <class _I2, class _T2>
|
||||
requires convertible_to<const _Ip&, _I2> && convertible_to<const _Tp&, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_value_result<_I2, _T2>() const& {
|
||||
return {in, value};
|
||||
}
|
||||
|
||||
template <class _I2, class _T2>
|
||||
requires convertible_to<_Ip, _I2> && convertible_to<_Tp, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_value_result<_I2, _T2>() && {
|
||||
return {std::move(in), std::move(value)};
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Ip, class _Tp>
|
||||
using fold_left_with_iter_result = in_value_result<_Ip, _Tp>;
|
||||
|
||||
template <class _Fp, class _Tp, class _Ip, class _Rp, class _Up = decay_t<_Rp>>
|
||||
concept __indirectly_binary_left_foldable_impl =
|
||||
convertible_to<_Rp, _Up> && //
|
||||
movable<_Tp> && //
|
||||
movable<_Up> && //
|
||||
convertible_to<_Tp, _Up> && //
|
||||
invocable<_Fp&, _Up, iter_reference_t<_Ip>> && //
|
||||
assignable_from<_Up&, invoke_result_t<_Fp&, _Up, iter_reference_t<_Ip>>>;
|
||||
|
||||
template <class _Fp, class _Tp, class _Ip>
|
||||
concept __indirectly_binary_left_foldable =
|
||||
copy_constructible<_Fp> && //
|
||||
invocable<_Fp&, _Tp, iter_reference_t<_Ip>> && //
|
||||
__indirectly_binary_left_foldable_impl<_Fp, _Tp, _Ip, invoke_result_t<_Fp&, _Tp, iter_reference_t<_Ip>>>;
|
||||
|
||||
struct __fold_left_with_iter {
|
||||
template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) {
|
||||
using _Up = decay_t<invoke_result_t<_Fp&, _Tp, iter_reference_t<_Ip>>>;
|
||||
|
||||
if (__first == __last) {
|
||||
return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), _Up(std::move(__init))};
|
||||
}
|
||||
|
||||
_Up __result = std::invoke(__f, std::move(__init), *__first);
|
||||
for (++__first; __first != __last; ++__first) {
|
||||
__result = std::invoke(__f, std::move(__result), *__first);
|
||||
}
|
||||
|
||||
return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
template <input_range _Rp, class _Tp, __indirectly_binary_left_foldable<_Tp, iterator_t<_Rp>> _Fp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) {
|
||||
auto __result = operator()(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f));
|
||||
|
||||
using _Up = decay_t<invoke_result_t<_Fp&, _Tp, range_reference_t<_Rp>>>;
|
||||
return fold_left_with_iter_result<borrowed_iterator_t<_Rp>, _Up>{std::move(__result.in), std::move(__result.value)};
|
||||
}
|
||||
};
|
||||
|
||||
inline constexpr auto fold_left_with_iter = __fold_left_with_iter();
|
||||
|
||||
struct __fold_left {
|
||||
template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) {
|
||||
return fold_left_with_iter(std::move(__first), std::move(__last), std::move(__init), std::ref(__f)).value;
|
||||
}
|
||||
|
||||
template <input_range _Rp, class _Tp, __indirectly_binary_left_foldable<_Tp, iterator_t<_Rp>> _Fp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) {
|
||||
return fold_left_with_iter(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)).value;
|
||||
}
|
||||
};
|
||||
|
||||
inline constexpr auto fold_left = __fold_left();
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOLD_H
|
57
libcxx/include/__cxx03/__algorithm/for_each.h
Normal file
57
libcxx/include/__cxx03/__algorithm/for_each.h
Normal file
@ -0,0 +1,57 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FOR_EACH_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_H
|
||||
|
||||
#include <__algorithm/for_each_segment.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__utility/in_place.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Function>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function
|
||||
for_each(_InputIterator __first, _InputIterator __last, _Function __f) {
|
||||
for (; __first != __last; ++__first)
|
||||
__f(*__first);
|
||||
return __f;
|
||||
}
|
||||
|
||||
// __movable_box is available in C++20, but is actually a copyable-box, so optimization is only correct in C++23
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
template <class _SegmentedIterator, class _Function>
|
||||
requires __is_segmented_iterator<_SegmentedIterator>::value
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Function
|
||||
for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function __func) {
|
||||
ranges::__movable_box<_Function> __wrapped_func(in_place, std::move(__func));
|
||||
std::__for_each_segment(__first, __last, [&](auto __lfirst, auto __llast) {
|
||||
__wrapped_func =
|
||||
ranges::__movable_box<_Function>(in_place, std::for_each(__lfirst, __llast, std::move(*__wrapped_func)));
|
||||
});
|
||||
return std::move(*__wrapped_func);
|
||||
}
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_H
|
41
libcxx/include/__cxx03/__algorithm/for_each_n.h
Normal file
41
libcxx/include/__cxx03/__algorithm/for_each_n.h
Normal file
@ -0,0 +1,41 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FOR_EACH_N_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
|
||||
template <class _InputIterator, class _Size, class _Function>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator
|
||||
for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) {
|
||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
while (__n > 0) {
|
||||
__f(*__first);
|
||||
++__first;
|
||||
--__n;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H
|
53
libcxx/include/__cxx03/__algorithm/for_each_segment.h
Normal file
53
libcxx/include/__cxx03/__algorithm/for_each_segment.h
Normal file
@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FOR_EACH_SEGMENT_H
|
||||
#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly.
|
||||
// __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators.
|
||||
// Anything that is returned from __func is ignored.
|
||||
|
||||
template <class _SegmentedIterator, class _Functor>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) {
|
||||
using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
|
||||
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
|
||||
// We are in a single segment, so we might not be at the beginning or end
|
||||
if (__sfirst == __slast) {
|
||||
__func(_Traits::__local(__first), _Traits::__local(__last));
|
||||
return;
|
||||
}
|
||||
|
||||
// We have more than one segment. Iterate over the first segment, since we might not start at the beginning
|
||||
__func(_Traits::__local(__first), _Traits::__end(__sfirst));
|
||||
++__sfirst;
|
||||
// iterate over the segments which are guaranteed to be completely in the range
|
||||
while (__sfirst != __slast) {
|
||||
__func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst));
|
||||
++__sfirst;
|
||||
}
|
||||
// iterate over the last segment
|
||||
__func(_Traits::__begin(__sfirst), _Traits::__local(__last));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H
|
29
libcxx/include/__cxx03/__algorithm/generate.h
Normal file
29
libcxx/include/__cxx03/__algorithm/generate.h
Normal file
@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_GENERATE_H
|
||||
#define _LIBCPP___ALGORITHM_GENERATE_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Generator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
|
||||
for (; __first != __last; ++__first)
|
||||
*__first = __gen();
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_GENERATE_H
|
33
libcxx/include/__cxx03/__algorithm/generate_n.h
Normal file
33
libcxx/include/__cxx03/__algorithm/generate_n.h
Normal file
@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_GENERATE_N_H
|
||||
#define _LIBCPP___ALGORITHM_GENERATE_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/convert_to_integral.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _OutputIterator, class _Size, class _Generator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) {
|
||||
typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize;
|
||||
_IntegralSize __n = __orig_n;
|
||||
for (; __n > 0; ++__first, (void)--__n)
|
||||
*__first = __gen();
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_GENERATE_N_H
|
37
libcxx/include/__cxx03/__algorithm/half_positive.h
Normal file
37
libcxx/include/__cxx03/__algorithm/half_positive.h
Normal file
@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_HALF_POSITIVE_H
|
||||
#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H
|
||||
|
||||
#include <__config>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_integral.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Perform division by two quickly for positive integers (llvm.org/PR39129)
|
||||
|
||||
template <typename _Integral, __enable_if_t<is_integral<_Integral>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Integral __half_positive(_Integral __value) {
|
||||
return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2);
|
||||
}
|
||||
|
||||
template <typename _Tp, __enable_if_t<!is_integral<_Tp>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp __half_positive(_Tp __value) {
|
||||
return __value / 2;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H
|
54
libcxx/include/__cxx03/__algorithm/in_found_result.h
Normal file
54
libcxx/include/__cxx03/__algorithm/in_found_result.h
Normal file
@ -0,0 +1,54 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_FOUND_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1>
|
||||
struct in_found_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
bool found;
|
||||
|
||||
template <class _InIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const& {
|
||||
return {in, found};
|
||||
}
|
||||
|
||||
template <class _InIter2>
|
||||
requires convertible_to<_InIter1, _InIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() && {
|
||||
return {std::move(in), found};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H
|
54
libcxx/include/__cxx03/__algorithm/in_fun_result.h
Normal file
54
libcxx/include/__cxx03/__algorithm/in_fun_result.h
Normal file
@ -0,0 +1,54 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_FUN_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1, class _Func1>
|
||||
struct in_fun_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Func1 fun;
|
||||
|
||||
template <class _InIter2, class _Func2>
|
||||
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _Func1&, _Func2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const& {
|
||||
return {in, fun};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _Func2>
|
||||
requires convertible_to<_InIter1, _InIter2> && convertible_to<_Func1, _Func2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() && {
|
||||
return {std::move(in), std::move(fun)};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H
|
59
libcxx/include/__cxx03/__algorithm/in_in_out_result.h
Normal file
59
libcxx/include/__cxx03/__algorithm/in_in_out_result.h
Normal file
@ -0,0 +1,59 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_IN_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter1, class _InIter2, class _OutIter1>
|
||||
struct in_in_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
|
||||
|
||||
template <class _InIter3, class _InIter4, class _OutIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4> &&
|
||||
convertible_to<const _OutIter1&, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& {
|
||||
return {in1, in2, out};
|
||||
}
|
||||
|
||||
template <class _InIter3, class _InIter4, class _OutIter2>
|
||||
requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> &&
|
||||
convertible_to<_OutIter1, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && {
|
||||
return {std::move(in1), std::move(in2), std::move(out)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H
|
56
libcxx/include/__cxx03/__algorithm/in_in_result.h
Normal file
56
libcxx/include/__cxx03/__algorithm/in_in_result.h
Normal file
@ -0,0 +1,56 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_IN_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter1, class _InIter2>
|
||||
struct in_in_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter2 in2;
|
||||
|
||||
template <class _InIter3, class _InIter4>
|
||||
requires convertible_to<const _InIter1&, _InIter3> && convertible_to<const _InIter2&, _InIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() const& {
|
||||
return {in1, in2};
|
||||
}
|
||||
|
||||
template <class _InIter3, class _InIter4>
|
||||
requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() && {
|
||||
return {std::move(in1), std::move(in2)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H
|
57
libcxx/include/__cxx03/__algorithm/in_out_out_result.h
Normal file
57
libcxx/include/__cxx03/__algorithm/in_out_out_result.h
Normal file
@ -0,0 +1,57 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_OUT_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template <class _InIter1, class _OutIter1, class _OutIter2>
|
||||
struct in_out_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out1;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2;
|
||||
|
||||
template <class _InIter2, class _OutIter3, class _OutIter4>
|
||||
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter3> &&
|
||||
convertible_to<const _OutIter2&, _OutIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& {
|
||||
return {in, out1, out2};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _OutIter3, class _OutIter4>
|
||||
requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter3> &&
|
||||
convertible_to<_OutIter2, _OutIter4>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && {
|
||||
return {std::move(in), std::move(out1), std::move(out2)};
|
||||
}
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H
|
56
libcxx/include/__cxx03/__algorithm/in_out_result.h
Normal file
56
libcxx/include/__cxx03/__algorithm/in_out_result.h
Normal file
@ -0,0 +1,56 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IN_OUT_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter1, class _OutIter1>
|
||||
struct in_out_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out;
|
||||
|
||||
template <class _InIter2, class _OutIter2>
|
||||
requires convertible_to<const _InIter1&, _InIter2> && convertible_to<const _OutIter1&, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() const& {
|
||||
return {in, out};
|
||||
}
|
||||
|
||||
template <class _InIter2, class _OutIter2>
|
||||
requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() && {
|
||||
return {std::move(in), std::move(out)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H
|
79
libcxx/include/__cxx03/__algorithm/includes.h
Normal file
79
libcxx/include/__cxx03/__algorithm/includes.h
Normal file
@ -0,0 +1,79 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_INCLUDES_H
|
||||
#define _LIBCPP___ALGORITHM_INCLUDES_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Comp, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Comp&& __comp,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2) {
|
||||
for (; __first2 != __last2; ++__first1) {
|
||||
if (__first1 == __last1 ||
|
||||
std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1)))
|
||||
return false;
|
||||
if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
++__first2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
includes(_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_Compare __comp) {
|
||||
static_assert(
|
||||
__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, "Comparator has to be callable");
|
||||
|
||||
return std::__includes(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp),
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_INCLUDES_H
|
240
libcxx/include/__cxx03/__algorithm/inplace_merge.h
Normal file
240
libcxx/include/__cxx03/__algorithm/inplace_merge.h
Normal file
@ -0,0 +1,240 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_INPLACE_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/lower_bound.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/move.h>
|
||||
#include <__algorithm/rotate.h>
|
||||
#include <__algorithm/upper_bound.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
#include <__memory/destruct_n.h>
|
||||
#include <__memory/temporary_buffer.h>
|
||||
#include <__memory/unique_ptr.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <new>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Predicate>
|
||||
class __invert // invert the sense of a comparison
|
||||
{
|
||||
private:
|
||||
_Predicate __p_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI __invert() {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit __invert(_Predicate __p) : __p_(__p) {}
|
||||
|
||||
template <class _T1>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x) {
|
||||
return !__p_(__x);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x, const _T2& __y) {
|
||||
return __p_(__y, __x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy,
|
||||
class _Compare,
|
||||
class _InputIterator1,
|
||||
class _Sent1,
|
||||
class _InputIterator2,
|
||||
class _Sent2,
|
||||
class _OutputIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI void __half_inplace_merge(
|
||||
_InputIterator1 __first1,
|
||||
_Sent1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_Sent2 __last2,
|
||||
_OutputIterator __result,
|
||||
_Compare&& __comp) {
|
||||
for (; __first1 != __last1; ++__result) {
|
||||
if (__first2 == __last2) {
|
||||
std::__move<_AlgPolicy>(__first1, __last1, __result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (__comp(*__first2, *__first1)) {
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first2);
|
||||
++__first2;
|
||||
} else {
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first1);
|
||||
++__first1;
|
||||
}
|
||||
}
|
||||
// __first2 through __last2 are already in the right spot.
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI void __buffered_inplace_merge(
|
||||
_BidirectionalIterator __first,
|
||||
_BidirectionalIterator __middle,
|
||||
_BidirectionalIterator __last,
|
||||
_Compare&& __comp,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
|
||||
typename iterator_traits<_BidirectionalIterator>::value_type* __buff) {
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
|
||||
__destruct_n __d(0);
|
||||
unique_ptr<value_type, __destruct_n&> __h2(__buff, __d);
|
||||
if (__len1 <= __len2) {
|
||||
value_type* __p = __buff;
|
||||
for (_BidirectionalIterator __i = __first; __i != __middle;
|
||||
__d.template __incr<value_type>(), (void)++__i, (void)++__p)
|
||||
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
|
||||
std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp);
|
||||
} else {
|
||||
value_type* __p = __buff;
|
||||
for (_BidirectionalIterator __i = __middle; __i != __last;
|
||||
__d.template __incr<value_type>(), (void)++__i, (void)++__p)
|
||||
::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i));
|
||||
typedef reverse_iterator<_BidirectionalIterator> _RBi;
|
||||
typedef reverse_iterator<value_type*> _Rv;
|
||||
typedef __invert<_Compare> _Inverted;
|
||||
std::__half_inplace_merge<_AlgPolicy>(
|
||||
_Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp));
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator>
|
||||
void __inplace_merge(
|
||||
_BidirectionalIterator __first,
|
||||
_BidirectionalIterator __middle,
|
||||
_BidirectionalIterator __last,
|
||||
_Compare&& __comp,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len1,
|
||||
typename iterator_traits<_BidirectionalIterator>::difference_type __len2,
|
||||
typename iterator_traits<_BidirectionalIterator>::value_type* __buff,
|
||||
ptrdiff_t __buff_size) {
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
||||
while (true) {
|
||||
// if __middle == __last, we're done
|
||||
if (__len2 == 0)
|
||||
return;
|
||||
if (__len1 <= __buff_size || __len2 <= __buff_size)
|
||||
return std::__buffered_inplace_merge<_AlgPolicy>(__first, __middle, __last, __comp, __len1, __len2, __buff);
|
||||
// shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0
|
||||
for (; true; ++__first, (void)--__len1) {
|
||||
if (__len1 == 0)
|
||||
return;
|
||||
if (__comp(*__middle, *__first))
|
||||
break;
|
||||
}
|
||||
// __first < __middle < __last
|
||||
// *__first > *__middle
|
||||
// partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that
|
||||
// all elements in:
|
||||
// [__first, __m1) <= [__middle, __m2)
|
||||
// [__middle, __m2) < [__m1, __middle)
|
||||
// [__m1, __middle) <= [__m2, __last)
|
||||
// and __m1 or __m2 is in the middle of its range
|
||||
_BidirectionalIterator __m1; // "median" of [__first, __middle)
|
||||
_BidirectionalIterator __m2; // "median" of [__middle, __last)
|
||||
difference_type __len11; // distance(__first, __m1)
|
||||
difference_type __len21; // distance(__middle, __m2)
|
||||
// binary search smaller range
|
||||
if (__len1 < __len2) { // __len >= 1, __len2 >= 2
|
||||
__len21 = __len2 / 2;
|
||||
__m2 = __middle;
|
||||
_Ops::advance(__m2, __len21);
|
||||
__m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity());
|
||||
__len11 = _Ops::distance(__first, __m1);
|
||||
} else {
|
||||
if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1
|
||||
// It is known *__first > *__middle
|
||||
_Ops::iter_swap(__first, __middle);
|
||||
return;
|
||||
}
|
||||
// __len1 >= 2, __len2 >= 1
|
||||
__len11 = __len1 / 2;
|
||||
__m1 = __first;
|
||||
_Ops::advance(__m1, __len11);
|
||||
__m2 = std::lower_bound(__middle, __last, *__m1, __comp);
|
||||
__len21 = _Ops::distance(__middle, __m2);
|
||||
}
|
||||
difference_type __len12 = __len1 - __len11; // distance(__m1, __middle)
|
||||
difference_type __len22 = __len2 - __len21; // distance(__m2, __last)
|
||||
// [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last)
|
||||
// swap middle two partitions
|
||||
__middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first;
|
||||
// __len12 and __len21 now have swapped meanings
|
||||
// merge smaller range with recursive call and larger with tail recursion elimination
|
||||
if (__len11 + __len21 < __len12 + __len22) {
|
||||
std::__inplace_merge<_AlgPolicy>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size);
|
||||
__first = __middle;
|
||||
__middle = __m2;
|
||||
__len1 = __len12;
|
||||
__len2 = __len22;
|
||||
} else {
|
||||
std::__inplace_merge<_AlgPolicy>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size);
|
||||
__last = __middle;
|
||||
__middle = __m1;
|
||||
__len1 = __len11;
|
||||
__len2 = __len21;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator, class _Compare>
|
||||
_LIBCPP_HIDE_FROM_ABI void __inplace_merge(
|
||||
_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) {
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
|
||||
typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type;
|
||||
difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle);
|
||||
difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last);
|
||||
difference_type __buf_size = std::min(__len1, __len2);
|
||||
// TODO: Remove the use of std::get_temporary_buffer
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
|
||||
pair<value_type*, ptrdiff_t> __buf = std::get_temporary_buffer<value_type>(__buf_size);
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_POP
|
||||
unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first);
|
||||
return std::__inplace_merge<_AlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second);
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI void inplace_merge(
|
||||
_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare __comp) {
|
||||
std::__inplace_merge<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__middle), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI void
|
||||
inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) {
|
||||
std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H
|
38
libcxx/include/__cxx03/__algorithm/is_heap.h
Normal file
38
libcxx/include/__cxx03/__algorithm/is_heap.h
Normal file
@ -0,0 +1,38 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_IS_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_heap_until.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
return std::is_heap(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_HEAP_H
|
62
libcxx/include/__cxx03/__algorithm/is_heap_until.h
Normal file
62
libcxx/include/__cxx03/__algorithm/is_heap_until.h
Normal file
@ -0,0 +1,62 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_HEAP_UNTIL_H
|
||||
#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
difference_type __len = __last - __first;
|
||||
difference_type __p = 0;
|
||||
difference_type __c = 1;
|
||||
_RandomAccessIterator __pp = __first;
|
||||
while (__c < __len) {
|
||||
_RandomAccessIterator __cp = __first + __c;
|
||||
if (__comp(*__pp, *__cp))
|
||||
return __cp;
|
||||
++__c;
|
||||
++__cp;
|
||||
if (__c == __len)
|
||||
return __last;
|
||||
if (__comp(*__pp, *__cp))
|
||||
return __cp;
|
||||
++__p;
|
||||
++__pp;
|
||||
__c = 2 * __p + 1;
|
||||
}
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
return std::__is_heap_until(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H
|
37
libcxx/include/__cxx03/__algorithm/is_partitioned.h
Normal file
37
libcxx/include/__cxx03/__algorithm/is_partitioned.h
Normal file
@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_PARTITIONED_H
|
||||
#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
if (__first == __last)
|
||||
return true;
|
||||
++__first;
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H
|
308
libcxx/include/__cxx03/__algorithm/is_permutation.h
Normal file
308
libcxx/include/__cxx03/__algorithm/is_permutation.h
Normal file
@ -0,0 +1,308 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void>
|
||||
struct _ConstTimeDistance : false_type {};
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2>
|
||||
struct _ConstTimeDistance<_Iter1,
|
||||
_Sent1,
|
||||
_Iter2,
|
||||
_Sent2,
|
||||
__enable_if_t< sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2> >>
|
||||
: true_type {};
|
||||
|
||||
#else
|
||||
|
||||
template <class _Iter1, class _Iter2>
|
||||
struct _ConstTimeDistance<
|
||||
_Iter1,
|
||||
_Iter1,
|
||||
_Iter2,
|
||||
_Iter2,
|
||||
__enable_if_t< is_same<typename iterator_traits<_Iter1>::iterator_category, random_access_iterator_tag>::value &&
|
||||
is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value > >
|
||||
: true_type {};
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
// Internal functions
|
||||
|
||||
// For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2)
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred&& __pred,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2) {
|
||||
using _D1 = __iter_diff_t<_Iter1>;
|
||||
|
||||
for (auto __i = __first1; __i != __last1; ++__i) {
|
||||
// Have we already counted the number of *__i in [f1, l1)?
|
||||
auto __match = __first1;
|
||||
for (; __match != __i; ++__match) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__match), std::__invoke(__proj1, *__i)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (__match == __i) {
|
||||
// Count number of *__i in [f2, l2)
|
||||
_D1 __c2 = 0;
|
||||
for (auto __j = __first2; __j != __last2; ++__j) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj2, *__j)))
|
||||
++__c2;
|
||||
}
|
||||
if (__c2 == 0)
|
||||
return false;
|
||||
|
||||
// Count number of *__i in [__i, l1) (we can start with 1)
|
||||
_D1 __c1 = 1;
|
||||
for (auto __j = _IterOps<_AlgPolicy>::next(__i); __j != __last1; ++__j) {
|
||||
if (std::__invoke(__pred, std::__invoke(__proj1, *__i), std::__invoke(__proj1, *__j)))
|
||||
++__c1;
|
||||
}
|
||||
if (__c1 != __c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2+1 iterators, predicate. Not used by range algorithms.
|
||||
template <class _AlgPolicy, class _ForwardIterator1, class _Sentinel1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
|
||||
_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) {
|
||||
// Shorten sequences as much as possible by lopping of any equal prefix.
|
||||
for (; __first1 != __last1; ++__first1, (void)++__first2) {
|
||||
if (!__pred(*__first1, *__first2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (__first1 == __last1)
|
||||
return true;
|
||||
|
||||
// __first1 != __last1 && *__first1 != *__first2
|
||||
using _D1 = __iter_diff_t<_ForwardIterator1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
if (__l1 == _D1(1))
|
||||
return false;
|
||||
auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1);
|
||||
|
||||
return std::__is_permutation_impl<_AlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__pred,
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate, non-constant time `distance`.
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred&& __pred,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2,
|
||||
/*_ConstTimeDistance=*/false_type) {
|
||||
// Shorten sequences as much as possible by lopping of any equal prefix.
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
if (__first1 == __last1)
|
||||
return __first2 == __last2;
|
||||
if (__first2 == __last2) // Second range is shorter
|
||||
return false;
|
||||
|
||||
using _D1 = __iter_diff_t<_Iter1>;
|
||||
_D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1);
|
||||
|
||||
using _D2 = __iter_diff_t<_Iter2>;
|
||||
_D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2);
|
||||
if (__l1 != __l2)
|
||||
return false;
|
||||
|
||||
return std::__is_permutation_impl<_AlgPolicy>(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate, specialization for constant-time `distance` call.
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred&& __pred,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2,
|
||||
/*_ConstTimeDistance=*/true_type) {
|
||||
if (std::distance(__first1, __last1) != std::distance(__first2, __last2))
|
||||
return false;
|
||||
return std::__is_permutation<_AlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
/*_ConstTimeDistance=*/false_type());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate
|
||||
template <class _AlgPolicy,
|
||||
class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred&& __pred,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2) {
|
||||
return std::__is_permutation<_AlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
_ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>());
|
||||
}
|
||||
|
||||
// Public interface
|
||||
|
||||
// 2+1 iterators, predicate
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
|
||||
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) {
|
||||
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
|
||||
"The predicate has to be callable");
|
||||
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2), __pred);
|
||||
}
|
||||
|
||||
// 2+1 iterators
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
return std::is_permutation(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
|
||||
// 2+2 iterators
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
|
||||
_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__equal_to(),
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
// 2+2 iterators, predicate
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
|
||||
"The predicate has to be callable");
|
||||
|
||||
return std::__is_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__pred,
|
||||
__identity(),
|
||||
__identity());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 14
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H
|
38
libcxx/include/__cxx03/__algorithm/is_sorted.h
Normal file
38
libcxx/include/__cxx03/__algorithm/is_sorted.h
Normal file
@ -0,0 +1,38 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_SORTED_H
|
||||
#define _LIBCPP___ALGORITHM_IS_SORTED_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/is_sorted_until.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
is_sorted(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::is_sorted(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_SORTED_H
|
51
libcxx/include/__cxx03/__algorithm/is_sorted_until.h
Normal file
51
libcxx/include/__cxx03/__algorithm/is_sorted_until.h
Normal file
@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IS_SORTED_UNTIL_H
|
||||
#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
if (__first != __last) {
|
||||
_ForwardIterator __i = __first;
|
||||
while (++__i != __last) {
|
||||
if (__comp(*__i, *__first))
|
||||
return __i;
|
||||
__first = __i;
|
||||
}
|
||||
}
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::is_sorted_until(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H
|
31
libcxx/include/__cxx03/__algorithm/iter_swap.h
Normal file
31
libcxx/include/__cxx03/__algorithm/iter_swap.h
Normal file
@ -0,0 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ITER_SWAP_H
|
||||
#define _LIBCPP___ALGORITHM_ITER_SWAP_H
|
||||
|
||||
#include <__config>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/swap.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
|
||||
// _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b)))
|
||||
_NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) {
|
||||
swap(*__a, *__b);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H
|
223
libcxx/include/__cxx03/__algorithm/iterator_operations.h
Normal file
223
libcxx/include/__cxx03/__algorithm/iterator_operations.h
Normal file
@ -0,0 +1,223 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ITERATOR_OPERATIONS_H
|
||||
#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
|
||||
|
||||
#include <__algorithm/iter_swap.h>
|
||||
#include <__algorithm/ranges_iterator_concept.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iter_move.h>
|
||||
#include <__iterator/iter_swap.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/prev.h>
|
||||
#include <__iterator/readable_traits.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/is_reference.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct _IterOps;
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
struct _RangeAlgPolicy {};
|
||||
|
||||
template <>
|
||||
struct _IterOps<_RangeAlgPolicy> {
|
||||
template <class _Iter>
|
||||
using __value_type = iter_value_t<_Iter>;
|
||||
|
||||
template <class _Iter>
|
||||
using __iterator_category = ranges::__iterator_concept<_Iter>;
|
||||
|
||||
template <class _Iter>
|
||||
using __difference_type = iter_difference_t<_Iter>;
|
||||
|
||||
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;
|
||||
static constexpr auto prev = ranges::prev;
|
||||
static constexpr auto __advance_to = ranges::advance;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct _ClassicAlgPolicy {};
|
||||
|
||||
template <>
|
||||
struct _IterOps<_ClassicAlgPolicy> {
|
||||
template <class _Iter>
|
||||
using __value_type = typename iterator_traits<_Iter>::value_type;
|
||||
|
||||
template <class _Iter>
|
||||
using __iterator_category = typename iterator_traits<_Iter>::iterator_category;
|
||||
|
||||
template <class _Iter>
|
||||
using __difference_type = typename iterator_traits<_Iter>::difference_type;
|
||||
|
||||
// advance
|
||||
template <class _Iter, class _Distance>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void advance(_Iter& __iter, _Distance __count) {
|
||||
std::advance(__iter, __count);
|
||||
}
|
||||
|
||||
// distance
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static typename iterator_traits<_Iter>::difference_type
|
||||
distance(_Iter __first, _Iter __last) {
|
||||
return std::distance(__first, __last);
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
using __deref_t = decltype(*std::declval<_Iter&>());
|
||||
|
||||
template <class _Iter>
|
||||
using __move_t = decltype(std::move(*std::declval<_Iter&>()));
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void __validate_iter_reference() {
|
||||
static_assert(
|
||||
is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value,
|
||||
"It looks like your iterator's `iterator_traits<It>::reference` does not match the return type of "
|
||||
"dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] "
|
||||
"and can lead to dangling reference issues at runtime, so we are flagging this.");
|
||||
}
|
||||
|
||||
// iter_move
|
||||
template <class _Iter, __enable_if_t<is_reference<__deref_t<_Iter> >::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
|
||||
// If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it.
|
||||
// Note that the C++03 mode doesn't support `decltype(auto)` as the return type.
|
||||
__move_t<_Iter>
|
||||
__iter_move(_Iter&& __i) {
|
||||
__validate_iter_reference<_Iter>();
|
||||
|
||||
return std::move(*std::forward<_Iter>(__i));
|
||||
}
|
||||
|
||||
template <class _Iter, __enable_if_t<!is_reference<__deref_t<_Iter> >::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static
|
||||
// If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a
|
||||
// value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to
|
||||
// that temporary. Note that the C++03 mode doesn't support `auto` as the return type.
|
||||
__deref_t<_Iter>
|
||||
__iter_move(_Iter&& __i) {
|
||||
__validate_iter_reference<_Iter>();
|
||||
|
||||
return *std::forward<_Iter>(__i);
|
||||
}
|
||||
|
||||
// iter_swap
|
||||
template <class _Iter1, class _Iter2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 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_SINCE_CXX14 _Iterator next(_Iterator, _Iterator __last) {
|
||||
return __last;
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter>
|
||||
next(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
|
||||
return std::next(std::forward<_Iter>(__it), __n);
|
||||
}
|
||||
|
||||
// prev
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter>
|
||||
prev(_Iter&& __iter, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) {
|
||||
return std::prev(std::forward<_Iter>(__iter), __n);
|
||||
}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 void __advance_to(_Iter& __first, _Iter __last) {
|
||||
__first = __last;
|
||||
}
|
||||
|
||||
// advance with sentinel, a la std::ranges::advance
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_Iter>
|
||||
__advance_to(_Iter& __iter, __difference_type<_Iter> __count, const _Iter& __sentinel) {
|
||||
return _IterOps::__advance_to(__iter, __count, __sentinel, typename iterator_traits<_Iter>::iterator_category());
|
||||
}
|
||||
|
||||
private:
|
||||
// advance with sentinel, a la std::ranges::advance -- InputIterator specialization
|
||||
template <class _InputIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_InputIter> __advance_to(
|
||||
_InputIter& __iter, __difference_type<_InputIter> __count, const _InputIter& __sentinel, input_iterator_tag) {
|
||||
__difference_type<_InputIter> __dist = 0;
|
||||
for (; __dist < __count && __iter != __sentinel; ++__dist)
|
||||
++__iter;
|
||||
return __count - __dist;
|
||||
}
|
||||
|
||||
// advance with sentinel, a la std::ranges::advance -- BidirectionalIterator specialization
|
||||
template <class _BiDirIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_BiDirIter>
|
||||
__advance_to(_BiDirIter& __iter,
|
||||
__difference_type<_BiDirIter> __count,
|
||||
const _BiDirIter& __sentinel,
|
||||
bidirectional_iterator_tag) {
|
||||
__difference_type<_BiDirIter> __dist = 0;
|
||||
if (__count >= 0)
|
||||
for (; __dist < __count && __iter != __sentinel; ++__dist)
|
||||
++__iter;
|
||||
else
|
||||
for (__count = -__count; __dist < __count && __iter != __sentinel; ++__dist)
|
||||
--__iter;
|
||||
return __count - __dist;
|
||||
}
|
||||
|
||||
// advance with sentinel, a la std::ranges::advance -- RandomIterator specialization
|
||||
template <class _RandIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_RandIter>
|
||||
__advance_to(_RandIter& __iter,
|
||||
__difference_type<_RandIter> __count,
|
||||
const _RandIter& __sentinel,
|
||||
random_access_iterator_tag) {
|
||||
auto __dist = _IterOps::distance(__iter, __sentinel);
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(
|
||||
__count == 0 || (__dist < 0) == (__count < 0), "__sentinel must precede __iter when __count < 0");
|
||||
if (__count < 0)
|
||||
__dist = __dist > __count ? __dist : __count;
|
||||
else
|
||||
__dist = __dist < __count ? __dist : __count;
|
||||
__iter += __dist;
|
||||
return __count - __dist;
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H
|
57
libcxx/include/__cxx03/__algorithm/lexicographical_compare.h
Normal file
57
libcxx/include/__cxx03/__algorithm/lexicographical_compare.h
Normal file
@ -0,0 +1,57 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_LEXICOGRAPHICAL_COMPARE_H
|
||||
#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(
|
||||
_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_Compare __comp) {
|
||||
for (; __first2 != __last2; ++__first1, (void)++__first2) {
|
||||
if (__first1 == __last1 || __comp(*__first1, *__first2))
|
||||
return true;
|
||||
if (__comp(*__first2, *__first1))
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(
|
||||
_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_Compare __comp) {
|
||||
return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H
|
@ -0,0 +1,125 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
||||
#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
||||
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/three_way_comp_ref_type.h>
|
||||
#include <__compare/compare_three_way.h>
|
||||
#include <__compare/ordering.h>
|
||||
#include <__concepts/arithmetic.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
// Fast path for random access iterators which computes the number of loop iterations up-front and
|
||||
// then skips the iterator comparisons inside the loop.
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
static_assert(
|
||||
signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior.");
|
||||
static_assert(
|
||||
signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior.");
|
||||
|
||||
using _Len1 = __iter_diff_t<_InputIterator1>;
|
||||
using _Len2 = __iter_diff_t<_InputIterator2>;
|
||||
using _Common = common_type_t<_Len1, _Len2>;
|
||||
|
||||
_Len1 __len1 = __last1 - __first1;
|
||||
_Len2 __len2 = __last2 - __first2;
|
||||
_Common __min_len = std::min<_Common>(__len1, __len2);
|
||||
|
||||
for (_Common __i = 0; __i < __min_len; ++__i) {
|
||||
auto __c = __comp(*__first1, *__first2);
|
||||
if (__c != 0) {
|
||||
return __c;
|
||||
}
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
|
||||
return __len1 <=> __len2;
|
||||
}
|
||||
|
||||
// Unoptimized implementation which compares the iterators against the end in every loop iteration
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
while (true) {
|
||||
bool __exhausted1 = __first1 == __last1;
|
||||
bool __exhausted2 = __first2 == __last2;
|
||||
|
||||
if (__exhausted1 || __exhausted2) {
|
||||
if (!__exhausted1)
|
||||
return strong_ordering::greater;
|
||||
if (!__exhausted2)
|
||||
return strong_ordering::less;
|
||||
return strong_ordering::equal;
|
||||
}
|
||||
|
||||
auto __c = __comp(*__first1, *__first2);
|
||||
if (__c != 0) {
|
||||
return __c;
|
||||
}
|
||||
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _Cmp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp)
|
||||
-> decltype(__comp(*__first1, *__first2)) {
|
||||
static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>,
|
||||
"The comparator passed to lexicographical_compare_three_way must return a comparison category type.");
|
||||
static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible.");
|
||||
__three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp);
|
||||
if constexpr (__has_random_access_iterator_category<_InputIterator1>::value &&
|
||||
__has_random_access_iterator_category<_InputIterator2>::value) {
|
||||
return std::__lexicographical_compare_three_way_fast_path(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
|
||||
} else {
|
||||
// Unoptimized implementation which compares the iterators against the end in every loop iteration
|
||||
return std::__lexicographical_compare_three_way_slow_path(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way(
|
||||
_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::lexicographical_compare_three_way(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H
|
109
libcxx/include/__cxx03/__algorithm/lower_bound.h
Normal file
109
libcxx/include/__cxx03/__algorithm/lower_bound.h
Normal file
@ -0,0 +1,109 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_LOWER_BOUND_H
|
||||
#define _LIBCPP___ALGORITHM_LOWER_BOUND_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__type_traits/remove_reference.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Iter, class _Type, class _Proj, class _Comp>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter __lower_bound_bisecting(
|
||||
_Iter __first,
|
||||
const _Type& __value,
|
||||
typename iterator_traits<_Iter>::difference_type __len,
|
||||
_Comp& __comp,
|
||||
_Proj& __proj) {
|
||||
while (__len != 0) {
|
||||
auto __l2 = std::__half_positive(__len);
|
||||
_Iter __m = __first;
|
||||
_IterOps<_AlgPolicy>::advance(__m, __l2);
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__m), __value)) {
|
||||
__first = ++__m;
|
||||
__len -= __l2 + 1;
|
||||
} else {
|
||||
__len = __l2;
|
||||
}
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
// One-sided binary search, aka meta binary search, has been in the public domain for decades, and has the general
|
||||
// advantage of being \Omega(1) rather than the classic algorithm's \Omega(log(n)), with the downside of executing at
|
||||
// most 2*log(n) comparisons vs the classic algorithm's exact log(n). There are two scenarios in which it really shines:
|
||||
// the first one is when operating over non-random-access iterators, because the classic algorithm requires knowing the
|
||||
// container's size upfront, which adds \Omega(n) iterator increments to the complexity. The second one is when you're
|
||||
// traversing the container in order, trying to fast-forward to the next value: in that case, the classic algorithm
|
||||
// would yield \Omega(n*log(n)) comparisons and, for non-random-access iterators, \Omega(n^2) iterator increments,
|
||||
// whereas the one-sided version will yield O(n) operations on both counts, with a \Omega(log(n)) bound on the number of
|
||||
// comparisons.
|
||||
template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Proj, class _Comp>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
|
||||
// step = 0, ensuring we can always short-circuit when distance is 1 later on
|
||||
if (__first == __last || !std::__invoke(__comp, std::__invoke(__proj, *__first), __value))
|
||||
return __first;
|
||||
|
||||
using _Distance = typename iterator_traits<_ForwardIterator>::difference_type;
|
||||
for (_Distance __step = 1; __first != __last; __step <<= 1) {
|
||||
auto __it = __first;
|
||||
auto __dist = __step - _IterOps<_AlgPolicy>::__advance_to(__it, __step, __last);
|
||||
// once we reach the last range where needle can be we must start
|
||||
// looking inwards, bisecting that range
|
||||
if (__it == __last || !std::__invoke(__comp, std::__invoke(__proj, *__it), __value)) {
|
||||
// we've already checked the previous value and it was less, we can save
|
||||
// one comparison by skipping bisection
|
||||
if (__dist == 1)
|
||||
return __it;
|
||||
return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj);
|
||||
}
|
||||
// range not found, move forward!
|
||||
__first = __it;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Proj, class _Comp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
__lower_bound(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
|
||||
const auto __dist = _IterOps<_AlgPolicy>::distance(__first, __last);
|
||||
return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable");
|
||||
auto __proj = std::__identity();
|
||||
return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
return std::lower_bound(__first, __last, __value, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H
|
60
libcxx/include/__cxx03/__algorithm/make_heap.h
Normal file
60
libcxx/include/__cxx03/__algorithm/make_heap.h
Normal file
@ -0,0 +1,60 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MAKE_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_MAKE_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
|
||||
__comp_ref_type<_Compare> __comp_ref = __comp;
|
||||
|
||||
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
|
||||
difference_type __n = __last - __first;
|
||||
if (__n > 1) {
|
||||
// start from the first parent, there is no need to consider children
|
||||
for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::make_heap(std::move(__first), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H
|
106
libcxx/include/__cxx03/__algorithm/make_projected.h
Normal file
106
libcxx/include/__cxx03/__algorithm/make_projected.h
Normal file
@ -0,0 +1,106 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MAKE_PROJECTED_H
|
||||
#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
|
||||
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/enable_if.h>
|
||||
#include <__type_traits/integral_constant.h>
|
||||
#include <__type_traits/is_member_pointer.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Pred, class _Proj>
|
||||
struct _ProjectedPred {
|
||||
_Pred& __pred; // Can be a unary or a binary predicate.
|
||||
_Proj& __proj;
|
||||
|
||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
|
||||
: __pred(__pred_arg), __proj(__proj_arg) {}
|
||||
|
||||
template <class _Tp>
|
||||
typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))>::type
|
||||
_LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
|
||||
operator()(_Tp&& __v) const {
|
||||
return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
typename __invoke_of<_Pred&,
|
||||
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
|
||||
decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))>::type _LIBCPP_CONSTEXPR
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
operator()(_T1&& __lhs, _T2&& __rhs) const {
|
||||
return std::__invoke(
|
||||
__pred, std::__invoke(__proj, std::forward<_T1>(__lhs)), std::__invoke(__proj, std::forward<_T2>(__rhs)));
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
class _Pred,
|
||||
class _Proj,
|
||||
__enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value && __is_identity<__decay_t<_Proj> >::value), int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred& __pred, _Proj& __proj) {
|
||||
return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
|
||||
}
|
||||
|
||||
// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
|
||||
// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
|
||||
// the call stack when the comparator is invoked, even in an unoptimized build.
|
||||
template <
|
||||
class _Pred,
|
||||
class _Proj,
|
||||
__enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value && __is_identity<__decay_t<_Proj> >::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) {
|
||||
return __pred;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Comp, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
|
||||
!is_member_pointer_v<decay_t<_Comp>>) {
|
||||
// Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
|
||||
// optimizations that rely on the type of the comparator.
|
||||
return __comp;
|
||||
|
||||
} else {
|
||||
return [&](auto&& __lhs, auto&& __rhs) -> bool {
|
||||
return std::invoke(__comp,
|
||||
std::invoke(__proj1, std::forward<decltype(__lhs)>(__lhs)),
|
||||
std::invoke(__proj2, std::forward<decltype(__rhs)>(__rhs)));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H
|
58
libcxx/include/__cxx03/__algorithm/max.h
Normal file
58
libcxx/include/__cxx03/__algorithm/max.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MAX_H
|
||||
#define _LIBCPP___ALGORITHM_MAX_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/max_element.h>
|
||||
#include <__config>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
|
||||
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
|
||||
return __comp(__a, __b) ? __b : __a;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
|
||||
max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
|
||||
return std::max(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp
|
||||
max(initializer_list<_Tp> __t, _Compare __comp) {
|
||||
return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) {
|
||||
return *std::max_element(__t.begin(), __t.end(), __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAX_H
|
51
libcxx/include/__cxx03/__algorithm/max_element.h
Normal file
51
libcxx/include/__cxx03/__algorithm/max_element.h
Normal file
@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MAX_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _ForwardIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
static_assert(
|
||||
__has_forward_iterator_category<_ForwardIterator>::value, "std::max_element requires a ForwardIterator");
|
||||
if (__first != __last) {
|
||||
_ForwardIterator __i = __first;
|
||||
while (++__i != __last)
|
||||
if (__comp(*__first, *__i))
|
||||
__first = __i;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
max_element(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::max_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H
|
69
libcxx/include/__cxx03/__algorithm/merge.h
Normal file
69
libcxx/include/__cxx03/__algorithm/merge.h
Normal file
@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MERGE_H
|
||||
#define _LIBCPP___ALGORITHM_MERGE_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _InputIterator1, class _InputIterator2, class _OutputIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __merge(
|
||||
_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_OutputIterator __result,
|
||||
_Compare __comp) {
|
||||
for (; __first1 != __last1; ++__result) {
|
||||
if (__first2 == __last2)
|
||||
return std::copy(__first1, __last1, __result);
|
||||
if (__comp(*__first2, *__first1)) {
|
||||
*__result = *__first2;
|
||||
++__first2;
|
||||
} else {
|
||||
*__result = *__first1;
|
||||
++__first1;
|
||||
}
|
||||
}
|
||||
return std::copy(__first2, __last2, __result);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _OutputIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
merge(_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_OutputIterator __result,
|
||||
_Compare __comp) {
|
||||
return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _OutputIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
merge(_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_OutputIterator __result) {
|
||||
return std::merge(__first1, __last1, __first2, __last2, __result, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MERGE_H
|
58
libcxx/include/__cxx03/__algorithm/min.h
Normal file
58
libcxx/include/__cxx03/__algorithm/min.h
Normal file
@ -0,0 +1,58 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MIN_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/min_element.h>
|
||||
#include <__config>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
|
||||
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
|
||||
return __comp(__b, __a) ? __b : __a;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&
|
||||
min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
|
||||
return std::min(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp
|
||||
min(initializer_list<_Tp> __t, _Compare __comp) {
|
||||
return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) {
|
||||
return *std::min_element(__t.begin(), __t.end(), __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_H
|
71
libcxx/include/__cxx03/__algorithm/min_element.h
Normal file
71
libcxx/include/__cxx03/__algorithm/min_element.h
Normal file
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MIN_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Comp, class _Iter, class _Sent, class _Proj>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
|
||||
__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
|
||||
if (__first == __last)
|
||||
return __first;
|
||||
|
||||
_Iter __i = __first;
|
||||
while (++__i != __last)
|
||||
if (std::__invoke(__comp, std::__invoke(__proj, *__i), std::__invoke(__proj, *__first)))
|
||||
__first = __i;
|
||||
|
||||
return __first;
|
||||
}
|
||||
|
||||
template <class _Comp, class _Iter, class _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) {
|
||||
auto __proj = __identity();
|
||||
return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
static_assert(
|
||||
__has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator");
|
||||
static_assert(
|
||||
__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable");
|
||||
|
||||
return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
|
||||
min_element(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::min_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H
|
56
libcxx/include/__cxx03/__algorithm/min_max_result.h
Normal file
56
libcxx/include/__cxx03/__algorithm/min_max_result.h
Normal file
@ -0,0 +1,56 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MIN_MAX_RESULT_H
|
||||
#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
|
||||
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__config>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _T1>
|
||||
struct min_max_result {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _T1 min;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _T1 max;
|
||||
|
||||
template <class _T2>
|
||||
requires convertible_to<const _T1&, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const& {
|
||||
return {min, max};
|
||||
}
|
||||
|
||||
template <class _T2>
|
||||
requires convertible_to<_T1, _T2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() && {
|
||||
return {std::move(min), std::move(max)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H
|
59
libcxx/include/__cxx03/__algorithm/minmax.h
Normal file
59
libcxx/include/__cxx03/__algorithm/minmax.h
Normal file
@ -0,0 +1,59 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MINMAX_H
|
||||
#define _LIBCPP___ALGORITHM_MINMAX_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/minmax_element.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <initializer_list>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&>
|
||||
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) {
|
||||
return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : pair<const _Tp&, const _Tp&>(__a, __b);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<const _Tp&, const _Tp&>
|
||||
minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) {
|
||||
return std::minmax(__a, __b, __less<>());
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
||||
template <class _Tp, class _Compare>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp>
|
||||
minmax(initializer_list<_Tp> __t, _Compare __comp) {
|
||||
static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable");
|
||||
__identity __proj;
|
||||
auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj);
|
||||
return pair<_Tp, _Tp>(*__ret.first, *__ret.second);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp>
|
||||
minmax(initializer_list<_Tp> __t) {
|
||||
return std::minmax(__t, __less<>());
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_CXX03_LANG
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MINMAX_H
|
100
libcxx/include/__cxx03/__algorithm/minmax_element.h
Normal file
100
libcxx/include/__cxx03/__algorithm/minmax_element.h
Normal file
@ -0,0 +1,100 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MINMAX_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Comp, class _Proj>
|
||||
class _MinmaxElementLessFunc {
|
||||
_Comp& __comp_;
|
||||
_Proj& __proj_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj)
|
||||
: __comp_(__comp), __proj_(__proj) {}
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(_Iter& __it1, _Iter& __it2) {
|
||||
return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2));
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Iter, class _Sent, class _Proj, class _Comp>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
|
||||
__minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
|
||||
auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj);
|
||||
|
||||
pair<_Iter, _Iter> __result(__first, __first);
|
||||
if (__first == __last || ++__first == __last)
|
||||
return __result;
|
||||
|
||||
if (__less(__first, __result.first))
|
||||
__result.first = __first;
|
||||
else
|
||||
__result.second = __first;
|
||||
|
||||
while (++__first != __last) {
|
||||
_Iter __i = __first;
|
||||
if (++__first == __last) {
|
||||
if (__less(__i, __result.first))
|
||||
__result.first = __i;
|
||||
else if (!__less(__i, __result.second))
|
||||
__result.second = __i;
|
||||
return __result;
|
||||
}
|
||||
|
||||
if (__less(__first, __i)) {
|
||||
if (__less(__first, __result.first))
|
||||
__result.first = __first;
|
||||
if (!__less(__i, __result.second))
|
||||
__result.second = __i;
|
||||
} else {
|
||||
if (__less(__i, __result.first))
|
||||
__result.first = __i;
|
||||
if (!__less(__first, __result.second))
|
||||
__result.second = __first;
|
||||
}
|
||||
}
|
||||
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Compare>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator>
|
||||
minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) {
|
||||
static_assert(
|
||||
__has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator");
|
||||
static_assert(
|
||||
__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable");
|
||||
auto __proj = __identity();
|
||||
return std::__minmax_element_impl(__first, __last, __comp, __proj);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator>
|
||||
minmax_element(_ForwardIterator __first, _ForwardIterator __last) {
|
||||
return std::minmax_element(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H
|
217
libcxx/include/__cxx03/__algorithm/mismatch.h
Normal file
217
libcxx/include/__cxx03/__algorithm/mismatch.h
Normal file
@ -0,0 +1,217 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MISMATCH_H
|
||||
#define _LIBCPP___ALGORITHM_MISMATCH_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__algorithm/simd_utils.h>
|
||||
#include <__algorithm/unwrap_iter.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/aliasing_iterator.h>
|
||||
#include <__type_traits/desugars_to.h>
|
||||
#include <__type_traits/invoke.h>
|
||||
#include <__type_traits/is_constant_evaluated.h>
|
||||
#include <__type_traits/is_equality_comparable.h>
|
||||
#include <__type_traits/is_integral.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <__utility/unreachable.h>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2>
|
||||
__mismatch_loop(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
while (__first1 != __last1) {
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
return std::make_pair(std::move(__first1), std::move(__first2));
|
||||
}
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2>
|
||||
__mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
#if _LIBCPP_VECTORIZE_ALGORITHMS
|
||||
|
||||
template <class _Iter>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
|
||||
__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
|
||||
using __value_type = __iter_value_type<_Iter>;
|
||||
constexpr size_t __unroll_count = 4;
|
||||
constexpr size_t __vec_size = __native_vector_size<__value_type>;
|
||||
using __vec = __simd_vector<__value_type, __vec_size>;
|
||||
|
||||
if (!__libcpp_is_constant_evaluated()) {
|
||||
auto __orig_first1 = __first1;
|
||||
auto __last2 = __first2 + (__last1 - __first1);
|
||||
while (static_cast<size_t>(__last1 - __first1) >= __unroll_count * __vec_size) [[__unlikely__]] {
|
||||
__vec __lhs[__unroll_count];
|
||||
__vec __rhs[__unroll_count];
|
||||
|
||||
for (size_t __i = 0; __i != __unroll_count; ++__i) {
|
||||
__lhs[__i] = std::__load_vector<__vec>(__first1 + __i * __vec_size);
|
||||
__rhs[__i] = std::__load_vector<__vec>(__first2 + __i * __vec_size);
|
||||
}
|
||||
|
||||
for (size_t __i = 0; __i != __unroll_count; ++__i) {
|
||||
if (auto __cmp_res = __lhs[__i] == __rhs[__i]; !std::__all_of(__cmp_res)) {
|
||||
auto __offset = __i * __vec_size + std::__find_first_not_set(__cmp_res);
|
||||
return {__first1 + __offset, __first2 + __offset};
|
||||
}
|
||||
}
|
||||
|
||||
__first1 += __unroll_count * __vec_size;
|
||||
__first2 += __unroll_count * __vec_size;
|
||||
}
|
||||
|
||||
// check the remaining 0-3 vectors
|
||||
while (static_cast<size_t>(__last1 - __first1) >= __vec_size) {
|
||||
if (auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2);
|
||||
!std::__all_of(__cmp_res)) {
|
||||
auto __offset = std::__find_first_not_set(__cmp_res);
|
||||
return {__first1 + __offset, __first2 + __offset};
|
||||
}
|
||||
__first1 += __vec_size;
|
||||
__first2 += __vec_size;
|
||||
}
|
||||
|
||||
if (__last1 - __first1 == 0)
|
||||
return {__first1, __first2};
|
||||
|
||||
// Check if we can load elements in front of the current pointer. If that's the case load a vector at
|
||||
// (last - vector_size) to check the remaining elements
|
||||
if (static_cast<size_t>(__first1 - __orig_first1) >= __vec_size) {
|
||||
__first1 = __last1 - __vec_size;
|
||||
__first2 = __last2 - __vec_size;
|
||||
auto __offset =
|
||||
std::__find_first_not_set(std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2));
|
||||
return {__first1 + __offset, __first2 + __offset};
|
||||
} // else loop over the elements individually
|
||||
}
|
||||
|
||||
__equal_to __pred;
|
||||
__identity __proj;
|
||||
return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj, __proj);
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
__enable_if_t<is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
|
||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
||||
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred&, _Proj1&, _Proj2&) {
|
||||
return std::__mismatch_vectorized(__first1, __last1, __first2);
|
||||
}
|
||||
|
||||
template <class _Tp,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
__enable_if_t<!is_integral<_Tp>::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> &&
|
||||
__is_identity<_Proj1>::value && __is_identity<_Proj2>::value &&
|
||||
__can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
||||
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
if (__libcpp_is_constant_evaluated()) {
|
||||
return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2);
|
||||
} else {
|
||||
using _Iter = __aliasing_iterator<_Tp*, __get_as_integer_type_t<_Tp>>;
|
||||
auto __ret = std::__mismatch_vectorized(_Iter(__first1), _Iter(__last1), _Iter(__first2));
|
||||
return {__ret.first.__base(), __ret.second.__base()};
|
||||
}
|
||||
}
|
||||
#endif // _LIBCPP_VECTORIZE_ALGORITHMS
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) {
|
||||
__identity __proj;
|
||||
auto __res = std::__mismatch(
|
||||
std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred, __proj, __proj);
|
||||
return std::make_pair(std::__rewrap_iter(__first1, __res.first), std::__rewrap_iter(__first2, __res.second));
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) {
|
||||
return std::mismatch(__first1, __last1, __first2, __equal_to());
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch(
|
||||
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
while (__first1 != __last1 && __first2 != __last2) {
|
||||
if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
|
||||
break;
|
||||
++__first1;
|
||||
++__first2;
|
||||
}
|
||||
return {std::move(__first1), std::move(__first2)};
|
||||
}
|
||||
|
||||
template <class _Tp, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
|
||||
__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
|
||||
auto __len = std::min(__last1 - __first1, __last2 - __first2);
|
||||
return std::__mismatch(__first1, __first1 + __len, __first2, __pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1,
|
||||
_InputIterator1 __last1,
|
||||
_InputIterator2 __first2,
|
||||
_InputIterator2 __last2,
|
||||
_BinaryPredicate __pred) {
|
||||
__identity __proj;
|
||||
auto __res = std::__mismatch(
|
||||
std::__unwrap_iter(__first1),
|
||||
std::__unwrap_iter(__last1),
|
||||
std::__unwrap_iter(__first2),
|
||||
std::__unwrap_iter(__last2),
|
||||
__pred,
|
||||
__proj,
|
||||
__proj);
|
||||
return {std::__rewrap_iter(__first1, __res.first), std::__rewrap_iter(__first2, __res.second)};
|
||||
}
|
||||
|
||||
template <class _InputIterator1, class _InputIterator2>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2>
|
||||
mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) {
|
||||
return std::mismatch(__first1, __last1, __first2, __last2, __equal_to());
|
||||
}
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MISMATCH_H
|
127
libcxx/include/__cxx03/__algorithm/move.h
Normal file
127
libcxx/include/__cxx03/__algorithm/move.h
Normal file
@ -0,0 +1,127 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MOVE_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/for_each_segment.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __move_impl {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
while (__first != __last) {
|
||||
*__result = _IterOps<_AlgPolicy>::__iter_move(__first);
|
||||
++__first;
|
||||
++__result;
|
||||
}
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
struct _MoveSegment {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
|
||||
_OutIter& __result_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _MoveSegment(_OutIter& __result)
|
||||
: __result_(__result) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) {
|
||||
__result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result));
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__result));
|
||||
|
||||
auto __local_first = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_last = _Traits::__end(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iters = std::__move<_AlgPolicy>(__first, __first + __size, __local_first);
|
||||
__first = std::move(__iters.first);
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), _Traits::__compose(__segment_iterator, std::move(__iters.second)));
|
||||
|
||||
__local_first = _Traits::__begin(++__segment_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out, __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
__move(_InIter __first, _Sent __last, _OutIter __result) {
|
||||
return std::__copy_move_unwrap_iters<__move_impl<_AlgPolicy> >(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
|
||||
move(_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
|
||||
static_assert(is_copy_constructible<_InputIterator>::value, "Iterators has to be copy constructible.");
|
||||
static_assert(is_copy_constructible<_OutputIterator>::value, "The output iterator has to be copy constructible.");
|
||||
|
||||
return std::__move<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MOVE_H
|
137
libcxx/include/__cxx03/__algorithm/move_backward.h
Normal file
137
libcxx/include/__cxx03/__algorithm/move_backward.h
Normal file
@ -0,0 +1,137 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_MOVE_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
||||
|
||||
#include <__algorithm/copy_move_common.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/min.h>
|
||||
#include <__config>
|
||||
#include <__iterator/segmented_iterator.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result);
|
||||
|
||||
template <class _AlgPolicy>
|
||||
struct __move_backward_impl {
|
||||
template <class _InIter, class _Sent, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
auto __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
auto __original_last_iter = __last_iter;
|
||||
|
||||
while (__first != __last_iter) {
|
||||
*--__result = _IterOps<_AlgPolicy>::__iter_move(--__last_iter);
|
||||
}
|
||||
|
||||
return std::make_pair(std::move(__original_last_iter), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_InIter>;
|
||||
auto __sfirst = _Traits::__segment(__first);
|
||||
auto __slast = _Traits::__segment(__last);
|
||||
if (__sfirst == __slast) {
|
||||
auto __iters =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result));
|
||||
return std::make_pair(__last, __iters.second);
|
||||
}
|
||||
|
||||
__result =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__local(__last), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
while (__sfirst != __slast) {
|
||||
__result =
|
||||
std::__move_backward<_AlgPolicy>(_Traits::__begin(__slast), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
--__slast;
|
||||
}
|
||||
__result = std::__move_backward<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__slast), std::move(__result))
|
||||
.second;
|
||||
return std::make_pair(__last, std::move(__result));
|
||||
}
|
||||
|
||||
template <class _InIter,
|
||||
class _OutIter,
|
||||
__enable_if_t<__has_random_access_iterator_category<_InIter>::value &&
|
||||
!__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value,
|
||||
int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _InIter __last, _OutIter __result) const {
|
||||
using _Traits = __segmented_iterator_traits<_OutIter>;
|
||||
using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type;
|
||||
|
||||
// When the range contains no elements, __result might not be a valid iterator
|
||||
if (__first == __last)
|
||||
return std::make_pair(__first, __result);
|
||||
|
||||
auto __orig_last = __last;
|
||||
|
||||
auto __local_last = _Traits::__local(__result);
|
||||
auto __segment_iterator = _Traits::__segment(__result);
|
||||
while (true) {
|
||||
auto __local_first = _Traits::__begin(__segment_iterator);
|
||||
auto __size = std::min<_DiffT>(__local_last - __local_first, __last - __first);
|
||||
auto __iter = std::__move_backward<_AlgPolicy>(__last - __size, __last, __local_last).second;
|
||||
__last -= __size;
|
||||
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__orig_last), _Traits::__compose(__segment_iterator, std::move(__iter)));
|
||||
|
||||
__local_last = _Traits::__end(--__segment_iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
|
||||
template <class _In, class _Out, __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
|
||||
operator()(_In* __first, _In* __last, _Out* __result) const {
|
||||
return std::__copy_backward_trivial_impl(__first, __last, __result);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, class _BidirectionalIterator2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
|
||||
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
|
||||
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
|
||||
std::is_copy_constructible<_BidirectionalIterator1>::value,
|
||||
"Iterators must be copy constructible.");
|
||||
|
||||
return std::__copy_move_unwrap_iters<__move_backward_impl<_AlgPolicy> >(
|
||||
std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator1, class _BidirectionalIterator2>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2
|
||||
move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) {
|
||||
return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H
|
75
libcxx/include/__cxx03/__algorithm/next_permutation.h
Normal file
75
libcxx/include/__cxx03/__algorithm/next_permutation.h
Normal file
@ -0,0 +1,75 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_NEXT_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/reverse.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
|
||||
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true) {
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*--__i, *__ip1)) {
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*__i, *--__j))
|
||||
;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first) {
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
|
||||
return std::__next_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
|
||||
.second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
|
||||
return std::next_permutation(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H
|
32
libcxx/include/__cxx03/__algorithm/none_of.h
Normal file
32
libcxx/include/__cxx03/__algorithm/none_of.h
Normal file
@ -0,0 +1,32 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_NONE_OF_H
|
||||
#define _LIBCPP___ALGORITHM_NONE_OF_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _Predicate>
|
||||
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) {
|
||||
for (; __first != __last; ++__first)
|
||||
if (__pred(*__first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NONE_OF_H
|
261
libcxx/include/__cxx03/__algorithm/nth_element.h
Normal file
261
libcxx/include/__cxx03/__algorithm/nth_element.h
Normal file
@ -0,0 +1,261 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_NTH_ELEMENT_H
|
||||
#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/sort.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__debug_utils/randomize_range.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __nth_element_find_guard(
|
||||
_RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator __m, _Compare __comp) {
|
||||
// manually guard downward moving __j against __i
|
||||
while (true) {
|
||||
if (__i == --__j) {
|
||||
return false;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
return true; // found guard for downward moving __j, now use unguarded partition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||
__nth_element(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) {
|
||||
using _Ops = _IterOps<_AlgPolicy>;
|
||||
|
||||
// _Compare is known to be a reference type
|
||||
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
|
||||
const difference_type __limit = 7;
|
||||
while (true) {
|
||||
if (__nth == __last)
|
||||
return;
|
||||
difference_type __len = __last - __first;
|
||||
switch (__len) {
|
||||
case 0:
|
||||
case 1:
|
||||
return;
|
||||
case 2:
|
||||
if (__comp(*--__last, *__first))
|
||||
_Ops::iter_swap(__first, __last);
|
||||
return;
|
||||
case 3: {
|
||||
_RandomAccessIterator __m = __first;
|
||||
std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (__len <= __limit) {
|
||||
std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp);
|
||||
return;
|
||||
}
|
||||
// __len > __limit >= 3
|
||||
_RandomAccessIterator __m = __first + __len / 2;
|
||||
_RandomAccessIterator __lm1 = __last;
|
||||
unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp);
|
||||
// *__m is median
|
||||
// partition [__first, __m) < *__m and *__m <= [__m, __last)
|
||||
// (this inhibits tossing elements equivalent to __m around unnecessarily)
|
||||
_RandomAccessIterator __i = __first;
|
||||
_RandomAccessIterator __j = __lm1;
|
||||
// j points beyond range to be tested, *__lm1 is known to be <= *__m
|
||||
// The search going up is known to be guarded but the search coming down isn't.
|
||||
// Prime the downward search with a guard.
|
||||
if (!__comp(*__i, *__m)) // if *__first == *__m
|
||||
{
|
||||
// *__first == *__m, *__first doesn't go in first part
|
||||
if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
} else {
|
||||
// *__first == *__m, *__m <= all other elements
|
||||
// Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
|
||||
++__i; // __first + 1
|
||||
__j = __last;
|
||||
if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1)
|
||||
while (true) {
|
||||
if (__i == __j) {
|
||||
return; // [__first, __last) all equivalent elements
|
||||
} else if (__comp(*__first, *__i)) {
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
++__i;
|
||||
break;
|
||||
}
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
// [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
|
||||
if (__i == __j) {
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
while (!__comp(*__first, *__i)) {
|
||||
++__i;
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__i != __last,
|
||||
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
|
||||
}
|
||||
do {
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__j != __first,
|
||||
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
|
||||
--__j;
|
||||
} while (__comp(*__first, *__j));
|
||||
if (__i >= __j)
|
||||
break;
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
++__i;
|
||||
}
|
||||
// [__first, __i) == *__first and *__first < [__i, __last)
|
||||
// The first part is sorted,
|
||||
if (__nth < __i) {
|
||||
return;
|
||||
}
|
||||
// __nth_element the second part
|
||||
// std::__nth_element<_Compare>(__i, __nth, __last, __comp);
|
||||
__first = __i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++__i;
|
||||
// j points beyond range to be tested, *__lm1 is known to be <= *__m
|
||||
// if not yet partitioned...
|
||||
if (__i < __j) {
|
||||
// known that *(__i - 1) < *__m
|
||||
while (true) {
|
||||
// __m still guards upward moving __i
|
||||
while (__comp(*__i, *__m)) {
|
||||
++__i;
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__i != __last,
|
||||
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
|
||||
}
|
||||
// It is now known that a guard exists for downward moving __j
|
||||
do {
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__j != __first,
|
||||
"Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?");
|
||||
--__j;
|
||||
} while (!__comp(*__j, *__m));
|
||||
if (__i >= __j)
|
||||
break;
|
||||
_Ops::iter_swap(__i, __j);
|
||||
++__n_swaps;
|
||||
// It is known that __m != __j
|
||||
// If __m just moved, follow it
|
||||
if (__m == __i)
|
||||
__m = __j;
|
||||
++__i;
|
||||
}
|
||||
}
|
||||
// [__first, __i) < *__m and *__m <= [__i, __last)
|
||||
if (__i != __m && __comp(*__m, *__i)) {
|
||||
_Ops::iter_swap(__i, __m);
|
||||
++__n_swaps;
|
||||
}
|
||||
// [__first, __i) < *__i and *__i <= [__i+1, __last)
|
||||
if (__nth == __i)
|
||||
return;
|
||||
if (__n_swaps == 0) {
|
||||
// We were given a perfectly partitioned sequence. Coincidence?
|
||||
if (__nth < __i) {
|
||||
// Check for [__first, __i) already sorted
|
||||
__j = __m = __first;
|
||||
while (true) {
|
||||
if (++__j == __i) {
|
||||
// [__first, __i) sorted
|
||||
return;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
// not yet sorted, so sort
|
||||
break;
|
||||
}
|
||||
__m = __j;
|
||||
}
|
||||
} else {
|
||||
// Check for [__i, __last) already sorted
|
||||
__j = __m = __i;
|
||||
while (true) {
|
||||
if (++__j == __last) {
|
||||
// [__i, __last) sorted
|
||||
return;
|
||||
}
|
||||
if (__comp(*__j, *__m)) {
|
||||
// not yet sorted, so sort
|
||||
break;
|
||||
}
|
||||
__m = __j;
|
||||
}
|
||||
}
|
||||
}
|
||||
// __nth_element on range containing __nth
|
||||
if (__nth < __i) {
|
||||
// std::__nth_element<_Compare>(__first, __nth, __i, __comp);
|
||||
__last = __i;
|
||||
} else {
|
||||
// std::__nth_element<_Compare>(__i+1, __nth, __last, __comp);
|
||||
__first = ++__i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __nth_element_impl(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare& __comp) {
|
||||
if (__nth == __last)
|
||||
return;
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
|
||||
|
||||
std::__nth_element<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __nth, __last, __comp);
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __nth);
|
||||
if (__nth != __last) {
|
||||
std::__debug_randomize_range<_AlgPolicy>(++__nth, __last);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) {
|
||||
std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) {
|
||||
std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H
|
91
libcxx/include/__cxx03/__algorithm/partial_sort.h
Normal file
91
libcxx/include/__cxx03/__algorithm/partial_sort.h
Normal file
@ -0,0 +1,91 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PARTIAL_SORT_H
|
||||
#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_heap.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__algorithm/sort_heap.h>
|
||||
#include <__config>
|
||||
#include <__debug_utils/randomize_range.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_assignable.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
|
||||
if (__first == __middle) {
|
||||
return _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
}
|
||||
|
||||
std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
|
||||
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
|
||||
_RandomAccessIterator __i = __middle;
|
||||
for (; __i != __last; ++__i) {
|
||||
if (__comp(*__i, *__first)) {
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
|
||||
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
|
||||
}
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
|
||||
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
|
||||
__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) {
|
||||
if (__first == __middle)
|
||||
return _IterOps<_AlgPolicy>::next(__middle, __last);
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
|
||||
|
||||
auto __last_iter =
|
||||
std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<__comp_ref_type<_Compare> >(__comp));
|
||||
|
||||
std::__debug_randomize_range<_AlgPolicy>(__middle, __last);
|
||||
|
||||
return __last_iter;
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort(
|
||||
_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) {
|
||||
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
|
||||
|
||||
(void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
|
||||
std::partial_sort(__first, __middle, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H
|
106
libcxx/include/__cxx03/__algorithm/partial_sort_copy.h
Normal file
106
libcxx/include/__cxx03/__algorithm/partial_sort_copy.h
Normal file
@ -0,0 +1,106 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PARTIAL_SORT_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/make_heap.h>
|
||||
#include <__algorithm/make_projected.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__algorithm/sort_heap.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_callable.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy,
|
||||
class _Compare,
|
||||
class _InputIterator,
|
||||
class _Sentinel1,
|
||||
class _RandomAccessIterator,
|
||||
class _Sentinel2,
|
||||
class _Proj1,
|
||||
class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> __partial_sort_copy(
|
||||
_InputIterator __first,
|
||||
_Sentinel1 __last,
|
||||
_RandomAccessIterator __result_first,
|
||||
_Sentinel2 __result_last,
|
||||
_Compare&& __comp,
|
||||
_Proj1&& __proj1,
|
||||
_Proj2&& __proj2) {
|
||||
_RandomAccessIterator __r = __result_first;
|
||||
auto&& __projected_comp = std::__make_projected(__comp, __proj2);
|
||||
|
||||
if (__r != __result_last) {
|
||||
for (; __first != __last && __r != __result_last; ++__first, (void)++__r)
|
||||
*__r = *__first;
|
||||
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
|
||||
for (; __first != __last; ++__first)
|
||||
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
|
||||
*__result_first = *__first;
|
||||
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
|
||||
}
|
||||
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
|
||||
}
|
||||
|
||||
return pair<_InputIterator, _RandomAccessIterator>(
|
||||
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
|
||||
_InputIterator __first,
|
||||
_InputIterator __last,
|
||||
_RandomAccessIterator __result_first,
|
||||
_RandomAccessIterator __result_last,
|
||||
_Compare __comp) {
|
||||
static_assert(
|
||||
__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable");
|
||||
|
||||
auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(
|
||||
__first,
|
||||
__last,
|
||||
__result_first,
|
||||
__result_last,
|
||||
static_cast<__comp_ref_type<_Compare> >(__comp),
|
||||
__identity(),
|
||||
__identity());
|
||||
return __result.second;
|
||||
}
|
||||
|
||||
template <class _InputIterator, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
|
||||
_InputIterator __first,
|
||||
_InputIterator __last,
|
||||
_RandomAccessIterator __result_first,
|
||||
_RandomAccessIterator __result_last) {
|
||||
return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H
|
90
libcxx/include/__cxx03/__algorithm/partition.h
Normal file
90
libcxx/include/__cxx03/__algorithm/partition.h
Normal file
@ -0,0 +1,90 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PARTITION_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) {
|
||||
while (true) {
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__first));
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
++__first;
|
||||
}
|
||||
|
||||
_ForwardIterator __p = __first;
|
||||
while (++__p != __last) {
|
||||
if (__pred(*__p)) {
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __p);
|
||||
++__first;
|
||||
}
|
||||
}
|
||||
return std::make_pair(std::move(__first), std::move(__p));
|
||||
}
|
||||
|
||||
template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
|
||||
__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) {
|
||||
_BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
|
||||
_BidirectionalIterator __last = __original_last;
|
||||
|
||||
while (true) {
|
||||
while (true) {
|
||||
if (__first == __last)
|
||||
return std::make_pair(std::move(__first), std::move(__original_last));
|
||||
if (!__pred(*__first))
|
||||
break;
|
||||
++__first;
|
||||
}
|
||||
do {
|
||||
if (__first == --__last)
|
||||
return std::make_pair(std::move(__first), std::move(__original_last));
|
||||
} while (!__pred(*__last));
|
||||
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
|
||||
++__first;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
|
||||
__partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
|
||||
return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>(
|
||||
std::move(__first), std::move(__last), __pred, __iter_category);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Predicate>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
|
||||
auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory());
|
||||
return __result.first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_H
|
43
libcxx/include/__cxx03/__algorithm/partition_copy.h
Normal file
43
libcxx/include/__cxx03/__algorithm/partition_copy.h
Normal file
@ -0,0 +1,43 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PARTITION_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_COPY_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _InputIterator, class _OutputIterator1, class _OutputIterator2, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy(
|
||||
_InputIterator __first,
|
||||
_InputIterator __last,
|
||||
_OutputIterator1 __out_true,
|
||||
_OutputIterator2 __out_false,
|
||||
_Predicate __pred) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (__pred(*__first)) {
|
||||
*__out_true = *__first;
|
||||
++__out_true;
|
||||
} else {
|
||||
*__out_false = *__first;
|
||||
++__out_false;
|
||||
}
|
||||
}
|
||||
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H
|
44
libcxx/include/__cxx03/__algorithm/partition_point.h
Normal file
44
libcxx/include/__cxx03/__algorithm/partition_point.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PARTITION_POINT_H
|
||||
#define _LIBCPP___ALGORITHM_PARTITION_POINT_H
|
||||
|
||||
#include <__algorithm/half_positive.h>
|
||||
#include <__config>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ForwardIterator, class _Predicate>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
|
||||
partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
|
||||
difference_type __len = std::distance(__first, __last);
|
||||
while (__len != 0) {
|
||||
difference_type __l2 = std::__half_positive(__len);
|
||||
_ForwardIterator __m = __first;
|
||||
std::advance(__m, __l2);
|
||||
if (__pred(*__m)) {
|
||||
__first = ++__m;
|
||||
__len -= __l2 + 1;
|
||||
} else
|
||||
__len = __l2;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H
|
81
libcxx/include/__cxx03/__algorithm/pop_heap.h
Normal file
81
libcxx/include/__cxx03/__algorithm/pop_heap.h
Normal file
@ -0,0 +1,81 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_POP_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_POP_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/push_heap.h>
|
||||
#include <__algorithm/sift_down.h>
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_assignable.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__pop_heap(_RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last,
|
||||
_Compare& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
|
||||
// Calling `pop_heap` on an empty range is undefined behavior, but in practice it will be a no-op.
|
||||
_LIBCPP_ASSERT_PEDANTIC(__len > 0, "The heap given to pop_heap must be non-empty");
|
||||
|
||||
__comp_ref_type<_Compare> __comp_ref = __comp;
|
||||
|
||||
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
|
||||
if (__len > 1) {
|
||||
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
|
||||
_RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
|
||||
--__last;
|
||||
|
||||
if (__hole == __last) {
|
||||
*__hole = std::move(__top);
|
||||
} else {
|
||||
*__hole = _IterOps<_AlgPolicy>::__iter_move(__last);
|
||||
++__hole;
|
||||
*__last = std::move(__top);
|
||||
std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
|
||||
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
|
||||
std::__pop_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp, __len);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::pop_heap(std::move(__first), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_POP_HEAP_H
|
75
libcxx/include/__cxx03/__algorithm/prev_permutation.h
Normal file
75
libcxx/include/__cxx03/__algorithm/prev_permutation.h
Normal file
@ -0,0 +1,75 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PREV_PERMUTATION_H
|
||||
#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/reverse.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
|
||||
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
|
||||
using _Result = pair<_BidirectionalIterator, bool>;
|
||||
|
||||
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
|
||||
_BidirectionalIterator __i = __last_iter;
|
||||
if (__first == __last || __first == --__i)
|
||||
return _Result(std::move(__last_iter), false);
|
||||
|
||||
while (true) {
|
||||
_BidirectionalIterator __ip1 = __i;
|
||||
if (__comp(*__ip1, *--__i)) {
|
||||
_BidirectionalIterator __j = __last_iter;
|
||||
while (!__comp(*--__j, *__i))
|
||||
;
|
||||
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
|
||||
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
|
||||
return _Result(std::move(__last_iter), true);
|
||||
}
|
||||
if (__i == __first) {
|
||||
std::__reverse<_AlgPolicy>(__first, __last_iter);
|
||||
return _Result(std::move(__last_iter), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
|
||||
return std::__prev_permutation<_ClassicAlgPolicy>(
|
||||
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
|
||||
.second;
|
||||
}
|
||||
|
||||
template <class _BidirectionalIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
|
||||
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
|
||||
return std::prev_permutation(__first, __last, __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H
|
663
libcxx/include/__cxx03/__algorithm/pstl.h
Normal file
663
libcxx/include/__cxx03/__algorithm/pstl.h
Normal file
@ -0,0 +1,663 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PSTL_H
|
||||
#define _LIBCPP___ALGORITHM_PSTL_H
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
# include <__functional/operations.h>
|
||||
# include <__iterator/cpp17_iterator_concepts.h>
|
||||
# include <__iterator/iterator_traits.h>
|
||||
# include <__pstl/backend.h>
|
||||
# include <__pstl/dispatch.h>
|
||||
# include <__pstl/handle_exception.h>
|
||||
# include <__type_traits/enable_if.h>
|
||||
# include <__type_traits/is_execution_policy.h>
|
||||
# include <__type_traits/remove_cvref.h>
|
||||
# include <__utility/forward.h>
|
||||
# include <__utility/move.h>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||
any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__any_of, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||
all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__all_of, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool
|
||||
none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__none_of, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardIterator, "copy(first, last, result) requires [first, last) to be ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardOutIterator, "copy(first, last, result) requires result to be a ForwardIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(*__first), "copy(first, last, result) requires result to be an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__copy, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Size,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardIterator, "copy_n(first, n, result) requires first to be a ForwardIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardOutIterator, "copy_n(first, n, result) requires result to be a ForwardIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(*__first), "copy_n(first, n, result) requires result to be an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__copy_n, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
||||
count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__count_if, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator>
|
||||
count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(
|
||||
_ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__count, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
equal(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__equal_3leg, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__equal_3leg, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
equal_to{});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _Pred,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
equal(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_Pred __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__equal, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
equal(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__equal, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
equal_to{});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__fill, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Size,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__fill_n, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardIterator
|
||||
find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Function,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__for_each, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__func));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Size,
|
||||
class _Function,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each_n requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__for_each_n, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Generator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__generate, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__gen));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Size,
|
||||
class _Generator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate_n requires a ForwardIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__generate_n, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Predicate,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool
|
||||
is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__is_partitioned, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _Comp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
merge(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_ForwardOutIterator __result,
|
||||
_Comp __comp) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__merge, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
std::move(__result),
|
||||
std::move(__comp));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
merge(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2,
|
||||
_ForwardOutIterator __result) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__merge, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
std::move(__result),
|
||||
less{});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator
|
||||
move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "move requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "move requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(std::move(*__first)), "move requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__move, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__result));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Pred,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
replace_if(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_Pred __pred,
|
||||
const _Tp& __new_value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_if requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__replace_if, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred), __new_value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
replace(_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
const _Tp& __old_value,
|
||||
const _Tp& __new_value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace requires ForwardIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__replace, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __old_value, __new_value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Pred,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void replace_copy_if(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
_Pred __pred,
|
||||
const _Tp& __new_value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy_if requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy_if requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(*__first), "replace_copy_if requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__replace_copy_if, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
std::move(__pred),
|
||||
__new_value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _Tp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void replace_copy(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
const _Tp& __old_value,
|
||||
const _Tp& __new_value) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(*__first), "replace_copy requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__replace_copy, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
__old_value,
|
||||
__new_value);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __middle,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "rotate_copy requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "rotate_copy requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(*__first), "rotate_copy requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__rotate_copy, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first),
|
||||
std::move(__middle),
|
||||
std::move(__last),
|
||||
std::move(__result));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _Comp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
|
||||
_LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__sort, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
_LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__sort, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _Comp,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
|
||||
_LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "stable_sort requires RandomAccessIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__stable_sort, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _RandomAccessIterator,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI void
|
||||
stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
_LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "stable_sort requires RandomAccessIterators");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__stable_sort, __pstl::__current_configuration, _RawPolicy>;
|
||||
__pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator,
|
||||
class _ForwardOutIterator,
|
||||
class _UnaryOperation,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator __first,
|
||||
_ForwardIterator __last,
|
||||
_ForwardOutIterator __result,
|
||||
_UnaryOperation __op) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(__op(*__first)), "transform requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__transform, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first),
|
||||
std::move(__last),
|
||||
std::move(__result),
|
||||
std::move(__op));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy,
|
||||
class _ForwardIterator1,
|
||||
class _ForwardIterator2,
|
||||
class _ForwardOutIterator,
|
||||
class _BinaryOperation,
|
||||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>,
|
||||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
|
||||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
|
||||
_ExecutionPolicy&& __policy,
|
||||
_ForwardIterator1 __first1,
|
||||
_ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2,
|
||||
_ForwardOutIterator __result,
|
||||
_BinaryOperation __op) {
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform requires ForwardIterators");
|
||||
_LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator");
|
||||
_LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(
|
||||
_ForwardOutIterator, decltype(__op(*__first1, *__first2)), "transform requires an OutputIterator");
|
||||
using _Implementation = __pstl::__dispatch<__pstl::__transform_binary, __pstl::__current_configuration, _RawPolicy>;
|
||||
return __pstl::__handle_exception<_Implementation>(
|
||||
std::forward<_ExecutionPolicy>(__policy),
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__result),
|
||||
std::move(__op));
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PSTL_H
|
84
libcxx/include/__cxx03/__algorithm/push_heap.h
Normal file
84
libcxx/include/__cxx03/__algorithm/push_heap.h
Normal file
@ -0,0 +1,84 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_PUSH_HEAP_H
|
||||
#define _LIBCPP___ALGORITHM_PUSH_HEAP_H
|
||||
|
||||
#include <__algorithm/comp.h>
|
||||
#include <__algorithm/comp_ref_type.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__type_traits/is_assignable.h>
|
||||
#include <__type_traits/is_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__sift_up(_RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last,
|
||||
_Compare&& __comp,
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
|
||||
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
|
||||
|
||||
if (__len > 1) {
|
||||
__len = (__len - 2) / 2;
|
||||
_RandomAccessIterator __ptr = __first + __len;
|
||||
|
||||
if (__comp(*__ptr, *--__last)) {
|
||||
value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last));
|
||||
do {
|
||||
*__last = _IterOps<_AlgPolicy>::__iter_move(__ptr);
|
||||
__last = __ptr;
|
||||
if (__len == 0)
|
||||
break;
|
||||
__len = (__len - 1) / 2;
|
||||
__ptr = __first + __len;
|
||||
} while (__comp(*__ptr, __t));
|
||||
|
||||
*__last = std::move(__t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
|
||||
__push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
|
||||
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
|
||||
std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator, class _Compare>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
|
||||
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
|
||||
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
|
||||
|
||||
std::__push_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
|
||||
}
|
||||
|
||||
template <class _RandomAccessIterator>
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
|
||||
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
|
||||
std::push_heap(std::move(__first), std::move(__last), __less<>());
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H
|
83
libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h
Normal file
83
libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h
Normal file
@ -0,0 +1,83 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ADJACENT_FIND_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_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 <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __adjacent_find {
|
||||
struct __fn {
|
||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static _Iter
|
||||
__adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
||||
if (__first == __last)
|
||||
return __first;
|
||||
|
||||
auto __i = __first;
|
||||
while (++__i != __last) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first), std::invoke(__proj, *__i)))
|
||||
return __first;
|
||||
__first = __i;
|
||||
}
|
||||
return __i;
|
||||
}
|
||||
|
||||
template <forward_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter
|
||||
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
|
||||
return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj);
|
||||
}
|
||||
|
||||
template <forward_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, projected<iterator_t<_Range>, _Proj>>
|
||||
_Pred = ranges::equal_to>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range>
|
||||
operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const {
|
||||
return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __adjacent_find
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto adjacent_find = __adjacent_find::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H
|
74
libcxx/include/__cxx03/__algorithm/ranges_all_of.h
Normal file
74
libcxx/include/__cxx03/__algorithm/ranges_all_of.h
Normal file
@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ALL_OF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __all_of {
|
||||
struct __fn {
|
||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (!std::invoke(__pred, std::invoke(__proj, *__first)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <input_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const {
|
||||
return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
|
||||
return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __all_of
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto all_of = __all_of::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H
|
74
libcxx/include/__cxx03/__algorithm/ranges_any_of.h
Normal file
74
libcxx/include/__cxx03/__algorithm/ranges_any_of.h
Normal file
@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ANY_OF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __any_of {
|
||||
struct __fn {
|
||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <input_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const {
|
||||
return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const {
|
||||
return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __any_of
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto any_of = __any_of::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H
|
73
libcxx/include/__cxx03/__algorithm/ranges_binary_search.h
Normal file
73
libcxx/include/__cxx03/__algorithm/ranges_binary_search.h
Normal file
@ -0,0 +1,73 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_BINARY_SEARCH_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
|
||||
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/lower_bound.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>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __binary_search {
|
||||
struct __fn {
|
||||
template <forward_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Type,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
|
||||
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
|
||||
}
|
||||
|
||||
template <forward_range _Range,
|
||||
class _Type,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr 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<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj);
|
||||
return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret));
|
||||
}
|
||||
};
|
||||
} // namespace __binary_search
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto binary_search = __binary_search::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H
|
66
libcxx/include/__cxx03/__algorithm/ranges_clamp.h
Normal file
66
libcxx/include/__cxx03/__algorithm/ranges_clamp.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_CLAMP_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_CLAMP_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__utility/forward.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __clamp {
|
||||
struct __fn {
|
||||
template <class _Type,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()(
|
||||
const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))),
|
||||
"Bad bounds passed to std::ranges::clamp");
|
||||
|
||||
auto&& __projected = std::invoke(__proj, __value);
|
||||
if (std::invoke(__comp, std::forward<decltype(__projected)>(__projected), std::invoke(__proj, __low)))
|
||||
return __low;
|
||||
else if (std::invoke(__comp, std::invoke(__proj, __high), std::forward<decltype(__projected)>(__projected)))
|
||||
return __high;
|
||||
else
|
||||
return __value;
|
||||
}
|
||||
};
|
||||
} // namespace __clamp
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto clamp = __clamp::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H
|
66
libcxx/include/__cxx03/__algorithm/ranges_contains.h
Normal file
66
libcxx/include/__cxx03/__algorithm/ranges_contains.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_CONTAINS_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_H
|
||||
|
||||
#include <__algorithm/ranges_find.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__functional/reference_wrapper.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __contains {
|
||||
struct __fn {
|
||||
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static
|
||||
operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) {
|
||||
return ranges::find(std::move(__first), __last, __value, std::ref(__proj)) != __last;
|
||||
}
|
||||
|
||||
template <input_range _Range, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static
|
||||
operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) {
|
||||
return ranges::find(ranges::begin(__range), ranges::end(__range), __value, std::ref(__proj)) !=
|
||||
ranges::end(__range);
|
||||
}
|
||||
};
|
||||
} // namespace __contains
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto contains = __contains::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_H
|
@ -0,0 +1,97 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_CONTAINS_SUBRANGE_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H
|
||||
|
||||
#include <__algorithm/ranges_search.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__functional/reference_wrapper.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __contains_subrange {
|
||||
struct __fn {
|
||||
template <forward_iterator _Iter1,
|
||||
sentinel_for<_Iter1> _Sent1,
|
||||
forward_iterator _Iter2,
|
||||
sentinel_for<_Iter2> _Sent2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred __pred = {},
|
||||
_Proj1 __proj1 = {},
|
||||
_Proj2 __proj2 = {}) {
|
||||
if (__first2 == __last2)
|
||||
return true;
|
||||
|
||||
auto __ret = ranges::search(
|
||||
std::move(__first1), __last1, std::move(__first2), __last2, __pred, std::ref(__proj1), std::ref(__proj2));
|
||||
return __ret.empty() == false;
|
||||
}
|
||||
|
||||
template <forward_range _Range1,
|
||||
forward_range _Range2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static
|
||||
operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) {
|
||||
if constexpr (sized_range<_Range2>) {
|
||||
if (ranges::size(__range2) == 0)
|
||||
return true;
|
||||
} else {
|
||||
if (ranges::begin(__range2) == ranges::end(__range2))
|
||||
return true;
|
||||
}
|
||||
|
||||
auto __ret = ranges::search(__range1, __range2, __pred, std::ref(__proj1), std::ref(__proj2));
|
||||
return __ret.empty() == false;
|
||||
}
|
||||
};
|
||||
} // namespace __contains_subrange
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto contains_subrange = __contains_subrange::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H
|
71
libcxx/include/__cxx03/__algorithm/ranges_copy.h
Normal file
71
libcxx/include/__cxx03/__algorithm/ranges_copy.h
Normal file
@ -0,0 +1,71 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COPY_H
|
||||
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _InIter, class _OutIter>
|
||||
using copy_result = in_out_result<_InIter, _OutIter>;
|
||||
|
||||
namespace __copy {
|
||||
struct __fn {
|
||||
template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter>
|
||||
requires indirectly_copyable<_InIter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter>
|
||||
operator()(_InIter __first, _Sent __last, _OutIter __result) const {
|
||||
auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <input_range _Range, weakly_incrementable _OutIter>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __r, _OutIter __result) const {
|
||||
auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
};
|
||||
} // namespace __copy
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto copy = __copy::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H
|
69
libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h
Normal file
69
libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h
Normal file
@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_BACKWARD_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
|
||||
|
||||
#include <__algorithm/copy_backward.h>
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Ip, class _Op>
|
||||
using copy_backward_result = in_out_result<_Ip, _Op>;
|
||||
|
||||
namespace __copy_backward {
|
||||
struct __fn {
|
||||
template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2>
|
||||
requires indirectly_copyable<_InIter1, _InIter2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2>
|
||||
operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const {
|
||||
auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <bidirectional_range _Range, bidirectional_iterator _Iter>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
|
||||
operator()(_Range&& __r, _Iter __result) const {
|
||||
auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result));
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
};
|
||||
} // namespace __copy_backward
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto copy_backward = __copy_backward::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H
|
87
libcxx/include/__cxx03/__algorithm/ranges_copy_if.h
Normal file
87
libcxx/include/__cxx03/__algorithm/ranges_copy_if.h
Normal file
@ -0,0 +1,87 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_IF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
|
||||
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Ip, class _Op>
|
||||
using copy_if_result = in_out_result<_Ip, _Op>;
|
||||
|
||||
namespace __copy_if {
|
||||
struct __fn {
|
||||
template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter>
|
||||
__copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first))) {
|
||||
*__result = *__first;
|
||||
++__result;
|
||||
}
|
||||
}
|
||||
return {std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
template <input_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
|
||||
requires indirectly_copyable<_Iter, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter>
|
||||
operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range,
|
||||
weakly_incrementable _OutIter,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
requires indirectly_copyable<iterator_t<_Range>, _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter>
|
||||
operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const {
|
||||
return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __copy_if
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto copy_if = __copy_if::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H
|
81
libcxx/include/__cxx03/__algorithm/ranges_copy_n.h
Normal file
81
libcxx/include/__cxx03/__algorithm/ranges_copy_n.h
Normal file
@ -0,0 +1,81 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COPY_N_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
||||
|
||||
#include <__algorithm/copy.h>
|
||||
#include <__algorithm/in_out_result.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/ranges_copy.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/unreachable_sentinel.h>
|
||||
#include <__iterator/wrap_iter.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Ip, class _Op>
|
||||
using copy_n_result = in_out_result<_Ip, _Op>;
|
||||
|
||||
namespace __copy_n {
|
||||
struct __fn {
|
||||
template <class _InIter, class _DiffType, class _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
|
||||
__go(_InIter __first, _DiffType __n, _OutIter __result) {
|
||||
while (__n != 0) {
|
||||
*__result = *__first;
|
||||
++__first;
|
||||
++__result;
|
||||
--__n;
|
||||
}
|
||||
return {std::move(__first), std::move(__result)};
|
||||
}
|
||||
|
||||
template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter>
|
||||
__go(_InIter __first, _DiffType __n, _OutIter __result) {
|
||||
auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result);
|
||||
return {__ret.first, __ret.second};
|
||||
}
|
||||
|
||||
template <input_iterator _Ip, weakly_incrementable _Op>
|
||||
requires indirectly_copyable<_Ip, _Op>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op>
|
||||
operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const {
|
||||
return __go(std::move(__first), __n, std::move(__result));
|
||||
}
|
||||
};
|
||||
} // namespace __copy_n
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto copy_n = __copy_n::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H
|
66
libcxx/include/__cxx03/__algorithm/ranges_count.h
Normal file
66
libcxx/include/__cxx03/__algorithm/ranges_count.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COUNT_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COUNT_H
|
||||
|
||||
#include <__algorithm/count.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __count {
|
||||
struct __fn {
|
||||
template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const {
|
||||
return std::__count<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
|
||||
operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const {
|
||||
return std::__count<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __count
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto count = __count::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H
|
79
libcxx/include/__cxx03/__algorithm/ranges_count_if.h
Normal file
79
libcxx/include/__cxx03/__algorithm/ranges_count_if.h
Normal file
@ -0,0 +1,79 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COUNT_IF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
template <class _Iter, class _Sent, class _Proj, class _Pred>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
|
||||
__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
|
||||
iter_difference_t<_Iter> __counter(0);
|
||||
for (; __first != __last; ++__first) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first)))
|
||||
++__counter;
|
||||
}
|
||||
return __counter;
|
||||
}
|
||||
|
||||
namespace __count_if {
|
||||
struct __fn {
|
||||
template <input_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const {
|
||||
return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range>
|
||||
operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const {
|
||||
return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __count_if
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto count_if = __count_if::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H
|
201
libcxx/include/__cxx03/__algorithm/ranges_ends_with.h
Normal file
201
libcxx/include/__cxx03/__algorithm/ranges_ends_with.h
Normal file
@ -0,0 +1,201 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ENDS_WITH_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H
|
||||
|
||||
#include <__algorithm/ranges_equal.h>
|
||||
#include <__algorithm/ranges_starts_with.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__functional/reference_wrapper.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__iterator/reverse_iterator.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __ends_with {
|
||||
struct __fn {
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl_bidirectional(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2) {
|
||||
auto __rbegin1 = std::make_reverse_iterator(__last1);
|
||||
auto __rend1 = std::make_reverse_iterator(__first1);
|
||||
auto __rbegin2 = std::make_reverse_iterator(__last2);
|
||||
auto __rend2 = std::make_reverse_iterator(__first2);
|
||||
return ranges::starts_with(
|
||||
__rbegin1, __rend1, __rbegin2, __rend2, std::ref(__pred), std::ref(__proj1), std::ref(__proj2));
|
||||
}
|
||||
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2) {
|
||||
if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&
|
||||
(!std::random_access_iterator<_Sent1>) && (!std::random_access_iterator<_Sent2>)) {
|
||||
return __ends_with_fn_impl_bidirectional(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
|
||||
|
||||
} else {
|
||||
auto __n1 = ranges::distance(__first1, __last1);
|
||||
auto __n2 = ranges::distance(__first2, __last2);
|
||||
if (__n2 == 0)
|
||||
return true;
|
||||
if (__n2 > __n1)
|
||||
return false;
|
||||
|
||||
return __ends_with_fn_impl_with_offset(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
__n1 - __n2);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Iter1,
|
||||
class _Sent1,
|
||||
class _Iter2,
|
||||
class _Sent2,
|
||||
class _Pred,
|
||||
class _Proj1,
|
||||
class _Proj2,
|
||||
class _Offset>
|
||||
static _LIBCPP_HIDE_FROM_ABI constexpr bool __ends_with_fn_impl_with_offset(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2,
|
||||
_Offset __offset) {
|
||||
if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&
|
||||
!std::random_access_iterator<_Sent1> && !std::random_access_iterator<_Sent2>) {
|
||||
return __ends_with_fn_impl_bidirectional(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
|
||||
|
||||
} else {
|
||||
ranges::advance(__first1, __offset);
|
||||
return ranges::equal(
|
||||
std::move(__first1),
|
||||
std::move(__last1),
|
||||
std::move(__first2),
|
||||
std::move(__last2),
|
||||
std::ref(__pred),
|
||||
std::ref(__proj1),
|
||||
std::ref(__proj2));
|
||||
}
|
||||
}
|
||||
|
||||
template <input_iterator _Iter1,
|
||||
sentinel_for<_Iter1> _Sent1,
|
||||
input_iterator _Iter2,
|
||||
sentinel_for<_Iter2> _Sent2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires(forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>) &&
|
||||
(forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>) &&
|
||||
indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred __pred = {},
|
||||
_Proj1 __proj1 = {},
|
||||
_Proj2 __proj2 = {}) const {
|
||||
return __ends_with_fn_impl(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <input_range _Range1,
|
||||
input_range _Range2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires(forward_range<_Range1> || sized_range<_Range1>) && (forward_range<_Range2> || sized_range<_Range2>) &&
|
||||
indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
||||
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
|
||||
auto __n1 = ranges::size(__range1);
|
||||
auto __n2 = ranges::size(__range2);
|
||||
if (__n2 == 0)
|
||||
return true;
|
||||
if (__n2 > __n1)
|
||||
return false;
|
||||
auto __offset = __n1 - __n2;
|
||||
|
||||
return __ends_with_fn_impl_with_offset(
|
||||
ranges::begin(__range1),
|
||||
ranges::end(__range1),
|
||||
ranges::begin(__range2),
|
||||
ranges::end(__range2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
__offset);
|
||||
|
||||
} else {
|
||||
return __ends_with_fn_impl(
|
||||
ranges::begin(__range1),
|
||||
ranges::end(__range1),
|
||||
ranges::begin(__range2),
|
||||
ranges::end(__range2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace __ends_with
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto ends_with = __ends_with::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H
|
109
libcxx/include/__cxx03/__algorithm/ranges_equal.h
Normal file
109
libcxx/include/__cxx03/__algorithm/ranges_equal.h
Normal file
@ -0,0 +1,109 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_EQUAL_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H
|
||||
|
||||
#include <__algorithm/equal.h>
|
||||
#include <__algorithm/unwrap_range.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/distance.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __equal {
|
||||
struct __fn {
|
||||
template <input_iterator _Iter1,
|
||||
sentinel_for<_Iter1> _Sent1,
|
||||
input_iterator _Iter2,
|
||||
sentinel_for<_Iter2> _Sent2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred __pred = {},
|
||||
_Proj1 __proj1 = {},
|
||||
_Proj2 __proj2 = {}) const {
|
||||
if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) {
|
||||
if (__last1 - __first1 != __last2 - __first2)
|
||||
return false;
|
||||
}
|
||||
auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1));
|
||||
auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2));
|
||||
return std::__equal_impl(
|
||||
std::move(__unwrapped1.first),
|
||||
std::move(__unwrapped1.second),
|
||||
std::move(__unwrapped2.first),
|
||||
std::move(__unwrapped2.second),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2);
|
||||
}
|
||||
|
||||
template <input_range _Range1,
|
||||
input_range _Range2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(
|
||||
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
if constexpr (sized_range<_Range1> && sized_range<_Range2>) {
|
||||
if (ranges::distance(__range1) != ranges::distance(__range2))
|
||||
return false;
|
||||
}
|
||||
auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1));
|
||||
auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2));
|
||||
return std::__equal_impl(
|
||||
std::move(__unwrapped1.first),
|
||||
std::move(__unwrapped1.second),
|
||||
std::move(__unwrapped2.first),
|
||||
std::move(__unwrapped2.second),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace __equal
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto equal = __equal::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H
|
80
libcxx/include/__cxx03/__algorithm/ranges_equal_range.h
Normal file
80
libcxx/include/__cxx03/__algorithm/ranges_equal_range.h
Normal file
@ -0,0 +1,80 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_EQUAL_RANGE_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
|
||||
|
||||
#include <__algorithm/equal_range.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __equal_range {
|
||||
|
||||
struct __fn {
|
||||
template <forward_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Tp,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj);
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
|
||||
template <forward_range _Range,
|
||||
class _Tp,
|
||||
class _Proj = identity,
|
||||
indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
|
||||
operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const {
|
||||
auto __ret =
|
||||
std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj);
|
||||
return {std::move(__ret.first), std::move(__ret.second)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __equal_range
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto equal_range = __equal_range::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H
|
62
libcxx/include/__cxx03/__algorithm/ranges_fill.h
Normal file
62
libcxx/include/__cxx03/__algorithm/ranges_fill.h
Normal file
@ -0,0 +1,62 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FILL_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FILL_H
|
||||
|
||||
#include <__algorithm/ranges_fill_n.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __fill {
|
||||
struct __fn {
|
||||
template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const {
|
||||
if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) {
|
||||
return ranges::fill_n(__first, __last - __first, __value);
|
||||
} else {
|
||||
for (; __first != __last; ++__first)
|
||||
*__first = __value;
|
||||
return __first;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Type, output_range<const _Type&> _Range>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const {
|
||||
return (*this)(ranges::begin(__range), ranges::end(__range), __value);
|
||||
}
|
||||
};
|
||||
} // namespace __fill
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto fill = __fill::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H
|
53
libcxx/include/__cxx03/__algorithm/ranges_fill_n.h
Normal file
53
libcxx/include/__cxx03/__algorithm/ranges_fill_n.h
Normal file
@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FILL_N_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H
|
||||
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __fill_n {
|
||||
struct __fn {
|
||||
template <class _Type, output_iterator<const _Type&> _Iter>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Iter
|
||||
operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const {
|
||||
for (; __n != 0; --__n) {
|
||||
*__first = __value;
|
||||
++__first;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
};
|
||||
} // namespace __fill_n
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto fill_n = __fill_n::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H
|
80
libcxx/include/__cxx03/__algorithm/ranges_find.h
Normal file
80
libcxx/include/__cxx03/__algorithm/ranges_find.h
Normal file
@ -0,0 +1,80 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_H
|
||||
|
||||
#include <__algorithm/find.h>
|
||||
#include <__algorithm/ranges_find_if.h>
|
||||
#include <__algorithm/unwrap_range.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 <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __find {
|
||||
struct __fn {
|
||||
template <class _Iter, class _Sent, class _Tp, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr _Iter
|
||||
__find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
|
||||
if constexpr (forward_iterator<_Iter>) {
|
||||
auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last));
|
||||
return std::__rewrap_range<_Sent>(
|
||||
std::move(__first), std::__find(std::move(__first_un), std::move(__last_un), __value, __proj));
|
||||
} else {
|
||||
return std::__find(std::move(__first), std::move(__last), __value, __proj);
|
||||
}
|
||||
}
|
||||
|
||||
template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
|
||||
operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const {
|
||||
return __find_unwrap(std::move(__first), std::move(__last), __value, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Rp, class _Tp, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
|
||||
operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const {
|
||||
return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find = __find::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_H
|
103
libcxx/include/__cxx03/__algorithm/ranges_find_end.h
Normal file
103
libcxx/include/__cxx03/__algorithm/ranges_find_end.h
Normal file
@ -0,0 +1,103 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_END_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_END_H
|
||||
|
||||
#include <__algorithm/find_end.h>
|
||||
#include <__algorithm/iterator_operations.h>
|
||||
#include <__algorithm/ranges_iterator_concept.h>
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/pair.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __find_end {
|
||||
struct __fn {
|
||||
template <forward_iterator _Iter1,
|
||||
sentinel_for<_Iter1> _Sent1,
|
||||
forward_iterator _Iter2,
|
||||
sentinel_for<_Iter2> _Sent2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred __pred = {},
|
||||
_Proj1 __proj1 = {},
|
||||
_Proj2 __proj2 = {}) const {
|
||||
auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
|
||||
__first1,
|
||||
__last1,
|
||||
__first2,
|
||||
__last2,
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
__iterator_concept<_Iter1>(),
|
||||
__iterator_concept<_Iter2>());
|
||||
return {__ret.first, __ret.second};
|
||||
}
|
||||
|
||||
template <forward_range _Range1,
|
||||
forward_range _Range2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()(
|
||||
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
auto __ret = std::__find_end_impl<_RangeAlgPolicy>(
|
||||
ranges::begin(__range1),
|
||||
ranges::end(__range1),
|
||||
ranges::begin(__range2),
|
||||
ranges::end(__range2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2,
|
||||
__iterator_concept<iterator_t<_Range1>>(),
|
||||
__iterator_concept<iterator_t<_Range2>>());
|
||||
return {__ret.first, __ret.second};
|
||||
}
|
||||
};
|
||||
} // namespace __find_end
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find_end = __find_end::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H
|
106
libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h
Normal file
106
libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h
Normal file
@ -0,0 +1,106 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_FIRST_OF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/dangling.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __find_first_of {
|
||||
struct __fn {
|
||||
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred& __pred,
|
||||
_Proj1& __proj1,
|
||||
_Proj2& __proj2) {
|
||||
for (; __first1 != __last1; ++__first1) {
|
||||
for (auto __j = __first2; __j != __last2; ++__j) {
|
||||
if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j)))
|
||||
return __first1;
|
||||
}
|
||||
}
|
||||
return __first1;
|
||||
}
|
||||
|
||||
template <input_iterator _Iter1,
|
||||
sentinel_for<_Iter1> _Sent1,
|
||||
forward_iterator _Iter2,
|
||||
sentinel_for<_Iter2> _Sent2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()(
|
||||
_Iter1 __first1,
|
||||
_Sent1 __last1,
|
||||
_Iter2 __first2,
|
||||
_Sent2 __last2,
|
||||
_Pred __pred = {},
|
||||
_Proj1 __proj1 = {},
|
||||
_Proj2 __proj2 = {}) const {
|
||||
return __find_first_of_impl(
|
||||
std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
|
||||
}
|
||||
|
||||
template <input_range _Range1,
|
||||
forward_range _Range2,
|
||||
class _Pred = ranges::equal_to,
|
||||
class _Proj1 = identity,
|
||||
class _Proj2 = identity>
|
||||
requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()(
|
||||
_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
|
||||
return __find_first_of_impl(
|
||||
ranges::begin(__range1),
|
||||
ranges::end(__range1),
|
||||
ranges::begin(__range2),
|
||||
ranges::end(__range2),
|
||||
__pred,
|
||||
__proj1,
|
||||
__proj2);
|
||||
}
|
||||
};
|
||||
} // namespace __find_first_of
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find_first_of = __find_first_of::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H
|
75
libcxx/include/__cxx03/__algorithm/ranges_find_if.h
Normal file
75
libcxx/include/__cxx03/__algorithm/ranges_find_if.h
Normal file
@ -0,0 +1,75 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IF_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_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 <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Ip, class _Sp, class _Pred, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
|
||||
for (; __first != __last; ++__first) {
|
||||
if (std::invoke(__pred, std::invoke(__proj, *__first)))
|
||||
break;
|
||||
}
|
||||
return __first;
|
||||
}
|
||||
|
||||
namespace __find_if {
|
||||
struct __fn {
|
||||
template <input_iterator _Ip,
|
||||
sentinel_for<_Ip> _Sp,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
|
||||
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
|
||||
return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
|
||||
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
|
||||
return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find_if
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find_if = __find_if::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H
|
69
libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h
Normal file
69
libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h
Normal file
@ -0,0 +1,69 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_IF_NOT_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
|
||||
|
||||
#include <__algorithm/ranges_find_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 <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
namespace __find_if_not {
|
||||
struct __fn {
|
||||
template <input_iterator _Ip,
|
||||
sentinel_for<_Ip> _Sp,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Ip, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip
|
||||
operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const {
|
||||
auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
|
||||
return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj);
|
||||
}
|
||||
|
||||
template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp>
|
||||
operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const {
|
||||
auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); };
|
||||
return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find_if_not
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find_if_not = __find_if_not::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H
|
175
libcxx/include/__cxx03/__algorithm/ranges_find_last.h
Normal file
175
libcxx/include/__cxx03/__algorithm/ranges_find_last.h
Normal file
@ -0,0 +1,175 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_H
|
||||
#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/identity.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/indirectly_comparable.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/prev.h>
|
||||
#include <__iterator/projected.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Iter, class _Sent, class _Pred, class _Proj>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
|
||||
__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj& __proj) {
|
||||
if (__first == __last) {
|
||||
return subrange<_Iter>(__first, __first);
|
||||
}
|
||||
|
||||
if constexpr (bidirectional_iterator<_Iter>) {
|
||||
auto __last_it = ranges::next(__first, __last);
|
||||
for (auto __it = ranges::prev(__last_it); __it != __first; --__it) {
|
||||
if (__pred(std::invoke(__proj, *__it))) {
|
||||
return subrange<_Iter>(std::move(__it), std::move(__last_it));
|
||||
}
|
||||
}
|
||||
if (__pred(std::invoke(__proj, *__first))) {
|
||||
return subrange<_Iter>(std::move(__first), std::move(__last_it));
|
||||
}
|
||||
return subrange<_Iter>(__last_it, __last_it);
|
||||
} else {
|
||||
bool __found = false;
|
||||
_Iter __found_it;
|
||||
for (; __first != __last; ++__first) {
|
||||
if (__pred(std::invoke(__proj, *__first))) {
|
||||
__found = true;
|
||||
__found_it = __first;
|
||||
}
|
||||
}
|
||||
|
||||
if (__found) {
|
||||
return subrange<_Iter>(std::move(__found_it), std::move(__first));
|
||||
} else {
|
||||
return subrange<_Iter>(__first, __first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace __find_last {
|
||||
struct __fn {
|
||||
template <class _Type>
|
||||
struct __op {
|
||||
const _Type& __value;
|
||||
template <class _Elem>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const {
|
||||
return std::forward<_Elem>(__elem) == __value;
|
||||
}
|
||||
};
|
||||
|
||||
template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Type>{__value}, __proj);
|
||||
}
|
||||
|
||||
template <forward_range _Range, class _Type, class _Proj = identity>
|
||||
requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range>
|
||||
operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Type>{__value}, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find_last
|
||||
|
||||
namespace __find_last_if {
|
||||
struct __fn {
|
||||
template <class _Pred>
|
||||
struct __op {
|
||||
_Pred& __pred;
|
||||
template <class _Elem>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const {
|
||||
return std::invoke(__pred, std::forward<_Elem>(__elem));
|
||||
}
|
||||
};
|
||||
|
||||
template <forward_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Pred>{__pred}, __proj);
|
||||
}
|
||||
|
||||
template <forward_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range>
|
||||
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Pred>{__pred}, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find_last_if
|
||||
|
||||
namespace __find_last_if_not {
|
||||
struct __fn {
|
||||
template <class _Pred>
|
||||
struct __op {
|
||||
_Pred& __pred;
|
||||
template <class _Elem>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const {
|
||||
return !std::invoke(__pred, std::forward<_Elem>(__elem));
|
||||
}
|
||||
};
|
||||
|
||||
template <forward_iterator _Iter,
|
||||
sentinel_for<_Iter> _Sent,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter>
|
||||
operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Pred>{__pred}, __proj);
|
||||
}
|
||||
|
||||
template <forward_range _Range,
|
||||
class _Proj = identity,
|
||||
indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range>
|
||||
operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) {
|
||||
return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Pred>{__pred}, __proj);
|
||||
}
|
||||
};
|
||||
} // namespace __find_last_if_not
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto find_last = __find_last::__fn{};
|
||||
inline constexpr auto find_last_if = __find_last_if::__fn{};
|
||||
inline constexpr auto find_last_if_not = __find_last_if_not::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user