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.

single.hpp 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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_VIEW_SINGLE_HPP
  14. #define RANGES_V3_VIEW_SINGLE_HPP
  15. #include <type_traits>
  16. #include <utility>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/iterator/concepts.hpp>
  19. #include <range/v3/iterator/traits.hpp>
  20. #include <range/v3/range/access.hpp>
  21. #include <range/v3/range/concepts.hpp>
  22. #include <range/v3/range/traits.hpp>
  23. #include <range/v3/utility/addressof.hpp>
  24. #include <range/v3/utility/optional.hpp>
  25. #include <range/v3/utility/semiregular_box.hpp>
  26. #include <range/v3/utility/static_const.hpp>
  27. #include <range/v3/view/facade.hpp>
  28. namespace ranges
  29. {
  30. /// \addtogroup group-views
  31. /// @{
  32. template<typename T>
  33. struct single_view : view_interface<single_view<T>, (cardinality)1>
  34. {
  35. private:
  36. CPP_assert(copy_constructible<T>);
  37. static_assert(std::is_object<T>::value,
  38. "The template parameter of single_view must be an object type");
  39. semiregular_box_t<T> value_;
  40. template<typename... Args>
  41. constexpr single_view(in_place_t, std::true_type, Args &&... args)
  42. : value_{static_cast<Args &&>(args)...}
  43. {}
  44. template<typename... Args>
  45. constexpr single_view(in_place_t, std::false_type, Args &&... args)
  46. : value_{in_place, static_cast<Args &&>(args)...}
  47. {}
  48. public:
  49. single_view() = default;
  50. constexpr explicit single_view(T const & t)
  51. : value_(t)
  52. {}
  53. constexpr explicit single_view(T && t)
  54. : value_(std::move(t))
  55. {}
  56. CPP_template(class... Args)( //
  57. requires constructible_from<T, Args...>) //
  58. constexpr single_view(in_place_t, Args &&... args)
  59. : single_view{in_place,
  60. meta::bool_<(bool)semiregular<T>>{},
  61. static_cast<Args &&>(args)...}
  62. {}
  63. constexpr T * begin() noexcept
  64. {
  65. return data();
  66. }
  67. constexpr T const * begin() const noexcept
  68. {
  69. return data();
  70. }
  71. constexpr T * end() noexcept
  72. {
  73. return data() + 1;
  74. }
  75. constexpr T const * end() const noexcept
  76. {
  77. return data() + 1;
  78. }
  79. constexpr static std::size_t size() noexcept
  80. {
  81. return 1u;
  82. }
  83. constexpr T * data() noexcept
  84. {
  85. return detail::addressof(static_cast<T &>(value_));
  86. }
  87. constexpr T const * data() const noexcept
  88. {
  89. return detail::addressof(static_cast<T const &>(value_));
  90. }
  91. };
  92. #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
  93. template<class T>
  94. explicit single_view(T &&)->single_view<detail::decay_t<T>>;
  95. #endif
  96. namespace views
  97. {
  98. struct single_fn
  99. {
  100. template<typename Val>
  101. auto operator()(Val value) const -> CPP_ret(single_view<Val>)( //
  102. requires copy_constructible<Val>)
  103. {
  104. return single_view<Val>{std::move(value)};
  105. }
  106. };
  107. /// \relates single_fn
  108. /// \ingroup group-views
  109. RANGES_INLINE_VARIABLE(single_fn, single)
  110. } // namespace views
  111. namespace cpp20
  112. {
  113. namespace views
  114. {
  115. using ranges::views::single;
  116. }
  117. CPP_template(typename T)( //
  118. requires std::is_object<T>::value) //
  119. using single_view = ranges::single_view<T>;
  120. } // namespace cpp20
  121. /// @}
  122. } // namespace ranges
  123. #include <range/v3/detail/satisfy_boost_range.hpp>
  124. RANGES_SATISFY_BOOST_RANGE(::ranges::single_view)
  125. #endif