traits.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Eric Niebler 2013-present
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. #ifndef RANGES_V3_ITERATOR_TRAITS_HPP
  14. #define RANGES_V3_ITERATOR_TRAITS_HPP
  15. #include <iterator>
  16. #include <type_traits>
  17. #include <meta/meta.hpp>
  18. #include <concepts/concepts.hpp>
  19. #include <range/v3/range_fwd.hpp>
  20. #include <range/v3/iterator/access.hpp> // for iter_move, iter_swap
  21. #include <range/v3/utility/common_type.hpp>
  22. #include <range/v3/detail/prologue.hpp>
  23. namespace ranges
  24. {
  25. /// \addtogroup group-iterator
  26. /// @{
  27. /// \cond
  28. using input_iterator_tag RANGES_DEPRECATED(
  29. "Please switch to the standard iterator tags") = std::input_iterator_tag;
  30. using forward_iterator_tag RANGES_DEPRECATED(
  31. "Please switch to the standard iterator tags") = std::forward_iterator_tag;
  32. using bidirectional_iterator_tag RANGES_DEPRECATED(
  33. "Please switch to the standard iterator tags") = std::bidirectional_iterator_tag;
  34. using random_access_iterator_tag RANGES_DEPRECATED(
  35. "Please switch to the standard iterator tags") = std::random_access_iterator_tag;
  36. /// \endcond
  37. struct contiguous_iterator_tag : std::random_access_iterator_tag
  38. {};
  39. /// \cond
  40. namespace detail
  41. {
  42. template<typename I, typename = iter_reference_t<I>,
  43. typename R = decltype(iter_move(std::declval<I &>())), typename = R &>
  44. using iter_rvalue_reference_t = R;
  45. template<typename I>
  46. RANGES_INLINE_VAR constexpr bool has_nothrow_iter_move_v =
  47. noexcept(iter_rvalue_reference_t<I>(ranges::iter_move(std::declval<I &>())));
  48. } // namespace detail
  49. /// \endcond
  50. template<typename I>
  51. using iter_rvalue_reference_t = detail::iter_rvalue_reference_t<I>;
  52. template<typename I>
  53. using iter_common_reference_t =
  54. common_reference_t<iter_reference_t<I>, iter_value_t<I> &>;
  55. #if defined(RANGES_DEEP_STL_INTEGRATION) && RANGES_DEEP_STL_INTEGRATION && \
  56. !defined(RANGES_DOXYGEN_INVOKED)
  57. template<typename T>
  58. using iter_difference_t =
  59. typename meta::conditional_t<detail::is_std_iterator_traits_specialized_v<T>,
  60. std::iterator_traits<uncvref_t<T>>,
  61. incrementable_traits<uncvref_t<T>>>::difference_type;
  62. #else
  63. template<typename T>
  64. using iter_difference_t =
  65. typename incrementable_traits<uncvref_t<T>>::difference_type;
  66. #endif
  67. // Defined in <range/v3/iterator/access.hpp>
  68. // template<typename T>
  69. // using iter_value_t = ...
  70. // Defined in <range/v3/iterator/access.hpp>
  71. // template<typename R>
  72. // using iter_reference_t = detail::iter_reference_t_<R>;
  73. // Defined in <range/v3/range_fwd.hpp>:
  74. // template<typename S, typename I>
  75. // inline constexpr bool disable_sized_sentinel = false;
  76. /// \cond
  77. namespace detail
  78. {
  79. template<typename I>
  80. using iter_size_t =
  81. meta::_t<meta::conditional_t<std::is_integral<iter_difference_t<I>>::value,
  82. std::make_unsigned<iter_difference_t<I>>,
  83. meta::id<iter_difference_t<I>>>>;
  84. template<typename I>
  85. using iter_arrow_t = decltype(std::declval<I &>().operator->());
  86. template<typename I>
  87. using iter_pointer_t =
  88. meta::_t<meta::conditional_t<
  89. meta::is_trait<meta::defer<iter_arrow_t, I>>::value,
  90. meta::defer<iter_arrow_t, I>,
  91. std::add_pointer<iter_reference_t<I>>>>;
  92. template<typename T>
  93. struct difference_type_ : meta::defer<iter_difference_t, T>
  94. {};
  95. template<typename T>
  96. struct value_type_ : meta::defer<iter_value_t, T>
  97. {};
  98. template<typename T>
  99. struct size_type_ : meta::defer<iter_size_t, T>
  100. {};
  101. } // namespace detail
  102. template<typename T>
  103. using difference_type_t RANGES_DEPRECATED(
  104. "ranges::difference_type_t is deprecated. Please use "
  105. "ranges::iter_difference_t instead.") = iter_difference_t<T>;
  106. template<typename T>
  107. using value_type_t RANGES_DEPRECATED(
  108. "ranges::value_type_t is deprecated. Please use "
  109. "ranges::iter_value_t instead.") = iter_value_t<T>;
  110. template<typename R>
  111. using reference_t RANGES_DEPRECATED(
  112. "ranges::reference_t is deprecated. Use ranges::iter_reference_t "
  113. "instead.") = iter_reference_t<R>;
  114. template<typename I>
  115. using rvalue_reference_t RANGES_DEPRECATED(
  116. "rvalue_reference_t is deprecated; "
  117. "use iter_rvalue_reference_t instead") = iter_rvalue_reference_t<I>;
  118. template<typename T>
  119. struct RANGES_DEPRECATED(
  120. "ranges::size_type is deprecated. Iterators do not have an associated "
  121. "size_type.") size_type : detail::size_type_<T>
  122. {};
  123. template<typename I>
  124. using size_type_t RANGES_DEPRECATED("size_type_t is deprecated.") =
  125. detail::iter_size_t<I>;
  126. /// \endcond
  127. namespace cpp20
  128. {
  129. using ranges::iter_common_reference_t;
  130. using ranges::iter_difference_t;
  131. using ranges::iter_reference_t;
  132. using ranges::iter_rvalue_reference_t;
  133. using ranges::iter_value_t;
  134. // Specialize these in the ranges:: namespace
  135. using ranges::disable_sized_sentinel;
  136. template<typename T>
  137. using incrementable_traits = ranges::incrementable_traits<T>;
  138. template<typename T>
  139. using indirectly_readable_traits = ranges::indirectly_readable_traits<T>;
  140. } // namespace cpp20
  141. /// @}
  142. } // namespace ranges
  143. #include <range/v3/detail/epilogue.hpp>
  144. #endif // RANGES_V3_ITERATOR_TRAITS_HPP