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 @@ -230,6 +230,7 @@ __memory/compressed_pair.h __memory/construct_at.h __memory/pointer_traits.h + __memory/ranges_uninitialized_algorithms.h __memory/raw_storage_iterator.h __memory/shared_ptr.h __memory/temporary_buffer.h diff --git a/libcxx/include/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__memory/ranges_uninitialized_algorithms.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__memory/ranges_uninitialized_algorithms.h @@ -0,0 +1,62 @@ +// -*- 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_RANGES_UNINITIALIZED_ALGORITHMS_H +#define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#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] + +template +concept __nothrow_input_iterator = + input_iterator<_Ip> && + // Not a proxy iterator. + 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_RANGES_UNINITIALIZED_ALGORITHMS_H diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -671,6 +671,7 @@ #include <__memory/compressed_pair.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> +#include <__memory/ranges_uninitialized_algorithms.h> #include <__memory/raw_storage_iterator.h> #include <__memory/shared_ptr.h> #include <__memory/temporary_buffer.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 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 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 ranges_uninitialized_algorithms { private header "__memory/ranges_uninitialized_algorithms.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 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,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 + +// template +// concept __nothrow_forward_iterator; + +#include + +#include "test_iterators.h" +#include "test_range.h" + +struct ForwardIterator_Proxy { + using value_type = int; + using difference_type = int; + ForwardIterator_Proxy& operator++(); + ForwardIterator_Proxy operator++(int); + bool operator==(const ForwardIterator_Proxy&) 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 ForwardIterator_Proxy { + using value_type = int; + using difference_type = int; + ForwardIterator_Proxy& operator++(); + ForwardIterator_Proxy operator++(int); + bool operator==(const ForwardIterator_Proxy&) 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 InputIterator_Proxy { + using value_type = int; + using difference_type = int; + InputIterator_Proxy& operator++(); + InputIterator_Proxy 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 InputIterator_Proxy { + using value_type = int; + using difference_type = int; + InputIterator_Proxy& operator++(); + InputIterator_Proxy 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,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +#include +#include + +#include "test_iterators.h" +#include "test_range.h" +#include "MoveOnly.h" + +static_assert(std::ranges::__nothrow_sentinel_for); +static_assert(!std::ranges::__nothrow_sentinel_for); diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp --- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.input/input_iterator.compile.pass.cpp @@ -23,14 +23,6 @@ using value_type = int; using difference_type = std::ptrdiff_t; - no_explicit_iter_concept() = default; - - no_explicit_iter_concept(no_explicit_iter_concept&&) = default; - no_explicit_iter_concept& operator=(no_explicit_iter_concept&&) = default; - - no_explicit_iter_concept(no_explicit_iter_concept const&) = delete; - no_explicit_iter_concept& operator=(no_explicit_iter_concept const&) = delete; - value_type operator*() const; no_explicit_iter_concept& operator++(); @@ -48,14 +40,6 @@ using difference_type = std::ptrdiff_t; using iterator_concept = std::input_iterator_tag; - not_weakly_incrementable() = default; - - not_weakly_incrementable(not_weakly_incrementable&&) = default; - not_weakly_incrementable& operator=(not_weakly_incrementable&&) = default; - - not_weakly_incrementable(not_weakly_incrementable const&) = delete; - not_weakly_incrementable& operator=(not_weakly_incrementable const&) = delete; - int operator*() const; not_weakly_incrementable& operator++(); @@ -67,14 +51,6 @@ using difference_type = std::ptrdiff_t; using iterator_concept = std::input_iterator_tag; - not_indirectly_readable() = default; - - not_indirectly_readable(not_indirectly_readable&&) = default; - not_indirectly_readable& operator=(not_indirectly_readable&&) = default; - - not_indirectly_readable(not_indirectly_readable const&) = delete; - not_indirectly_readable& operator=(not_indirectly_readable const&) = delete; - int operator*() const; not_indirectly_readable& operator++(); @@ -87,14 +63,6 @@ using difference_type = std::ptrdiff_t; using iterator_category = void; - bad_iterator_category() = default; - - bad_iterator_category(bad_iterator_category&&) = default; - bad_iterator_category& operator=(bad_iterator_category&&) = default; - - bad_iterator_category(bad_iterator_category const&) = delete; - bad_iterator_category& operator=(bad_iterator_category const&) = delete; - value_type operator*() const; bad_iterator_category& operator++(); @@ -107,14 +75,6 @@ using difference_type = std::ptrdiff_t; using iterator_concept = void*; - bad_iterator_concept() = default; - - bad_iterator_concept(bad_iterator_concept&&) = default; - bad_iterator_concept& operator=(bad_iterator_concept&&) = default; - - bad_iterator_concept(bad_iterator_concept const&) = delete; - bad_iterator_concept& operator=(bad_iterator_concept const&) = delete; - value_type operator*() const; bad_iterator_concept& operator++();