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 @@ -17,7 +17,7 @@ | *no-throw-input-range* | *no-throw-forward-iterator* | *no-throw-forward-range*","| [iterator.concepts] -| [range.refinements]",Konstantin Varlamov,Not started +| [range.refinements]",Konstantin Varlamov,✅ `[specialized.algorithms] `_,"| ranges::uninitialized_default_construct | ranges::uninitialized_default_construct_n | ranges::uninitialized_value_construct diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -228,6 +228,7 @@ __memory/allocator.h __memory/auto_ptr.h __memory/compressed_pair.h + __memory/concepts.h __memory/construct_at.h __memory/pointer_traits.h __memory/raw_storage_iterator.h diff --git a/libcxx/include/__memory/concepts.h b/libcxx/include/__memory/concepts.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__memory/concepts.h @@ -0,0 +1,66 @@ +// -*- 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___MEMORY_CONCEPTS_H +#define _LIBCPP___MEMORY_CONCEPTS_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) +namespace ranges { + +// [special.mem.concepts] + +// This concept ensures that uninitialized algorithms can construct an object +// at the address pointed-to by the iterator, which requires an lvalue. +template +concept __nothrow_input_iterator = + input_iterator<_Ip> && + is_lvalue_reference_v> && + same_as>, iter_value_t<_Ip>>; + +template +concept __nothrow_sentinel_for = sentinel_for<_Sp, _Ip>; + +template +concept __nothrow_input_range = + range<_Rp> && + __nothrow_input_iterator> && + __nothrow_sentinel_for, iterator_t<_Rp>>; + +template +concept __nothrow_forward_iterator = + __nothrow_input_iterator<_Ip> && + forward_iterator<_Ip> && + __nothrow_sentinel_for<_Ip, _Ip>; + +template +concept __nothrow_forward_range = + __nothrow_input_range<_Rp> && + __nothrow_forward_iterator>; + +} // namespace ranges +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MEMORY_CONCEPTS_H diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -669,6 +669,7 @@ #include <__memory/allocator_arg_t.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> +#include <__memory/concepts.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__memory/raw_storage_iterator.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -630,21 +630,22 @@ export * module __memory { - module addressof { private header "__memory/addressof.h" } - module allocation_guard { private header "__memory/allocation_guard.h" } - module allocator { private header "__memory/allocator.h" } - module allocator_arg_t { private header "__memory/allocator_arg_t.h" } - module allocator_traits { private header "__memory/allocator_traits.h" } - module auto_ptr { private header "__memory/auto_ptr.h" } - module compressed_pair { private header "__memory/compressed_pair.h" } - module construct_at { private header "__memory/construct_at.h" } - module pointer_traits { private header "__memory/pointer_traits.h" } - module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } - module shared_ptr { private header "__memory/shared_ptr.h" } - module temporary_buffer { private header "__memory/temporary_buffer.h" } + module addressof { private header "__memory/addressof.h" } + module allocation_guard { private header "__memory/allocation_guard.h" } + module allocator { private header "__memory/allocator.h" } + module allocator_arg_t { private header "__memory/allocator_arg_t.h" } + module allocator_traits { private header "__memory/allocator_traits.h" } + module auto_ptr { private header "__memory/auto_ptr.h" } + module compressed_pair { private header "__memory/compressed_pair.h" } + module concepts { private header "__memory/concepts.h" } + module construct_at { private header "__memory/construct_at.h" } + module pointer_traits { private header "__memory/pointer_traits.h" } + module raw_storage_iterator { private header "__memory/raw_storage_iterator.h" } + module shared_ptr { private header "__memory/shared_ptr.h" } + module temporary_buffer { private header "__memory/temporary_buffer.h" } module uninitialized_algorithms { private header "__memory/uninitialized_algorithms.h" } - module unique_ptr { private header "__memory/unique_ptr.h" } - module uses_allocator { private header "__memory/uses_allocator.h" } + module unique_ptr { private header "__memory/unique_ptr.h" } + module uses_allocator { private header "__memory/uses_allocator.h" } } } module mutex { diff --git a/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_iterator.compile.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept __nothrow_forward_iterator; + +#include + +#include "test_iterators.h" + +struct ForwardProxyIterator { + using value_type = int; + using difference_type = int; + ForwardProxyIterator& operator++(); + ForwardProxyIterator operator++(int); + bool operator==(const ForwardProxyIterator&) const; + + int operator*() const; +}; + +static_assert(std::ranges::__nothrow_forward_iterator>); +static_assert(std::forward_iterator); +static_assert(!std::ranges::__nothrow_forward_iterator); diff --git a/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_forward_range.compile.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept __nothrow_forward_range; + +#include + +#include "test_iterators.h" +#include "test_range.h" + +// Has to be a template to work with `test_range`. +template +struct ForwardProxyIterator { + using value_type = int; + using difference_type = int; + ForwardProxyIterator& operator++(); + ForwardProxyIterator operator++(int); + bool operator==(const ForwardProxyIterator&) const; + + int operator*() const; +}; + +static_assert(std::ranges::__nothrow_forward_range>); +static_assert(!std::ranges::__nothrow_forward_range>); +static_assert(std::ranges::forward_range>); +static_assert(!std::ranges::__nothrow_forward_range>); diff --git a/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_iterator.compile.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept __nothrow_input_iterator; + +#include + +#include "test_iterators.h" + +struct InputProxyIterator { + using value_type = int; + using difference_type = int; + InputProxyIterator& operator++(); + InputProxyIterator operator++(int); + + int operator*() const; +}; + +static_assert(std::ranges::__nothrow_input_iterator>); +static_assert(!std::ranges::__nothrow_input_iterator>); +static_assert(std::input_iterator); +static_assert(!std::ranges::__nothrow_input_iterator); diff --git a/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_input_range.compile.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept __nothrow_input_range; + +#include + +#include "test_iterators.h" +#include "test_range.h" + +// Has to be a template to work with `test_range`. +template +struct InputProxyIterator { + using value_type = int; + using difference_type = int; + InputProxyIterator& operator++(); + InputProxyIterator operator++(int); + + int operator*() const; +}; + +static_assert(std::ranges::__nothrow_input_range>); +static_assert(std::ranges::input_range>); +static_assert(!std::ranges::__nothrow_input_range>); diff --git a/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/algorithms/specialized.algorithms/special.mem.concepts/nothrow_sentinel_for.compile.pass.cpp @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept __nothrow_sentinel_for; + +#include + +static_assert(std::ranges::__nothrow_sentinel_for); +static_assert(!std::ranges::__nothrow_sentinel_for); diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/memory/concepts.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/memory/concepts.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/memory/concepts.module.verify.cpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// 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: '__memory/concepts.h'}} +#include <__memory/concepts.h>