diff --git a/libcxx/docs/OneRangesProposalStatus.csv b/libcxx/docs/OneRangesProposalStatus.csv --- a/libcxx/docs/OneRangesProposalStatus.csv +++ b/libcxx/docs/OneRangesProposalStatus.csv @@ -53,7 +53,7 @@ [range.iota],iota_view,[range.all],Louis Dionne,, [range.take],take_view,[range.all],Zoe Carver,, [range.join],join_view,[range.all],Christopher Di Bella,, -[range.empty],empty_view,[view.interface],Zoe Carver,, +[range.empty],empty_view,[view.interface],Zoe Carver,,✅ [range.single],single_view,[view.interface],,, [range.split],split_view,[range.all],,, [range.counted],view::counted,[range.subrange],,, diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -122,6 +122,7 @@ __ranges/concepts.h __ranges/data.h __ranges/empty.h + __ranges/empty_view.h __ranges/enable_borrowed_range.h __ranges/view_interface.h __ranges/view.h diff --git a/libcxx/include/__ranges/empty_view.h b/libcxx/include/__ranges/empty_view.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__ranges/empty_view.h @@ -0,0 +1,45 @@ +// -*- 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_EMPTY_VIEW_H +#define _LIBCPP___RANGES_EMPTY_VIEW_H + +#include <__config> +#include <__ranges/view_interface.h> + +#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 empty_view : public view_interface> { + public: + static constexpr _Tp* begin() noexcept { return nullptr; } + static constexpr _Tp* end() noexcept { return nullptr; } + static constexpr _Tp* data() noexcept { return nullptr; } + static constexpr size_t size() noexcept { return 0; } + static constexpr bool empty() noexcept { return true; } + }; +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_EMPTY_VIEW_H diff --git a/libcxx/include/ranges b/libcxx/include/ranges --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -83,6 +83,11 @@ template requires is_class_v && same_as> class view_interface; + + // [range.empty], empty view + template + requires is_object_v + class empty_view; } */ @@ -92,6 +97,7 @@ #include <__ranges/concepts.h> #include <__ranges/data.h> #include <__ranges/empty.h> +#include <__ranges/empty_view.h> #include <__ranges/enable_borrowed_range.h> #include <__ranges/size.h> #include <__ranges/view_interface.h> diff --git a/libcxx/test/std/ranges/range.adaptors/range.empty/empty_view.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.empty/empty_view.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.empty/empty_view.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// class empty_view; + +#include +#include + +#include "test_macros.h" + +template +constexpr void testType() { + static_assert(std::ranges::range>); + static_assert(std::ranges::range>); + static_assert(std::ranges::view>); + + std::ranges::empty_view empty; + + assert(empty.begin() == nullptr); + assert(empty.end() == nullptr); + assert(empty.data() == nullptr); + assert(empty.size() == 0); + assert(empty.empty() == true); + + assert(std::ranges::begin(empty) == nullptr); + assert(std::ranges::end(empty) == nullptr); + assert(std::ranges::data(empty) == nullptr); + assert(std::ranges::size(empty) == 0); + assert(std::ranges::empty(empty) == true); +} + +struct Empty {}; +struct BigType { char buff[8]; }; + +template +concept ValidEmptyView = requires { typename std::ranges::empty_view; }; + +constexpr bool test() { + // Not objects: + static_assert(!ValidEmptyView); + static_assert(!ValidEmptyView); + + testType(); + testType(); + testType(); + testType(); + testType(); + testType(); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +}