single_view.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. #ifndef _LIBCPP___RANGES_SINGLE_VIEW_H
  10. #define _LIBCPP___RANGES_SINGLE_VIEW_H
  11. #include <__concepts/constructible.h>
  12. #include <__config>
  13. #include <__ranges/movable_box.h>
  14. #include <__ranges/range_adaptor.h>
  15. #include <__ranges/view_interface.h>
  16. #include <__type_traits/decay.h>
  17. #include <__type_traits/is_object.h>
  18. #include <__utility/forward.h>
  19. #include <__utility/in_place.h>
  20. #include <__utility/move.h>
  21. #include <cstddef>
  22. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  23. # pragma GCC system_header
  24. #endif
  25. _LIBCPP_BEGIN_NAMESPACE_STD
  26. #if _LIBCPP_STD_VER >= 20
  27. namespace ranges {
  28. # if _LIBCPP_STD_VER >= 23
  29. template <move_constructible _Tp>
  30. # else
  31. template <copy_constructible _Tp>
  32. # endif
  33. requires is_object_v<_Tp>
  34. class single_view : public view_interface<single_view<_Tp>> {
  35. __movable_box<_Tp> __value_;
  36. public:
  37. _LIBCPP_HIDE_FROM_ABI single_view()
  38. requires default_initializable<_Tp>
  39. = default;
  40. _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
  41. # if _LIBCPP_STD_VER >= 23
  42. requires copy_constructible<_Tp>
  43. # endif
  44. : __value_(in_place, __t) {
  45. }
  46. _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
  47. template <class... _Args>
  48. requires constructible_from<_Tp, _Args...>
  49. _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
  50. : __value_{in_place, std::forward<_Args>(__args)...} {}
  51. _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
  52. _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
  53. _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
  54. _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
  55. _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
  56. _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
  57. _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
  58. };
  59. template<class _Tp>
  60. single_view(_Tp) -> single_view<_Tp>;
  61. namespace views {
  62. namespace __single_view {
  63. struct __fn : __range_adaptor_closure<__fn> {
  64. template<class _Range>
  65. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
  66. constexpr auto operator()(_Range&& __range) const
  67. noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
  68. -> decltype( single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))
  69. { return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); }
  70. };
  71. } // namespace __single_view
  72. inline namespace __cpo {
  73. inline constexpr auto single = __single_view::__fn{};
  74. } // namespace __cpo
  75. } // namespace views
  76. } // namespace ranges
  77. #endif // _LIBCPP_STD_VER >= 20
  78. _LIBCPP_END_NAMESPACE_STD
  79. #endif // _LIBCPP___RANGES_SINGLE_VIEW_H