1349cc55cSDimitry Andric // -*- C++ -*-
2349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
3349cc55cSDimitry Andric //
4349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7349cc55cSDimitry Andric //
8349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
9bdd1243dSDimitry Andric 
10349cc55cSDimitry Andric #ifndef _LIBCPP___RANGES_SINGLE_VIEW_H
11349cc55cSDimitry Andric #define _LIBCPP___RANGES_SINGLE_VIEW_H
12349cc55cSDimitry Andric 
13bdd1243dSDimitry Andric #include <__concepts/constructible.h>
14349cc55cSDimitry Andric #include <__config>
1506c3fb27SDimitry Andric #include <__ranges/movable_box.h>
1681ad6265SDimitry Andric #include <__ranges/range_adaptor.h>
1704eeddc0SDimitry Andric #include <__ranges/view_interface.h>
1806c3fb27SDimitry Andric #include <__type_traits/decay.h>
1906c3fb27SDimitry Andric #include <__type_traits/is_object.h>
20349cc55cSDimitry Andric #include <__utility/forward.h>
21349cc55cSDimitry Andric #include <__utility/in_place.h>
22349cc55cSDimitry Andric #include <__utility/move.h>
2306c3fb27SDimitry Andric #include <cstddef>
24349cc55cSDimitry Andric 
25349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26349cc55cSDimitry Andric #  pragma GCC system_header
27349cc55cSDimitry Andric #endif
28349cc55cSDimitry Andric 
29*b3edf446SDimitry Andric _LIBCPP_PUSH_MACROS
30*b3edf446SDimitry Andric #include <__undef_macros>
31*b3edf446SDimitry Andric 
32349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
33349cc55cSDimitry Andric 
3406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
35349cc55cSDimitry Andric 
36349cc55cSDimitry Andric namespace ranges {
3706c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 23
3806c3fb27SDimitry Andric template <move_constructible _Tp>
3906c3fb27SDimitry Andric #  else
40349cc55cSDimitry Andric template <copy_constructible _Tp>
4106c3fb27SDimitry Andric #  endif
42349cc55cSDimitry Andric   requires is_object_v<_Tp>
437a6dacacSDimitry Andric class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS single_view : public view_interface<single_view<_Tp>> {
44647cbc5dSDimitry Andric   _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_;
45349cc55cSDimitry Andric 
46349cc55cSDimitry Andric public:
4706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI single_view()
4806c3fb27SDimitry Andric     requires default_initializable<_Tp>
4906c3fb27SDimitry Andric   = default;
50349cc55cSDimitry Andric 
single_view(const _Tp & __t)5106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
5206c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 23
5306c3fb27SDimitry Andric     requires copy_constructible<_Tp>
5406c3fb27SDimitry Andric #  endif
5506c3fb27SDimitry Andric       : __value_(in_place, __t) {
5606c3fb27SDimitry Andric   }
57349cc55cSDimitry Andric 
single_view(_Tp && __t)5806c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
59349cc55cSDimitry Andric 
60349cc55cSDimitry Andric   template <class... _Args>
61349cc55cSDimitry Andric     requires constructible_from<_Tp, _Args...>
single_view(in_place_t,_Args &&...__args)6206c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
6381ad6265SDimitry Andric       : __value_{in_place, std::forward<_Args>(__args)...} {}
64349cc55cSDimitry Andric 
begin()6506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
66349cc55cSDimitry Andric 
begin()6706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
68349cc55cSDimitry Andric 
end()6906c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
70349cc55cSDimitry Andric 
end()7106c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
72349cc55cSDimitry Andric 
size()7306c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
74349cc55cSDimitry Andric 
data()7506c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
76349cc55cSDimitry Andric 
data()7706c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
78349cc55cSDimitry Andric };
79349cc55cSDimitry Andric 
80349cc55cSDimitry Andric template <class _Tp>
81349cc55cSDimitry Andric single_view(_Tp) -> single_view<_Tp>;
8281ad6265SDimitry Andric 
8381ad6265SDimitry Andric namespace views {
8481ad6265SDimitry Andric namespace __single_view {
8581ad6265SDimitry Andric 
8681ad6265SDimitry Andric struct __fn : __range_adaptor_closure<__fn> {
8781ad6265SDimitry Andric   template <class _Range>
88cb14a3feSDimitry Andric   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
8981ad6265SDimitry Andric       noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
90cb14a3feSDimitry Andric           -> decltype(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))) {
91cb14a3feSDimitry Andric     return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range));
92cb14a3feSDimitry Andric   }
9381ad6265SDimitry Andric };
9481ad6265SDimitry Andric } // namespace __single_view
9581ad6265SDimitry Andric 
9681ad6265SDimitry Andric inline namespace __cpo {
9781ad6265SDimitry Andric inline constexpr auto single = __single_view::__fn{};
9881ad6265SDimitry Andric } // namespace __cpo
9981ad6265SDimitry Andric 
10081ad6265SDimitry Andric } // namespace views
101349cc55cSDimitry Andric } // namespace ranges
102349cc55cSDimitry Andric 
10306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
104349cc55cSDimitry Andric 
105349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD
106349cc55cSDimitry Andric 
107*b3edf446SDimitry Andric _LIBCPP_POP_MACROS
108*b3edf446SDimitry Andric 
109349cc55cSDimitry Andric #endif // _LIBCPP___RANGES_SINGLE_VIEW_H
110