1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___RANGES_SINGLE_VIEW_H 11 #define _LIBCPP___RANGES_SINGLE_VIEW_H 12 13 #include <__concepts/constructible.h> 14 #include <__config> 15 #include <__ranges/movable_box.h> 16 #include <__ranges/range_adaptor.h> 17 #include <__ranges/view_interface.h> 18 #include <__type_traits/decay.h> 19 #include <__type_traits/is_object.h> 20 #include <__utility/forward.h> 21 #include <__utility/in_place.h> 22 #include <__utility/move.h> 23 #include <cstddef> 24 25 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26 # pragma GCC system_header 27 #endif 28 29 _LIBCPP_BEGIN_NAMESPACE_STD 30 31 #if _LIBCPP_STD_VER >= 20 32 33 namespace ranges { 34 # if _LIBCPP_STD_VER >= 23 35 template <move_constructible _Tp> 36 # else 37 template <copy_constructible _Tp> 38 # endif 39 requires is_object_v<_Tp> 40 class _LIBCPP_ABI_2023_OVERLAPPING_SUBOBJECT_FIX_TAG single_view : public view_interface<single_view<_Tp>> { 41 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_; 42 43 public: 44 _LIBCPP_HIDE_FROM_ABI single_view() 45 requires default_initializable<_Tp> 46 = default; 47 48 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t) 49 # if _LIBCPP_STD_VER >= 23 50 requires copy_constructible<_Tp> 51 # endif 52 : __value_(in_place, __t) { 53 } 54 55 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {} 56 57 template <class... _Args> 58 requires constructible_from<_Tp, _Args...> 59 _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args) 60 : __value_{in_place, std::forward<_Args>(__args)...} {} 61 62 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); } 63 64 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); } 65 66 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; } 67 68 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; } 69 70 _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; } 71 72 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); } 73 74 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); } 75 }; 76 77 template <class _Tp> 78 single_view(_Tp) -> single_view<_Tp>; 79 80 namespace views { 81 namespace __single_view { 82 83 struct __fn : __range_adaptor_closure<__fn> { 84 template <class _Range> 85 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const 86 noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))) 87 -> decltype(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))) { 88 return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); 89 } 90 }; 91 } // namespace __single_view 92 93 inline namespace __cpo { 94 inline constexpr auto single = __single_view::__fn{}; 95 } // namespace __cpo 96 97 } // namespace views 98 } // namespace ranges 99 100 #endif // _LIBCPP_STD_VER >= 20 101 102 _LIBCPP_END_NAMESPACE_STD 103 104 #endif // _LIBCPP___RANGES_SINGLE_VIEW_H 105