//===----------------------------------------------------------------------===// // // 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 <__algorithm/copy_n.h> #include <__algorithm/count.h> #include <__algorithm/equal.h> #include <__algorithm/fill_n.h> #include <__algorithm/for_each.h> #include <__algorithm/for_each_n.h> #include <__algorithm/pstl_frontend_dispatch.h> #include <__atomic/atomic.h> #include <__config> #include <__functional/identity.h> #include <__functional/operations.h> #include <__iterator/concepts.h> #include <__iterator/cpp17_iterator_concepts.h> #include <__iterator/iterator_traits.h> #include <__numeric/pstl.h> #include <__pstl/configuration.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_execution_policy.h> #include <__type_traits/is_trivially_copyable.h> #include <__type_traits/remove_cvref.h> #include <__utility/empty.h> #include <__utility/move.h> #include #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 _LIBCPP_BEGIN_NAMESPACE_STD template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>> __find_if(_ExecutionPolicy&&, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__find_if(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_any_of(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __any_of( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) -> optional { auto __res = std::__find_if(__policy, __g_first, __g_last, __g_pred); if (!__res) return nullopt; return *__res != __g_last; }, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__any_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_all_of(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __all_of(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Pred&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) -> optional { auto __res = std::__any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) { return !__g_pred(__value); }); if (!__res) return nullopt; return !*__res; }, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__all_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_none_of(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __none_of(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Pred&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) -> optional { auto __res = std::__any_of(__policy, __g_first, __g_last, __g_pred); if (!__res) return nullopt; return !*__res; }, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__none_of(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardOutIterator>> __transform(_ExecutionPolicy&&, _ForwardIterator&& __first, _ForwardIterator&& __last, _ForwardOutIterator&& __result, _UnaryOperation&& __op) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_transform<_RawPolicy>( _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op)); } template , enable_if_t, 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"); auto __res = std::__transform(__policy, std::move(__first), std::move(__last), std::move(__result), std::move(__op)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template , enable_if_t, int> = 0> _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardOutIterator>> __transform(_ExecutionPolicy&&, _ForwardIterator1&& __first1, _ForwardIterator1&& __last1, _ForwardIterator2&& __first2, _ForwardOutIterator&& __result, _BinaryOperation&& __op) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_transform<_RawPolicy>( _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op)); } template , enable_if_t, 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"); auto __res = std::__transform( __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __for_each(_ExecutionPolicy&&, _ForwardIterator&& __first, _ForwardIterator&& __last, _Function&& __func) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func)); } template , enable_if_t, 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"); if (!std::__for_each(__policy, std::move(__first), std::move(__last), std::move(__func))) std::__throw_bad_alloc(); } // TODO: Use the std::copy/move shenanigans to forward to std::memmove template void __pstl_copy(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __copy(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _ForwardOutIterator&& __result) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result) { return std::__transform(__policy, __g_first, __g_last, __g_result, __identity()); }, std::move(__first), std::move(__last), std::move(__result)); } template , enable_if_t, 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"); auto __res = std::__copy(__policy, std::move(__first), std::move(__last), std::move(__result)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_copy_n(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __copy_n( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _ForwardOutIterator&& __result) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_copy_n, _RawPolicy), [&__policy]( _ForwardIterator __g_first, _Size __g_n, _ForwardOutIterator __g_result) -> optional<_ForwardIterator> { if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) { return std::__copy(__policy, std::move(__g_first), std::move(__g_first + __g_n), std::move(__g_result)); } else { (void)__policy; return std::copy_n(__g_first, __g_n, __g_result); } }, std::move(__first), std::move(__n), std::move(__result)); } template , enable_if_t, 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"); auto __res = std::__copy_n(__policy, std::move(__first), std::move(__n), std::move(__result)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_count_if(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> __count_if( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept { using __diff_t = __iter_diff_t<_ForwardIterator>; return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) -> optional<__diff_t> { return std::__transform_reduce( __policy, std::move(__g_first), std::move(__g_last), __diff_t(), std::plus{}, [&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); }); }, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__count_if(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_count(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__iter_diff_t<_ForwardIterator>> __count( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) -> optional<__iter_diff_t<_ForwardIterator>> { return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) { return __v == __g_value; }); }, std::forward<_ForwardIterator>(__first), std::forward<_ForwardIterator>(__last), __value); } template , enable_if_t, 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"); auto __res = std::__count(__policy, std::move(__first), std::move(__last), __value); if (!__res) std::__throw_bad_alloc(); return *__res; } template void __pstl_equal(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __equal(_ExecutionPolicy&& __policy, _ForwardIterator1&& __first1, _ForwardIterator1&& __last1, _ForwardIterator2&& __first2, _Pred&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy), [&__policy]( _ForwardIterator1 __g_first1, _ForwardIterator1 __g_last1, _ForwardIterator2 __g_first2, _Pred __g_pred) { return std::__transform_reduce( __policy, std::move(__g_first1), std::move(__g_last1), std::move(__g_first2), true, std::logical_and{}, std::move(__g_pred)); }, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *__res; } template >, 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"); auto __res = std::__equal(__policy, std::move(__first1), std::move(__last1), std::move(__first2), std::equal_to{}); if (!__res) std::__throw_bad_alloc(); return *__res; } template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __equal(_ExecutionPolicy&& __policy, _ForwardIterator1&& __first1, _ForwardIterator1&& __last1, _ForwardIterator2&& __first2, _ForwardIterator2&& __last2, _Pred&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_equal, _RawPolicy), [&__policy](_ForwardIterator1 __g_first1, _ForwardIterator1 __g_last1, _ForwardIterator2 __g_first2, _ForwardIterator2 __g_last2, _Pred __g_pred) -> optional { if constexpr (__has_random_access_iterator_category<_ForwardIterator1>::value && __has_random_access_iterator_category<_ForwardIterator2>::value) { if (__g_last1 - __g_first1 != __g_last2 - __g_first2) return false; return std::__equal( __policy, std::move(__g_first1), std::move(__g_last1), std::move(__g_first2), std::move(__g_pred)); } else { (void)__policy; // Avoid unused lambda capture warning return std::equal( std::move(__g_first1), std::move(__g_last1), std::move(__g_first2), std::move(__g_last2), std::move(__g_pred)); } }, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__equal( __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *__res; } template >, 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"); auto __res = std::__equal( __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::equal_to{}); if (!__res) std::__throw_bad_alloc(); return *__res; } template void __pstl_fill(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> _LIBCPP_HIDE_FROM_ABI optional<__empty> __fill( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { return std::__for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { __element = __g_value; }); }, std::forward<_ForwardIterator>(__first), std::forward<_ForwardIterator>(__last), __value); } template , enable_if_t, 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"); if (!std::__fill(__policy, std::move(__first), std::move(__last), __value)) std::__throw_bad_alloc(); } template void __pstl_fill_n(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __fill_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _SizeT&& __n, const _Tp& __value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n, _RawPolicy), [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) { if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) std::fill(__policy, __g_first, __g_first + __g_n, __g_value); else std::fill_n(__g_first, __g_n, __g_value); return optional<__empty>{__empty{}}; }, std::move(__first), std::move(__n), __value); } template , enable_if_t, int> = 0> _LIBCPP_HIDE_FROM_ABI void fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) { _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires ForwardIterators"); if (!std::__fill_n(__policy, std::move(__first), std::move(__n), __value)) std::__throw_bad_alloc(); } template void __pstl_find_if_not(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>> __find_if_not( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not, _RawPolicy), [&](_ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Predicate&& __g_pred) -> optional<__remove_cvref_t<_ForwardIterator>> { return std::__find_if( __policy, __g_first, __g_last, [&](__iter_reference<__remove_cvref_t<_ForwardIterator>> __value) { return !__g_pred(__value); }); }, std::forward<_ForwardIterator>(__first), std::forward<_ForwardIterator>(__last), std::forward<_Predicate>(__pred)); } template , enable_if_t, 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"); auto __res = std::__find_if_not(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_find(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__remove_cvref_t<_ForwardIterator>> __find( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find, _RawPolicy), [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) -> optional<_ForwardIterator> { return std::find_if( __policy, __g_first, __g_last, [&](__iter_reference<__remove_cvref_t<_ForwardIterator>> __element) { return __element == __g_value; }); }, std::forward<_ForwardIterator>(__first), std::forward<_ForwardIterator>(__last), __value); } template , enable_if_t, 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"); auto __res = std::__find(__policy, std::move(__first), std::move(__last), __value); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template void __pstl_for_each_n(); // declaration needed for the frontend dispatch below template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __size, _Function&& __func) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n, _RawPolicy), [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) -> optional<__empty> { if constexpr (__has_random_access_iterator_category_or_concept<_ForwardIterator>::value) { std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func)); return __empty{}; } else { std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func)); return __empty{}; } }, std::move(__first), std::move(__size), std::move(__func)); } template , enable_if_t, 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"); auto __res = std::__for_each_n(__policy, std::move(__first), std::move(__size), std::move(__func)); if (!__res) std::__throw_bad_alloc(); } template void __pstl_generate(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __generate( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Generator&& __gen) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) { return std::__for_each( __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) { __element = __g_gen(); }); }, std::move(__first), std::move(__last), std::move(__gen)); } template , enable_if_t, 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"); if (!std::__generate(__policy, std::move(__first), std::move(__last), std::move(__gen))) std::__throw_bad_alloc(); } template void __pstl_generate_n(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __generate_n(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _Size&& __n, _Generator&& __gen) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n, _RawPolicy), [&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) { return std::__for_each_n( __policy, std::move(__g_first), std::move(__g_n), [&](__iter_reference<_ForwardIterator> __element) { __element = __g_gen(); }); }, std::move(__first), __n, std::move(__gen)); } template , enable_if_t, 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"); if (!std::__generate_n(__policy, std::move(__first), std::move(__n), std::move(__gen))) std::__throw_bad_alloc(); } template void __pstl_is_partitioned(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional __is_partitioned( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Predicate&& __pred) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { __g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred); if (__g_first == __g_last) return true; ++__g_first; return std::none_of(__policy, __g_first, __g_last, __g_pred); }, std::move(__first), std::move(__last), std::move(__pred)); } template , enable_if_t, 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"); auto __res = std::__is_partitioned(__policy, std::move(__first), std::move(__last), std::move(__pred)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __merge(_ExecutionPolicy&&, _ForwardIterator1&& __first1, _ForwardIterator1&& __last1, _ForwardIterator2&& __first2, _ForwardIterator2&& __last2, _ForwardOutIterator&& __result, _Comp&& __comp) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_merge<_RawPolicy>( _Backend{}, std::forward<_ForwardIterator1>(__first1), std::forward<_ForwardIterator1>(__last1), std::forward<_ForwardIterator2>(__first2), std::forward<_ForwardIterator2>(__last2), std::forward<_ForwardOutIterator>(__result), std::forward<_Comp>(__comp)); } template , class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, enable_if_t, 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"); auto __res = std::__merge( __policy, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::move(__result), std::move(__comp)); if (!__res) std::__throw_bad_alloc(); return *std::move(__res); } // TODO: Use the std::copy/move shenanigans to forward to std::memmove // Investigate whether we want to still forward to std::transform(policy) // in that case for the execution::par part, or whether we actually want // to run everything serially in that case. template void __pstl_move(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __move(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _ForwardOutIterator&& __result) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_move, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result) { return std::__transform(__policy, __g_first, __g_last, __g_result, [](auto&& __v) { return std::move(__v); }); }, std::move(__first), std::move(__last), std::move(__result)); } template , enable_if_t, 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"); auto __res = std::__move(__policy, std::move(__first), std::move(__last), std::move(__result)); if (!__res) std::__throw_bad_alloc(); return *__res; } template void __pstl_replace_if(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_if(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _Pred&& __pred, const _Tp& __new_value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if, _RawPolicy), [&__policy]( _ForwardIterator&& __g_first, _ForwardIterator&& __g_last, _Pred&& __g_pred, const _Tp& __g_new_value) { std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { if (__g_pred(__element)) __element = __g_new_value; }); return optional<__empty>{__empty{}}; }, std::move(__first), std::move(__last), std::move(__pred), __new_value); } template , enable_if_t, 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"); auto __res = std::__replace_if(__policy, std::move(__first), std::move(__last), std::move(__pred), __new_value); if (!__res) std::__throw_bad_alloc(); } template void __pstl_replace(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, const _Tp& __old_value, const _Tp& __new_value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace, _RawPolicy), [&__policy]( _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) { return std::__replace_if( __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, __g_new_value); }, std::forward<_ForwardIterator>(__first), std::forward<_ForwardIterator>(__last), __old_value, __new_value); } template , enable_if_t, 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"); if (!std::__replace(__policy, std::move(__first), std::move(__last), __old_value, __new_value)) std::__throw_bad_alloc(); } template void __pstl_replace_copy_if(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy_if( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _ForwardOutIterator&& __result, _Pred&& __pred, const _Tp& __new_value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result, _Pred __g_pred, const _Tp& __g_new_value) -> optional<__empty> { if (!std::__transform( __policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) { return __g_pred(__element) ? __g_new_value : __element; })) return nullopt; return __empty{}; }, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value); } template , enable_if_t, 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"); if (!std::__replace_copy_if( __policy, std::move(__first), std::move(__last), std::move(__result), std::move(__pred), __new_value)) std::__throw_bad_alloc(); } template void __pstl_replace_copy(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __replace_copy( _ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __last, _ForwardOutIterator&& __result, const _Tp& __old_value, const _Tp& __new_value) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result, const _Tp& __g_old_value, const _Tp& __g_new_value) { return std::__replace_copy_if( __policy, std::move(__g_first), std::move(__g_last), std::move(__g_result), [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, __g_new_value); }, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value); } template , enable_if_t, 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"); if (!std::__replace_copy( __policy, std::move(__first), std::move(__last), std::move(__result), __old_value, __new_value)) std::__throw_bad_alloc(); } template void __pstl_rotate_copy(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> __rotate_copy(_ExecutionPolicy&& __policy, _ForwardIterator&& __first, _ForwardIterator&& __middle, _ForwardIterator&& __last, _ForwardOutIterator&& __result) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_rotate_copy, _RawPolicy), [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_middle, _ForwardIterator __g_last, _ForwardOutIterator __g_result) -> optional<_ForwardOutIterator> { auto __result_mid = std::__copy(__policy, _ForwardIterator(__g_middle), std::move(__g_last), std::move(__g_result)); if (!__result_mid) return nullopt; return std::__copy(__policy, std::move(__g_first), std::move(__g_middle), *std::move(__result_mid)); }, std::move(__first), std::move(__middle), std::move(__last), std::move(__result)); } template , enable_if_t, 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"); auto __res = std::__rotate_copy(__policy, std::move(__first), std::move(__middle), std::move(__last), std::move(__result)); if (!__res) std::__throw_bad_alloc(); return *__res; } template , class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __stable_sort( _ExecutionPolicy&&, _RandomAccessIterator&& __first, _RandomAccessIterator&& __last, _Comp&& __comp = {}) noexcept { using _Backend = typename __select_backend<_RawPolicy>::type; return std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp)); } template , class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, enable_if_t, 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"); if (!std::__stable_sort(__policy, std::move(__first), std::move(__last), std::move(__comp))) std::__throw_bad_alloc(); } template void __pstl_sort(); template , enable_if_t, int> = 0> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<__empty> __sort(_ExecutionPolicy&& __policy, _RandomAccessIterator&& __first, _RandomAccessIterator&& __last, _Comp&& __comp) noexcept { return std::__pstl_frontend_dispatch( _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort, _RawPolicy), [&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) { std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp)); return optional<__empty>{__empty{}}; }, std::forward<_RandomAccessIterator>(__first), std::forward<_RandomAccessIterator>(__last), std::forward<_Comp>(__comp)); } template , enable_if_t, 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"); if (!std::__sort(__policy, std::move(__first), std::move(__last), std::move(__comp))) std::__throw_bad_alloc(); } template , enable_if_t, int> = 0> _LIBCPP_HIDE_FROM_ABI void sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) { _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators"); if (!std::__sort(__policy, std::move(__first), std::move(__last), less{})) std::__throw_bad_alloc(); } _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 _LIBCPP_POP_MACROS #endif // _LIBCPP___ALGORITHM_PSTL_H