158b29a4eSLouis Dionne // -*- C++ -*- 258b29a4eSLouis Dionne //===----------------------------------------------------------------------===// 358b29a4eSLouis Dionne // 458b29a4eSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 558b29a4eSLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 658b29a4eSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 758b29a4eSLouis Dionne // 858b29a4eSLouis Dionne //===----------------------------------------------------------------------===// 9480cd780SLouis Dionne 1058b29a4eSLouis Dionne #ifndef _LIBCPP___ITERATOR_PROJECTED_H 1158b29a4eSLouis Dionne #define _LIBCPP___ITERATOR_PROJECTED_H 1258b29a4eSLouis Dionne 1358b29a4eSLouis Dionne #include <__config> 1458b29a4eSLouis Dionne #include <__iterator/concepts.h> 154d08eccdSLouis Dionne #include <__iterator/incrementable_traits.h> // iter_difference_t 16430b397fSNikolas Klauser #include <__type_traits/remove_cvref.h> 1758b29a4eSLouis Dionne 1858b29a4eSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1958b29a4eSLouis Dionne # pragma GCC system_header 2058b29a4eSLouis Dionne #endif 2158b29a4eSLouis Dionne 2258b29a4eSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 2358b29a4eSLouis Dionne 244f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 2558b29a4eSLouis Dionne 264d08eccdSLouis Dionne template <class _It, class _Proj> 274d08eccdSLouis Dionne struct __projected_impl { 284d08eccdSLouis Dionne struct __type { 29*f6958523SNikolas Klauser using __primary_template _LIBCPP_NODEBUG = __type; 30*f6958523SNikolas Klauser using __projected_iterator _LIBCPP_NODEBUG = _It; 31*f6958523SNikolas Klauser using __projected_projection _LIBCPP_NODEBUG = _Proj; 32026210e8SA. Jiang 3358b29a4eSLouis Dionne using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>; 3458b29a4eSLouis Dionne indirect_result_t<_Proj&, _It> operator*() const; // not defined 3558b29a4eSLouis Dionne }; 364d08eccdSLouis Dionne }; 3758b29a4eSLouis Dionne 3858b29a4eSLouis Dionne template <weakly_incrementable _It, class _Proj> 394d08eccdSLouis Dionne struct __projected_impl<_It, _Proj> { 404d08eccdSLouis Dionne struct __type { 41*f6958523SNikolas Klauser using __primary_template _LIBCPP_NODEBUG = __type; 42*f6958523SNikolas Klauser using __projected_iterator _LIBCPP_NODEBUG = _It; 43*f6958523SNikolas Klauser using __projected_projection _LIBCPP_NODEBUG = _Proj; 44026210e8SA. Jiang 454d08eccdSLouis Dionne using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>; 4658b29a4eSLouis Dionne using difference_type = iter_difference_t<_It>; 474d08eccdSLouis Dionne indirect_result_t<_Proj&, _It> operator*() const; // not defined 4858b29a4eSLouis Dionne }; 494d08eccdSLouis Dionne }; 504d08eccdSLouis Dionne 514d08eccdSLouis Dionne // Note that we implement std::projected in a way that satisfies P2538R1 even in standard 524d08eccdSLouis Dionne // modes before C++26 to avoid breaking the ABI between standard modes (even though ABI 534d08eccdSLouis Dionne // breaks with std::projected are expected to have essentially no impact). 544d08eccdSLouis Dionne template <indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj> 554d08eccdSLouis Dionne using projected = typename __projected_impl<_It, _Proj>::__type; 5658b29a4eSLouis Dionne 574f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 5858b29a4eSLouis Dionne 5958b29a4eSLouis Dionne _LIBCPP_END_NAMESPACE_STD 6058b29a4eSLouis Dionne 6158b29a4eSLouis Dionne #endif // _LIBCPP___ITERATOR_PROJECTED_H 62