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.

132 lines
4.1KB

  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_RANGE_TRAITS_HPP
  14. #define RANGES_V3_RANGE_TRAITS_HPP
  15. #include <array>
  16. #include <iterator>
  17. #include <type_traits>
  18. #include <utility>
  19. #include <meta/meta.hpp>
  20. #include <range/v3/range_fwd.hpp>
  21. #include <range/v3/range/access.hpp>
  22. #include <range/v3/range/primitives.hpp>
  23. namespace ranges
  24. {
  25. /// \cond
  26. namespace detail
  27. {
  28. template<typename I, typename S>
  29. using common_iterator_impl_t =
  30. enable_if_t<(bool)(input_or_output_iterator<I> && sentinel_for<S, I>),
  31. common_iterator<I, S>>;
  32. }
  33. /// \endcond
  34. /// \addtogroup group-range
  35. /// @{
  36. template<typename I, typename S>
  37. using common_iterator_t = detail::if_then_t<std::is_same<I, S>::value, I,
  38. detail::common_iterator_impl_t<I, S>>;
  39. /// \cond
  40. namespace detail
  41. {
  42. template<typename I, typename S>
  43. using cpp17_iterator_t =
  44. if_then_t<std::is_integral<iter_difference_t<I>>::value,
  45. common_iterator_t<I, S>, cpp17_iterator<common_iterator_t<I, S>>>;
  46. }
  47. /// \endcond
  48. // Aliases (SFINAE-able)
  49. template<typename Rng>
  50. using range_difference_t = iter_difference_t<iterator_t<Rng>>;
  51. template<typename Rng>
  52. using range_value_t = iter_value_t<iterator_t<Rng>>;
  53. template<typename Rng>
  54. using range_reference_t = iter_reference_t<iterator_t<Rng>>;
  55. template<typename Rng>
  56. using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<Rng>>;
  57. template<typename Rng>
  58. using range_common_reference_t = iter_common_reference_t<iterator_t<Rng>>;
  59. template<typename Rng>
  60. using range_size_t = decltype(ranges::size(std::declval<Rng &>()));
  61. /// \cond
  62. template<typename Rng>
  63. using range_difference_type_t RANGES_DEPRECATED(
  64. "range_difference_type_t is deprecated. Use the range_difference_t instead.") =
  65. iter_difference_t<iterator_t<Rng>>;
  66. template<typename Rng>
  67. using range_value_type_t RANGES_DEPRECATED(
  68. "range_value_type_t is deprecated. Use the range_value_t instead.") =
  69. iter_value_t<iterator_t<Rng>>;
  70. template<typename Rng>
  71. using range_category_t RANGES_DEPRECATED(
  72. "range_category_t is deprecated. Use the range concepts instead.") =
  73. meta::_t<detail::iterator_category<iterator_t<Rng>>>;
  74. template<typename Rng>
  75. using range_size_type_t RANGES_DEPRECATED(
  76. "range_size_type_t is deprecated. Use range_size_t instead.") =
  77. detail::iter_size_t<iterator_t<Rng>>;
  78. /// \endcond
  79. template<typename Rng>
  80. using range_common_iterator_t = common_iterator_t<iterator_t<Rng>, sentinel_t<Rng>>;
  81. /// \cond
  82. namespace detail
  83. {
  84. template<typename Rng>
  85. using range_cpp17_iterator_t = cpp17_iterator_t<iterator_t<Rng>, sentinel_t<Rng>>;
  86. std::integral_constant<cardinality, finite> test_cardinality(void *);
  87. template<cardinality Card>
  88. std::integral_constant<cardinality, Card> test_cardinality(basic_view<Card> *);
  89. template<typename T, std::size_t N>
  90. std::integral_constant<cardinality, static_cast<cardinality>(N)> test_cardinality(
  91. T (*)[N]);
  92. template<typename T, std::size_t N>
  93. std::integral_constant<cardinality, static_cast<cardinality>(N)> test_cardinality(
  94. std::array<T, N> *);
  95. } // namespace detail
  96. /// \endcond
  97. // User customization point for specifying the cardinality of ranges:
  98. template<typename Rng, typename Void /*= void*/>
  99. struct range_cardinality
  100. : detail::if_then_t<RANGES_IS_SAME(Rng, uncvref_t<Rng>),
  101. decltype(detail::test_cardinality(
  102. static_cast<uncvref_t<Rng> *>(nullptr))),
  103. range_cardinality<uncvref_t<Rng>>>
  104. {};
  105. /// @}
  106. } // namespace ranges
  107. #endif