single.hpp 3.9 KB

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