[libc++][ranges] Implement [special.mem.concepts].
Implement the exposition-only concepts specified in `[special.mem.concepts]`. These are all thin wrappers over other concepts. Reviewed By: #libc, Quuxplusone, ldionne Differential Revision: https://reviews.llvm.org/D114761
This commit is contained in:
parent
4e24ca1cdc
commit
2d9efcfeec
|
@ -17,7 +17,7 @@ Section,Description,Dependencies,Assignee,Complete
|
|||
| *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] <http://wg21.link/specialized.algorithms>`_,"| ranges::uninitialized_default_construct
|
||||
| ranges::uninitialized_default_construct_n
|
||||
| ranges::uninitialized_value_construct
|
||||
|
|
|
|
@ -228,6 +228,7 @@ set(files
|
|||
__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
|
||||
|
|
66
libcxx/include/__memory/concepts.h
Normal file
66
libcxx/include/__memory/concepts.h
Normal file
|
@ -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 <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
#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 <class _Ip>
|
||||
concept __nothrow_input_iterator =
|
||||
input_iterator<_Ip> &&
|
||||
is_lvalue_reference_v<iter_reference_t<_Ip>> &&
|
||||
same_as<remove_cvref_t<iter_reference_t<_Ip>>, iter_value_t<_Ip>>;
|
||||
|
||||
template <class _Sp, class _Ip>
|
||||
concept __nothrow_sentinel_for = sentinel_for<_Sp, _Ip>;
|
||||
|
||||
template <class _Rp>
|
||||
concept __nothrow_input_range =
|
||||
range<_Rp> &&
|
||||
__nothrow_input_iterator<iterator_t<_Rp>> &&
|
||||
__nothrow_sentinel_for<sentinel_t<_Rp>, iterator_t<_Rp>>;
|
||||
|
||||
template <class _Ip>
|
||||
concept __nothrow_forward_iterator =
|
||||
__nothrow_input_iterator<_Ip> &&
|
||||
forward_iterator<_Ip> &&
|
||||
__nothrow_sentinel_for<_Ip, _Ip>;
|
||||
|
||||
template <class _Rp>
|
||||
concept __nothrow_forward_range =
|
||||
__nothrow_input_range<_Rp> &&
|
||||
__nothrow_forward_iterator<iterator_t<_Rp>>;
|
||||
|
||||
} // namespace ranges
|
||||
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___MEMORY_CONCEPTS_H
|
|
@ -669,6 +669,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
|
|||
#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>
|
||||
|
|
|
@ -630,21 +630,22 @@ module std [system] {
|
|||
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 {
|
||||
|
|
|
@ -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<class I>
|
||||
// concept __nothrow_forward_iterator;
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<forward_iterator<int*>>);
|
||||
static_assert(std::forward_iterator<ForwardProxyIterator>);
|
||||
static_assert(!std::ranges::__nothrow_forward_iterator<ForwardProxyIterator>);
|
|
@ -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<class R>
|
||||
// concept __nothrow_forward_range;
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
|
||||
// Has to be a template to work with `test_range`.
|
||||
template <typename>
|
||||
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<test_range<forward_iterator>>);
|
||||
static_assert(!std::ranges::__nothrow_forward_range<test_range<cpp20_input_iterator>>);
|
||||
static_assert(std::ranges::forward_range<test_range<ForwardProxyIterator>>);
|
||||
static_assert(!std::ranges::__nothrow_forward_range<test_range<ForwardProxyIterator>>);
|
|
@ -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<class I>
|
||||
// concept __nothrow_input_iterator;
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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<cpp20_input_iterator<int*>>);
|
||||
static_assert(!std::ranges::__nothrow_input_iterator<output_iterator<int*>>);
|
||||
static_assert(std::input_iterator<InputProxyIterator>);
|
||||
static_assert(!std::ranges::__nothrow_input_iterator<InputProxyIterator>);
|
|
@ -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<class R>
|
||||
// concept __nothrow_input_range;
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "test_iterators.h"
|
||||
#include "test_range.h"
|
||||
|
||||
// Has to be a template to work with `test_range`.
|
||||
template <typename>
|
||||
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<test_range<cpp20_input_iterator>>);
|
||||
static_assert(std::ranges::input_range<test_range<InputProxyIterator>>);
|
||||
static_assert(!std::ranges::__nothrow_input_range<test_range<InputProxyIterator>>);
|
|
@ -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<class S, class I>
|
||||
// concept __nothrow_sentinel_for;
|
||||
|
||||
#include <memory>
|
||||
|
||||
static_assert(std::ranges::__nothrow_sentinel_for<int*, int*>);
|
||||
static_assert(!std::ranges::__nothrow_sentinel_for<int*, long*>);
|
|
@ -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>
|
Loading…
Reference in a new issue