diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv --- a/libcxx/docs/Status/RangesPaper.csv +++ b/libcxx/docs/Status/RangesPaper.csv @@ -142,7 +142,7 @@ `[range.take] `_,take_view,[range.all],Zoe Carver,In Progress `[range.join] `_,join_view,[range.all],Christopher Di Bella,Not started `[range.empty] `_,`empty_view `_,[view.interface],Zoe Carver,✅ -`[range.single] `_,single_view,[view.interface],Zoe Carver,In Progress +`[range.single] `_,single_view,[view.interface],Zoe Carver,✅ `[range.split] `_,split_view,[range.all],Unassigned,Not started `[range.counted] `_,view::counted,[range.subrange],Zoe Carver,Not started `[range.common] `_,common_view,[range.all],Zoe Carver,✅ diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -197,6 +197,7 @@ __ranges/enable_view.h __ranges/non_propagating_cache.h __ranges/ref_view.h + __ranges/single_view.h __ranges/size.h __ranges/subrange.h __ranges/transform_view.h diff --git a/libcxx/include/__ranges/copyable_box.h b/libcxx/include/__ranges/copyable_box.h --- a/libcxx/include/__ranges/copyable_box.h +++ b/libcxx/include/__ranges/copyable_box.h @@ -91,6 +91,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); } + _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); } + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); } }; @@ -162,6 +166,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return _VSTD::addressof(__val_); } + _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return _VSTD::addressof(__val_); } + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; } }; } // namespace ranges diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__ranges/single_view.h @@ -0,0 +1,83 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef _LIBCPP___RANGES_SINGLE_VIEW_H +#define _LIBCPP___RANGES_SINGLE_VIEW_H + +#include <__config> +#include <__ranges/view_interface.h> +#include <__ranges/copyable_box.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template + requires is_object_v<_Tp> + class single_view : public view_interface> { + __copyable_box<_Tp> __value_; + + public: + _LIBCPP_HIDE_FROM_ABI + single_view() requires default_initializable<_Tp> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit single_view(_Tp&& __t) : __value_(in_place, _VSTD::move(__t)) {} + + template + requires constructible_from<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI + constexpr explicit single_view(in_place_t, _Args&&... __args) + : __value_{in_place, _VSTD::forward<_Args>(__args)...} {} + + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp* begin() noexcept { return data(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr const _Tp* begin() const noexcept { return data(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp* end() noexcept { return data() + 1; } + + _LIBCPP_HIDE_FROM_ABI + constexpr const _Tp* end() const noexcept { return data() + 1; } + + _LIBCPP_HIDE_FROM_ABI + static constexpr size_t size() noexcept { return 1; } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp* data() noexcept { return __value_.operator->(); } + + _LIBCPP_HIDE_FROM_ABI + constexpr const _Tp* data() const noexcept { return __value_.operator->(); } + }; + + template + single_view(_Tp) -> single_view<_Tp>; +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_SINGLE_VIEW_H diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -627,6 +627,7 @@ module non_propagating_cache { private header "__ranges/non_propagating_cache.h" } module ref_view { private header "__ranges/ref_view.h" } module size { private header "__ranges/size.h" } + module single_view { private header "__ranges/single_view.h" } module subrange { private header "__ranges/subrange.h" } module transform_view { private header "__ranges/transform_view.h" } module view_interface { private header "__ranges/view_interface.h" } diff --git a/libcxx/include/ranges b/libcxx/include/ranges --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -156,6 +156,10 @@ template inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + + template + requires is_object_v + class single_view; } */ @@ -173,6 +177,7 @@ #include <__ranges/enable_borrowed_range.h> #include <__ranges/enable_view.h> #include <__ranges/ref_view.h> +#include <__ranges/single_view.h> #include <__ranges/size.h> #include <__ranges/subrange.h> #include <__ranges/transform_view.h> diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/ranges/single_view.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/ranges/single_view.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/ranges/single_view.module.verify.cpp @@ -0,0 +1,16 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: modules-build + +// WARNING: This test was generated by 'generate_private_header_tests.py' +// and should not be edited manually. + +// expected-error@*:* {{use of private header from outside its module: '__ranges/single_view.h'}} +#include <__ranges/single_view.h> diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// T* ::operator->() +// const T* ::operator->() const + +#include + +#include +#include +#include // in_place_t + +#include "types.h" + +template +constexpr void check() { + // non-const version + { + std::ranges::__copyable_box x(std::in_place, 10); + T* result = x.operator->(); + static_assert(noexcept(x.operator->())); + assert(result->value == 10); + assert(x->value == 10); + } + + // const version + { + std::ranges::__copyable_box const x(std::in_place, 10); + const T* result = x.operator->(); + static_assert(noexcept(x.operator->())); + assert(result->value == 10); + assert(x->value == 10); + } +} + +constexpr bool test() { + check(); // primary template + check(); // optimization #1 + check(); // optimization #2 + return true; +} + +int main(int, char**) { + assert(test()); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/size.pass.cpp @@ -32,6 +32,10 @@ constexpr size_t size() { return 42; } }; +struct StaticSizeMember { + constexpr static size_t size() { return 42; } +}; + static_assert(!std::is_invocable_v); struct SizeFunction { @@ -82,6 +86,9 @@ assert(std::ranges::size(SizeMemberSigned()) == 42); ASSERT_SAME_TYPE(decltype(std::ranges::size(SizeMemberSigned())), long); + assert(std::ranges::size(StaticSizeMember()) == 42); + ASSERT_SAME_TYPE(decltype(std::ranges::size(StaticSizeMember())), size_t); + return true; } diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/assign.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/assign.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/assign.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10, gcc-11 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// Tests that is a . + +#include +#include + +#include "test_macros.h" + +struct NotAssignable { + NotAssignable() = default; + NotAssignable(const NotAssignable&) = default; + NotAssignable(NotAssignable&&) = default; + + NotAssignable& operator=(const NotAssignable&) = delete; + NotAssignable& operator=(NotAssignable&&) = delete; +}; + +constexpr bool test() { + const std::ranges::single_view a; + std::ranges::single_view b; + b = a; + b = std::move(a); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/begin.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/begin.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/begin.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// constexpr T* begin() noexcept; +// constexpr const T* begin() const noexcept; + +#include +#include + +#include "test_macros.h" + +struct Empty {}; +struct BigType { char buffer[64] = {10}; }; + +constexpr bool test() { + { + auto sv = std::ranges::single_view(42); + assert(*sv.begin() == 42); + + ASSERT_SAME_TYPE(decltype(sv.begin()), int*); + static_assert(noexcept(sv.begin())); + } + { + const auto sv = std::ranges::single_view(42); + assert(*sv.begin() == 42); + + ASSERT_SAME_TYPE(decltype(sv.begin()), const int*); + static_assert(noexcept(sv.begin())); + } + + { + auto sv = std::ranges::single_view(Empty()); + assert(sv.begin() != nullptr); + + ASSERT_SAME_TYPE(decltype(sv.begin()), Empty*); + } + { + const auto sv = std::ranges::single_view(Empty()); + assert(sv.begin() != nullptr); + + ASSERT_SAME_TYPE(decltype(sv.begin()), const Empty*); + } + + { + auto sv = std::ranges::single_view(BigType()); + assert(sv.begin()->buffer[0] == 10); + + ASSERT_SAME_TYPE(decltype(sv.begin()), BigType*); + } + { + const auto sv = std::ranges::single_view(BigType()); + assert(sv.begin()->buffer[0] == 10); + + ASSERT_SAME_TYPE(decltype(sv.begin()), const BigType*); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/ctad.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/ctad.compile.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// template +// single_view(T) -> single_view; + +#include + +#include +#include + +#include "test_iterators.h" + +struct Empty {}; + +static_assert(std::same_as< + decltype(std::ranges::single_view(Empty())), + std::ranges::single_view +>); + +static_assert(std::same_as< + decltype(std::ranges::single_view(std::declval())), + std::ranges::single_view +>); + +static_assert(std::same_as< + decltype(std::ranges::single_view(std::declval())), + std::ranges::single_view +>); diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.default.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.default.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// single_view() requires default_initializable = default; + +#include +#include + +#include "test_macros.h" + +struct BigType { char buffer[64] = {10}; }; + +template +struct IsDefaultConstructible { + IsDefaultConstructible() requires DefaultCtorEnabled = default; +}; + +constexpr bool test() { + static_assert( std::default_initializable>>); + static_assert(!std::default_initializable>>); + + { + std::ranges::single_view sv; + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + { + const std::ranges::single_view sv; + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/ctor.in_place.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.in_place.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.in_place.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// template +// requires constructible_from +// constexpr explicit single_view(in_place_t, Args&&... args); + +#include +#include + +#include "test_macros.h" + +struct TakesTwoInts { + int a_, b_; + constexpr TakesTwoInts(int a, int b) : a_(a), b_(b) {} +}; + +constexpr bool test() { + { + std::ranges::single_view sv(std::in_place, 1, 2); + assert(sv.data()->a_ == 1); + assert(sv.data()->b_ == 2); + assert(sv.size() == 1); + } + { + const std::ranges::single_view sv(std::in_place, 1, 2); + assert(sv.data()->a_ == 1); + assert(sv.data()->b_ == 2); + assert(sv.size() == 1); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/ctor.value.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.value.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/ctor.value.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// constexpr explicit single_view(const T& t); +// constexpr explicit single_view(T&& t); + +#include +#include + +#include "test_macros.h" + +struct Empty {}; +struct BigType { char buffer[64] = {10}; }; + +constexpr bool test() { + { + BigType bt; + std::ranges::single_view sv(bt); + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + { + const BigType bt; + const std::ranges::single_view sv(bt); + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + + { + BigType bt; + std::ranges::single_view sv(std::move(bt)); + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + { + const BigType bt; + const std::ranges::single_view sv(std::move(bt)); + assert(sv.data()->buffer[0] == 10); + assert(sv.size() == 1); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/data.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/data.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/data.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// constexpr T* data() noexcept; +// constexpr const T* data() const noexcept; + +#include +#include + +#include "test_macros.h" + +struct Empty {}; +struct BigType { char buffer[64] = {10}; }; + +constexpr bool test() { + { + auto sv = std::ranges::single_view(42); + assert(*sv.data() == 42); + + ASSERT_SAME_TYPE(decltype(sv.data()), int*); + static_assert(noexcept(sv.data())); + } + { + const auto sv = std::ranges::single_view(42); + assert(*sv.data() == 42); + + ASSERT_SAME_TYPE(decltype(sv.data()), const int*); + static_assert(noexcept(sv.data())); + } + + { + auto sv = std::ranges::single_view(Empty()); + assert(sv.data() != nullptr); + + ASSERT_SAME_TYPE(decltype(sv.data()), Empty*); + } + { + const auto sv = std::ranges::single_view(Empty()); + assert(sv.data() != nullptr); + + ASSERT_SAME_TYPE(decltype(sv.data()), const Empty*); + } + + { + auto sv = std::ranges::single_view(BigType()); + assert(sv.data()->buffer[0] == 10); + + ASSERT_SAME_TYPE(decltype(sv.data()), BigType*); + } + { + const auto sv = std::ranges::single_view(BigType()); + assert(sv.data()->buffer[0] == 10); + + ASSERT_SAME_TYPE(decltype(sv.data()), const BigType*); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/end.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/end.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/end.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// constexpr T* end() noexcept; +// constexpr const T* end() const noexcept; + +#include +#include + +#include "test_macros.h" + +struct Empty {}; +struct BigType { char buffer[64] = {10}; }; + +constexpr bool test() { + { + auto sv = std::ranges::single_view(42); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), int*); + static_assert(noexcept(sv.end())); + } + { + const auto sv = std::ranges::single_view(42); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), const int*); + static_assert(noexcept(sv.end())); + } + + { + auto sv = std::ranges::single_view(Empty()); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), Empty*); + } + { + const auto sv = std::ranges::single_view(Empty()); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), const Empty*); + } + + { + auto sv = std::ranges::single_view(BigType()); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), BigType*); + } + { + const auto sv = std::ranges::single_view(BigType()); + assert(sv.end() == sv.begin() + 1); + + ASSERT_SAME_TYPE(decltype(sv.end()), const BigType*); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/range_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/range_concept_conformance.compile.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// Test that single_view conforms to range and view concepts. + +#include + +#include +#include + +#include "test_iterators.h" + +struct Empty {}; + +static_assert(std::ranges::contiguous_range>); +static_assert(std::ranges::contiguous_range>); +static_assert(std::ranges::view>); +static_assert(std::ranges::view>); +static_assert(std::ranges::contiguous_range>); +static_assert(std::ranges::view>); +static_assert(std::ranges::view>); +static_assert(std::ranges::contiguous_range>); diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/size.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/size.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.factories/range.single.view/size.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 +// UNSUPPORTED: libcpp-has-no-incomplete-ranges + +// static constexpr size_t size() noexcept; + +#include +#include + +#include "test_macros.h" + +constexpr bool test() { + { + auto sv = std::ranges::single_view(42); + assert(sv.size() == 1); + + ASSERT_SAME_TYPE(decltype(sv.size()), size_t); + static_assert(noexcept(sv.size())); + } + { + const auto sv = std::ranges::single_view(42); + assert(sv.size() == 1); + + ASSERT_SAME_TYPE(decltype(sv.size()), size_t); + static_assert(noexcept(sv.size())); + } + { + auto sv = std::ranges::single_view(42); + assert(std::ranges::size(sv) == 1); + + ASSERT_SAME_TYPE(decltype(std::ranges::size(sv)), size_t); + static_assert(noexcept(std::ranges::size(sv))); + } + { + const auto sv = std::ranges::single_view(42); + assert(std::ranges::size(sv) == 1); + + ASSERT_SAME_TYPE(decltype(std::ranges::size(sv)), size_t); + static_assert(noexcept(std::ranges::size(sv))); + } + + // Test that it's static. + { + assert(std::ranges::single_view::size() == 1); + + ASSERT_SAME_TYPE(decltype(std::ranges::single_view::size()), size_t); + static_assert(noexcept(std::ranges::single_view::size())); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +}