xref: /llvm-project/libcxx/include/__iterator/projected.h (revision f69585235ec85d54e0f3fc41b2d5700430907f99)
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