1*4d6fc14bSjoerg // -*- C++ -*- 2*4d6fc14bSjoerg //===------------------------ __ranges/data.h ------------------------------===// 3*4d6fc14bSjoerg // 4*4d6fc14bSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg // See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg // 8*4d6fc14bSjoerg //===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg #ifndef _LIBCPP___RANGES_DATA_H 10*4d6fc14bSjoerg #define _LIBCPP___RANGES_DATA_H 11*4d6fc14bSjoerg 12*4d6fc14bSjoerg #include <__config> 13*4d6fc14bSjoerg #include <__iterator/concepts.h> 14*4d6fc14bSjoerg #include <__iterator/iterator_traits.h> 15*4d6fc14bSjoerg #include <__ranges/access.h> 16*4d6fc14bSjoerg #include <concepts> 17*4d6fc14bSjoerg #include <type_traits> 18*4d6fc14bSjoerg 19*4d6fc14bSjoerg #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20*4d6fc14bSjoerg #pragma GCC system_header 21*4d6fc14bSjoerg #endif 22*4d6fc14bSjoerg 23*4d6fc14bSjoerg _LIBCPP_PUSH_MACROS 24*4d6fc14bSjoerg #include <__undef_macros> 25*4d6fc14bSjoerg 26*4d6fc14bSjoerg _LIBCPP_BEGIN_NAMESPACE_STD 27*4d6fc14bSjoerg 28*4d6fc14bSjoerg #if !defined(_LIBCPP_HAS_NO_RANGES) 29*4d6fc14bSjoerg 30*4d6fc14bSjoerg // clang-format off 31*4d6fc14bSjoerg namespace ranges { 32*4d6fc14bSjoerg // [range.prim.data] 33*4d6fc14bSjoerg namespace __data { 34*4d6fc14bSjoerg template <class _Tp> 35*4d6fc14bSjoerg concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>; 36*4d6fc14bSjoerg 37*4d6fc14bSjoerg template <class _Tp> 38*4d6fc14bSjoerg concept __member_data = requires(_Tp && __t)39*4d6fc14bSjoerg requires(_Tp&& __t) { 40*4d6fc14bSjoerg { _VSTD::forward<_Tp>(__t) } -> __can_borrow; 41*4d6fc14bSjoerg { __t.data() } -> __ptr_to_object; 42*4d6fc14bSjoerg }; 43*4d6fc14bSjoerg 44*4d6fc14bSjoerg template <class _Tp> 45*4d6fc14bSjoerg concept __ranges_begin_invocable = 46*4d6fc14bSjoerg !__member_data<_Tp> && 47*4d6fc14bSjoerg requires(_Tp&& __t) { 48*4d6fc14bSjoerg { _VSTD::forward<_Tp>(__t) } -> __can_borrow; 49*4d6fc14bSjoerg { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator; 50*4d6fc14bSjoerg }; 51*4d6fc14bSjoerg 52*4d6fc14bSjoerg struct __fn { 53*4d6fc14bSjoerg template <__member_data _Tp> 54*4d6fc14bSjoerg requires __can_borrow<_Tp> operator__fn55*4d6fc14bSjoerg constexpr __ptr_to_object auto operator()(_Tp&& __t) const 56*4d6fc14bSjoerg noexcept(noexcept(__t.data())) { 57*4d6fc14bSjoerg return __t.data(); 58*4d6fc14bSjoerg } 59*4d6fc14bSjoerg 60*4d6fc14bSjoerg template<__ranges_begin_invocable _Tp> 61*4d6fc14bSjoerg requires __can_borrow<_Tp> operator__fn62*4d6fc14bSjoerg constexpr __ptr_to_object auto operator()(_Tp&& __t) const 63*4d6fc14bSjoerg noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) { 64*4d6fc14bSjoerg return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))); 65*4d6fc14bSjoerg } 66*4d6fc14bSjoerg }; 67*4d6fc14bSjoerg } // end namespace __data 68*4d6fc14bSjoerg 69*4d6fc14bSjoerg inline namespace __cpo { 70*4d6fc14bSjoerg inline constexpr const auto data = __data::__fn{}; 71*4d6fc14bSjoerg } // namespace __cpo 72*4d6fc14bSjoerg } // namespace ranges 73*4d6fc14bSjoerg 74*4d6fc14bSjoerg // clang-format off 75*4d6fc14bSjoerg 76*4d6fc14bSjoerg #endif // !defined(_LIBCPP_HAS_NO_RANGES) 77*4d6fc14bSjoerg 78*4d6fc14bSjoerg _LIBCPP_END_NAMESPACE_STD 79*4d6fc14bSjoerg 80*4d6fc14bSjoerg _LIBCPP_POP_MACROS 81*4d6fc14bSjoerg 82*4d6fc14bSjoerg #endif // _LIBCPP___RANGES_DATA_H 83