1fe6060f1SDimitry Andric // -*- C++ -*- 2349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9bdd1243dSDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___RANGES_DATA_H 11fe6060f1SDimitry Andric #define _LIBCPP___RANGES_DATA_H 12fe6060f1SDimitry Andric 1304eeddc0SDimitry Andric #include <__concepts/class_or_enum.h> 14fe6060f1SDimitry Andric #include <__config> 15fe6060f1SDimitry Andric #include <__iterator/concepts.h> 16fe6060f1SDimitry Andric #include <__iterator/iterator_traits.h> 17fe6060f1SDimitry Andric #include <__memory/pointer_traits.h> 18fe6060f1SDimitry Andric #include <__ranges/access.h> 19bdd1243dSDimitry Andric #include <__type_traits/decay.h> 20bdd1243dSDimitry Andric #include <__type_traits/is_object.h> 21bdd1243dSDimitry Andric #include <__type_traits/is_pointer.h> 22bdd1243dSDimitry Andric #include <__type_traits/is_reference.h> 23bdd1243dSDimitry Andric #include <__type_traits/remove_pointer.h> 24bdd1243dSDimitry Andric #include <__type_traits/remove_reference.h> 2504eeddc0SDimitry Andric #include <__utility/auto_cast.h> 26fe6060f1SDimitry Andric 27fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 28fe6060f1SDimitry Andric # pragma GCC system_header 29fe6060f1SDimitry Andric #endif 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 32fe6060f1SDimitry Andric 3306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 34fe6060f1SDimitry Andric 35fe6060f1SDimitry Andric // [range.prim.data] 360eae32dcSDimitry Andric 370eae32dcSDimitry Andric namespace ranges { 38fe6060f1SDimitry Andric namespace __data { 39fe6060f1SDimitry Andric template <class _Tp> 40fe6060f1SDimitry Andric concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>; 41fe6060f1SDimitry Andric 42fe6060f1SDimitry Andric template <class _Tp> requires(_Tp && __t)43*0fca6ea1SDimitry Andricconcept __member_data = __can_borrow<_Tp> && requires(_Tp&& __t) { 4404eeddc0SDimitry Andric { _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object; 45fe6060f1SDimitry Andric }; 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric template <class _Tp> 48cb14a3feSDimitry Andric concept __ranges_begin_invocable = !__member_data<_Tp> && __can_borrow<_Tp> && requires(_Tp&& __t) { 4904eeddc0SDimitry Andric { ranges::begin(__t) } -> contiguous_iterator; 50fe6060f1SDimitry Andric }; 51fe6060f1SDimitry Andric 52fe6060f1SDimitry Andric struct __fn { 53fe6060f1SDimitry Andric template <__member_data _Tp> operator__fn54cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(__t.data())) { 55fe6060f1SDimitry Andric return __t.data(); 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric template <__ranges_begin_invocable _Tp> operator__fn59cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const 6081ad6265SDimitry Andric noexcept(noexcept(std::to_address(ranges::begin(__t)))) { 6181ad6265SDimitry Andric return std::to_address(ranges::begin(__t)); 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric }; 641fd87a68SDimitry Andric } // namespace __data 65fe6060f1SDimitry Andric 66fe6060f1SDimitry Andric inline namespace __cpo { 67349cc55cSDimitry Andric inline constexpr auto data = __data::__fn{}; 68fe6060f1SDimitry Andric } // namespace __cpo 69fe6060f1SDimitry Andric } // namespace ranges 70fe6060f1SDimitry Andric 7104eeddc0SDimitry Andric // [range.prim.cdata] 7204eeddc0SDimitry Andric 7304eeddc0SDimitry Andric namespace ranges { 7404eeddc0SDimitry Andric namespace __cdata { 7504eeddc0SDimitry Andric struct __fn { 7604eeddc0SDimitry Andric template <class _Tp> 7704eeddc0SDimitry Andric requires is_lvalue_reference_v<_Tp&&> 78cb14a3feSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const 7904eeddc0SDimitry Andric noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))) 80cb14a3feSDimitry Andric -> decltype(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))) { 81cb14a3feSDimitry Andric return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); 82cb14a3feSDimitry Andric } 8304eeddc0SDimitry Andric 8404eeddc0SDimitry Andric template <class _Tp> 8504eeddc0SDimitry Andric requires is_rvalue_reference_v<_Tp&&> 86*0fca6ea1SDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept( 87*0fca6ea1SDimitry Andric noexcept(ranges::data(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::data(static_cast<const _Tp&&>(__t))) { 88cb14a3feSDimitry Andric return ranges::data(static_cast<const _Tp&&>(__t)); 89cb14a3feSDimitry Andric } 9004eeddc0SDimitry Andric }; 911fd87a68SDimitry Andric } // namespace __cdata 9204eeddc0SDimitry Andric 9304eeddc0SDimitry Andric inline namespace __cpo { 9404eeddc0SDimitry Andric inline constexpr auto cdata = __cdata::__fn{}; 9504eeddc0SDimitry Andric } // namespace __cpo 9604eeddc0SDimitry Andric } // namespace ranges 9704eeddc0SDimitry Andric 9806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 99fe6060f1SDimitry Andric 100fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric #endif // _LIBCPP___RANGES_DATA_H 103