data.h 3.1 KB

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