You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
5.2KB

  1. // Range v3 library
  2. //
  3. // Copyright Casey Carter 2018
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. #ifndef RANGES_V3_DETAIL_ADL_GET_HPP
  12. #define RANGES_V3_DETAIL_ADL_GET_HPP
  13. #include <cstddef>
  14. #include <concepts/concepts.hpp>
  15. #include <range/v3/range_fwd.hpp>
  16. namespace ranges
  17. {
  18. /// \cond
  19. namespace detail
  20. {
  21. namespace _adl_get_
  22. {
  23. template<typename>
  24. void get();
  25. template<std::size_t I, typename TupleLike>
  26. constexpr auto adl_get(TupleLike && t) noexcept
  27. -> decltype(get<I>(static_cast<TupleLike &&>(t)))
  28. {
  29. return get<I>(static_cast<TupleLike &&>(t));
  30. }
  31. template<typename T, typename TupleLike>
  32. constexpr auto adl_get(TupleLike && t) noexcept
  33. -> decltype(get<T>(static_cast<TupleLike &&>(t)))
  34. {
  35. return get<T>(static_cast<TupleLike &&>(t));
  36. }
  37. } // namespace _adl_get_
  38. using _adl_get_::adl_get;
  39. } // namespace detail
  40. namespace _tuple_wrapper_
  41. {
  42. template<typename TupleLike>
  43. struct forward_tuple_interface : TupleLike
  44. {
  45. forward_tuple_interface() = default;
  46. using TupleLike::TupleLike;
  47. #if !defined(__clang__) || __clang_major__ > 3
  48. CPP_member
  49. constexpr CPP_ctor(forward_tuple_interface)(TupleLike && base)( //
  50. noexcept(std::is_nothrow_move_constructible<TupleLike>::value) //
  51. requires move_constructible<TupleLike>)
  52. : TupleLike(static_cast<TupleLike &&>(base))
  53. {}
  54. CPP_member
  55. constexpr CPP_ctor(forward_tuple_interface)(TupleLike const & base)( //
  56. noexcept(std::is_nothrow_copy_constructible<TupleLike>::value) //
  57. requires copy_constructible<TupleLike>)
  58. : TupleLike(base)
  59. {}
  60. #else
  61. // Clang 3.x have a problem with inheriting constructors
  62. // that causes the declarations in the preceeding PP block to get
  63. // instantiated too early.
  64. CPP_template(typename B = TupleLike)( //
  65. requires move_constructible<B>) //
  66. constexpr forward_tuple_interface(TupleLike && base) noexcept(
  67. std::is_nothrow_move_constructible<TupleLike>::value)
  68. : TupleLike(static_cast<TupleLike &&>(base))
  69. {}
  70. CPP_template(typename B = TupleLike)( //
  71. requires copy_constructible<B>) //
  72. constexpr forward_tuple_interface(TupleLike const & base) noexcept(
  73. std::is_nothrow_copy_constructible<TupleLike>::value)
  74. : TupleLike(base)
  75. {}
  76. #endif
  77. // clang-format off
  78. template<std::size_t I, typename U = TupleLike>
  79. friend constexpr auto CPP_auto_fun(get)(
  80. forward_tuple_interface<TupleLike> &wb)
  81. (
  82. return detail::adl_get<I>(static_cast<U &>(wb))
  83. )
  84. template<std::size_t I, typename U = TupleLike>
  85. friend constexpr auto CPP_auto_fun(get)(
  86. forward_tuple_interface<TupleLike> const &wb)
  87. (
  88. return detail::adl_get<I>(static_cast<U const &>(wb))
  89. )
  90. template<std::size_t I, typename U = TupleLike>
  91. friend constexpr auto CPP_auto_fun(get)(
  92. forward_tuple_interface<TupleLike> &&wb)
  93. (
  94. return detail::adl_get<I>(static_cast<U &&>(wb))
  95. )
  96. template<std::size_t I, typename U = TupleLike>
  97. friend constexpr auto CPP_auto_fun(get)(
  98. forward_tuple_interface<TupleLike> const &&wb)
  99. (
  100. return detail::adl_get<I>(static_cast<U const &&>(wb))
  101. )
  102. template<typename T, typename U = TupleLike>
  103. friend constexpr auto CPP_auto_fun(get)(
  104. forward_tuple_interface<TupleLike> &wb)
  105. (
  106. return detail::adl_get<T>(static_cast<U &>(wb))
  107. )
  108. template<typename T, typename U = TupleLike>
  109. friend constexpr auto CPP_auto_fun(get)(
  110. forward_tuple_interface<TupleLike> const &wb)
  111. (
  112. return detail::adl_get<T>(static_cast<U const &>(wb))
  113. )
  114. template<typename T, typename U = TupleLike>
  115. friend constexpr auto CPP_auto_fun(get)(
  116. forward_tuple_interface<TupleLike> &&wb)
  117. (
  118. return detail::adl_get<T>(static_cast<U &&>(wb))
  119. )
  120. template<typename T, typename U = TupleLike>
  121. friend constexpr auto CPP_auto_fun(get)(
  122. forward_tuple_interface<TupleLike> const &&wb)
  123. (
  124. return detail::adl_get<T>(static_cast<U const &&>(wb))
  125. )
  126. // clang-format on
  127. };
  128. } // namespace _tuple_wrapper_
  129. /// \endcond
  130. } // namespace ranges
  131. #endif // RANGES_V3_DETAIL_ADL_GET_HPP