single_view.h 3.0 KB

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