181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric #ifndef _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H 1081ad6265SDimitry Andric #define _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H 1181ad6265SDimitry Andric 1281ad6265SDimitry Andric #include <__algorithm/in_in_out_result.h> 1381ad6265SDimitry Andric #include <__algorithm/in_out_result.h> 1481ad6265SDimitry Andric #include <__concepts/constructible.h> 1581ad6265SDimitry Andric #include <__config> 1681ad6265SDimitry Andric #include <__functional/identity.h> 1781ad6265SDimitry Andric #include <__functional/invoke.h> 1881ad6265SDimitry Andric #include <__iterator/concepts.h> 1981ad6265SDimitry Andric #include <__iterator/projected.h> 2081ad6265SDimitry Andric #include <__ranges/access.h> 2181ad6265SDimitry Andric #include <__ranges/concepts.h> 2281ad6265SDimitry Andric #include <__ranges/dangling.h> 2381ad6265SDimitry Andric #include <__utility/move.h> 2481ad6265SDimitry Andric 2581ad6265SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2681ad6265SDimitry Andric # pragma GCC system_header 2781ad6265SDimitry Andric #endif 2881ad6265SDimitry Andric 29*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS 30*b3edf446SDimitry Andric #include <__undef_macros> 31*b3edf446SDimitry Andric 3206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 3381ad6265SDimitry Andric 3481ad6265SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 3581ad6265SDimitry Andric 3681ad6265SDimitry Andric namespace ranges { 3781ad6265SDimitry Andric 3881ad6265SDimitry Andric template <class _Ip, class _Op> 3981ad6265SDimitry Andric using unary_transform_result = in_out_result<_Ip, _Op>; 4081ad6265SDimitry Andric 4181ad6265SDimitry Andric template <class _I1, class _I2, class _O1> 4281ad6265SDimitry Andric using binary_transform_result = in_in_out_result<_I1, _I2, _O1>; 4381ad6265SDimitry Andric 4481ad6265SDimitry Andric namespace __transform { 4581ad6265SDimitry Andric struct __fn { 4681ad6265SDimitry Andric private: 4706c3fb27SDimitry Andric template <class _InIter, class _Sent, class _OutIter, class _Func, class _Proj> 4806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter> __unary__fn4906c3fb27SDimitry Andric __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) { 5081ad6265SDimitry Andric while (__first != __last) { 5181ad6265SDimitry Andric *__result = std::invoke(__operation, std::invoke(__projection, *__first)); 5281ad6265SDimitry Andric ++__first; 5381ad6265SDimitry Andric ++__result; 5481ad6265SDimitry Andric } 5581ad6265SDimitry Andric 5681ad6265SDimitry Andric return {std::move(__first), std::move(__result)}; 5781ad6265SDimitry Andric } 5881ad6265SDimitry Andric 5906c3fb27SDimitry Andric template <class _InIter1, 6006c3fb27SDimitry Andric class _Sent1, 6106c3fb27SDimitry Andric class _InIter2, 6206c3fb27SDimitry Andric class _Sent2, 6381ad6265SDimitry Andric class _OutIter, 6481ad6265SDimitry Andric class _Func, 6581ad6265SDimitry Andric class _Proj1, 6681ad6265SDimitry Andric class _Proj2> 6781ad6265SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> __binary__fn6806c3fb27SDimitry Andric __binary(_InIter1 __first1, 6906c3fb27SDimitry Andric _Sent1 __last1, 7006c3fb27SDimitry Andric _InIter2 __first2, 7106c3fb27SDimitry Andric _Sent2 __last2, 7281ad6265SDimitry Andric _OutIter __result, 7381ad6265SDimitry Andric _Func& __binary_operation, 7481ad6265SDimitry Andric _Proj1& __projection1, 7581ad6265SDimitry Andric _Proj2& __projection2) { 7681ad6265SDimitry Andric while (__first1 != __last1 && __first2 != __last2) { 7706c3fb27SDimitry Andric *__result = 7806c3fb27SDimitry Andric std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2)); 7981ad6265SDimitry Andric ++__first1; 8081ad6265SDimitry Andric ++__first2; 8181ad6265SDimitry Andric ++__result; 8281ad6265SDimitry Andric } 8381ad6265SDimitry Andric return {std::move(__first1), std::move(__first2), std::move(__result)}; 8481ad6265SDimitry Andric } 8506c3fb27SDimitry Andric 8681ad6265SDimitry Andric public: 8706c3fb27SDimitry Andric template <input_iterator _InIter, 8806c3fb27SDimitry Andric sentinel_for<_InIter> _Sent, 8981ad6265SDimitry Andric weakly_incrementable _OutIter, 9081ad6265SDimitry Andric copy_constructible _Func, 9181ad6265SDimitry Andric class _Proj = identity> 9281ad6265SDimitry Andric requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>> 9306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<_InIter, _OutIter> operator__fn9406c3fb27SDimitry Andric operator()(_InIter __first, _Sent __last, _OutIter __result, _Func __operation, _Proj __proj = {}) const { 9581ad6265SDimitry Andric return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj); 9681ad6265SDimitry Andric } 9781ad6265SDimitry Andric 9806c3fb27SDimitry Andric template <input_range _Range, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj = identity> 9981ad6265SDimitry Andric requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected<iterator_t<_Range>, _Proj>>> 10006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> operator__fn10106c3fb27SDimitry Andric operator()(_Range&& __range, _OutIter __result, _Func __operation, _Proj __projection = {}) const { 10281ad6265SDimitry Andric return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection); 10381ad6265SDimitry Andric } 10481ad6265SDimitry Andric 10506c3fb27SDimitry Andric template <input_iterator _InIter1, 10606c3fb27SDimitry Andric sentinel_for<_InIter1> _Sent1, 10706c3fb27SDimitry Andric input_iterator _InIter2, 10806c3fb27SDimitry Andric sentinel_for<_InIter2> _Sent2, 10981ad6265SDimitry Andric weakly_incrementable _OutIter, 11081ad6265SDimitry Andric copy_constructible _Func, 11181ad6265SDimitry Andric class _Proj1 = identity, 11281ad6265SDimitry Andric class _Proj2 = identity> 11306c3fb27SDimitry Andric requires indirectly_writable<_OutIter, 11406c3fb27SDimitry Andric indirect_result_t<_Func&, projected<_InIter1, _Proj1>, projected<_InIter2, _Proj2>>> operator__fn11506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> operator()( 11606c3fb27SDimitry Andric _InIter1 __first1, 11706c3fb27SDimitry Andric _Sent1 __last1, 11806c3fb27SDimitry Andric _InIter2 __first2, 11906c3fb27SDimitry Andric _Sent2 __last2, 12081ad6265SDimitry Andric _OutIter __result, 12181ad6265SDimitry Andric _Func __binary_operation, 12281ad6265SDimitry Andric _Proj1 __projection1 = {}, 12381ad6265SDimitry Andric _Proj2 __projection2 = {}) const { 12406c3fb27SDimitry Andric return __binary( 12506c3fb27SDimitry Andric std::move(__first1), 12606c3fb27SDimitry Andric std::move(__last1), 12706c3fb27SDimitry Andric std::move(__first2), 12806c3fb27SDimitry Andric std::move(__last2), 12981ad6265SDimitry Andric std::move(__result), 13081ad6265SDimitry Andric __binary_operation, 13181ad6265SDimitry Andric __projection1, 13281ad6265SDimitry Andric __projection2); 13381ad6265SDimitry Andric } 13481ad6265SDimitry Andric 13581ad6265SDimitry Andric template <input_range _Range1, 13681ad6265SDimitry Andric input_range _Range2, 13781ad6265SDimitry Andric weakly_incrementable _OutIter, 13881ad6265SDimitry Andric copy_constructible _Func, 13981ad6265SDimitry Andric class _Proj1 = identity, 14081ad6265SDimitry Andric class _Proj2 = identity> 14106c3fb27SDimitry Andric requires indirectly_writable< 14206c3fb27SDimitry Andric _OutIter, 14306c3fb27SDimitry Andric indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>> 14406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<borrowed_iterator_t<_Range1>, 14506c3fb27SDimitry Andric borrowed_iterator_t<_Range2>, 14606c3fb27SDimitry Andric _OutIter> operator__fn14781ad6265SDimitry Andric operator()(_Range1&& __range1, 14881ad6265SDimitry Andric _Range2&& __range2, 14981ad6265SDimitry Andric _OutIter __result, 15081ad6265SDimitry Andric _Func __binary_operation, 15181ad6265SDimitry Andric _Proj1 __projection1 = {}, 15281ad6265SDimitry Andric _Proj2 __projection2 = {}) const { 15306c3fb27SDimitry Andric return __binary( 15406c3fb27SDimitry Andric ranges::begin(__range1), 15506c3fb27SDimitry Andric ranges::end(__range1), 15606c3fb27SDimitry Andric ranges::begin(__range2), 15706c3fb27SDimitry Andric ranges::end(__range2), 15881ad6265SDimitry Andric std::move(__result), 15981ad6265SDimitry Andric __binary_operation, 16081ad6265SDimitry Andric __projection1, 16181ad6265SDimitry Andric __projection2); 16281ad6265SDimitry Andric } 16381ad6265SDimitry Andric }; 16481ad6265SDimitry Andric } // namespace __transform 16581ad6265SDimitry Andric 16681ad6265SDimitry Andric inline namespace __cpo { 16781ad6265SDimitry Andric inline constexpr auto transform = __transform::__fn{}; 16881ad6265SDimitry Andric } // namespace __cpo 16981ad6265SDimitry Andric } // namespace ranges 17081ad6265SDimitry Andric 17181ad6265SDimitry Andric _LIBCPP_END_NAMESPACE_STD 17281ad6265SDimitry Andric 17306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 17481ad6265SDimitry Andric 175*b3edf446SDimitry Andric _LIBCPP_POP_MACROS 176*b3edf446SDimitry Andric 17781ad6265SDimitry Andric #endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H 178