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