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/copyable_box.h>
16#include <__ranges/range_adaptor.h>
17#include <__ranges/view_interface.h>
18#include <__utility/forward.h>
19#include <__utility/in_place.h>
20#include <__utility/move.h>
21#include <type_traits>
22
23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24#  pragma GCC system_header
25#endif
26
27_LIBCPP_BEGIN_NAMESPACE_STD
28
29#if _LIBCPP_STD_VER > 17
30
31namespace ranges {
32  template<copy_constructible _Tp>
33    requires is_object_v<_Tp>
34  class single_view : public view_interface<single_view<_Tp>> {
35    __copyable_box<_Tp> __value_;
36
37  public:
38    _LIBCPP_HIDE_FROM_ABI
39    single_view() requires default_initializable<_Tp> = default;
40
41    _LIBCPP_HIDE_FROM_ABI
42    constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
43
44    _LIBCPP_HIDE_FROM_ABI
45    constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
46
47    template<class... _Args>
48      requires constructible_from<_Tp, _Args...>
49    _LIBCPP_HIDE_FROM_ABI
50    constexpr explicit single_view(in_place_t, _Args&&... __args)
51      : __value_{in_place, std::forward<_Args>(__args)...} {}
52
53    _LIBCPP_HIDE_FROM_ABI
54    constexpr _Tp* begin() noexcept { return data(); }
55
56    _LIBCPP_HIDE_FROM_ABI
57    constexpr const _Tp* begin() const noexcept { return data(); }
58
59    _LIBCPP_HIDE_FROM_ABI
60    constexpr _Tp* end() noexcept { return data() + 1; }
61
62    _LIBCPP_HIDE_FROM_ABI
63    constexpr const _Tp* end() const noexcept { return data() + 1; }
64
65    _LIBCPP_HIDE_FROM_ABI
66    static constexpr size_t size() noexcept { return 1; }
67
68    _LIBCPP_HIDE_FROM_ABI
69    constexpr _Tp* data() noexcept { return __value_.operator->(); }
70
71    _LIBCPP_HIDE_FROM_ABI
72    constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
73  };
74
75template<class _Tp>
76single_view(_Tp) -> single_view<_Tp>;
77
78namespace views {
79namespace __single_view {
80
81struct __fn : __range_adaptor_closure<__fn> {
82  template<class _Range>
83  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
84  constexpr auto operator()(_Range&& __range) const
85    noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
86    -> decltype(      single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))
87    { return          single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); }
88};
89} // namespace __single_view
90
91inline namespace __cpo {
92  inline constexpr auto single = __single_view::__fn{};
93} // namespace __cpo
94
95} // namespace views
96} // namespace ranges
97
98#endif // _LIBCPP_STD_VER > 17
99
100_LIBCPP_END_NAMESPACE_STD
101
102#endif // _LIBCPP___RANGES_SINGLE_VIEW_H
103