forked from OSchip/llvm-project
[libcxx] contiguous iterator concept: don't require pointer or complete element types
`contiguous_iterator` requires the iterator type passed is either a pointer type or that the element type of the iterator is a complete object type. These constraints are not part of the current wording in defining the `contiguous_iterator` concept - adjust the concept to reflect this. Inspired from discussion at https://reviews.llvm.org/D108645. Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D108855
This commit is contained in:
parent
a3d357e504
commit
2d400db63c
|
@ -171,7 +171,6 @@ concept contiguous_iterator =
|
|||
derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> &&
|
||||
is_lvalue_reference_v<iter_reference_t<_Ip>> &&
|
||||
same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> &&
|
||||
(is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) &&
|
||||
requires(const _Ip& __i) {
|
||||
{ _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>;
|
||||
};
|
||||
|
|
|
@ -101,9 +101,10 @@ static_assert(!std::contiguous_iterator<mismatch_value_iter_ref_t>);
|
|||
struct wrong_iter_reference_t {
|
||||
typedef std::contiguous_iterator_tag iterator_category;
|
||||
typedef short value_type;
|
||||
typedef short element_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef int* pointer;
|
||||
typedef short& reference;
|
||||
typedef short* pointer;
|
||||
typedef int& reference;
|
||||
typedef wrong_iter_reference_t self;
|
||||
|
||||
wrong_iter_reference_t();
|
||||
|
@ -132,40 +133,6 @@ struct wrong_iter_reference_t {
|
|||
static_assert(std::random_access_iterator<wrong_iter_reference_t>);
|
||||
static_assert(!std::contiguous_iterator<wrong_iter_reference_t>);
|
||||
|
||||
struct no_element_type {
|
||||
typedef std::contiguous_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef int* pointer;
|
||||
typedef int& reference;
|
||||
typedef no_element_type self;
|
||||
|
||||
no_element_type();
|
||||
|
||||
reference operator*() const;
|
||||
pointer operator->() const;
|
||||
auto operator<=>(const self&) const = default;
|
||||
|
||||
self& operator++();
|
||||
self operator++(int);
|
||||
|
||||
self& operator--();
|
||||
self operator--(int);
|
||||
|
||||
self& operator+=(difference_type n);
|
||||
self operator+(difference_type n) const;
|
||||
friend self operator+(difference_type n, self x);
|
||||
|
||||
self& operator-=(difference_type n);
|
||||
self operator-(difference_type n) const;
|
||||
difference_type operator-(const self& n) const;
|
||||
|
||||
reference operator[](difference_type n) const;
|
||||
};
|
||||
|
||||
static_assert(std::random_access_iterator<no_element_type>);
|
||||
static_assert(!std::contiguous_iterator<no_element_type>);
|
||||
|
||||
struct to_address_wrong_return_type {
|
||||
typedef std::contiguous_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// REQUIRES: libc++
|
||||
|
||||
// This test checks that std::contiguous_iterator uses std::to_address, which is not SFINAE-friendly
|
||||
// when the type is missing the `T::element_type` typedef.
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <compare>
|
||||
#include <cstddef>
|
||||
|
||||
struct no_element_type {
|
||||
typedef std::contiguous_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef int* pointer;
|
||||
typedef int& reference;
|
||||
typedef no_element_type self;
|
||||
|
||||
no_element_type();
|
||||
|
||||
reference operator*() const;
|
||||
pointer operator->() const;
|
||||
auto operator<=>(const self&) const = default;
|
||||
|
||||
self& operator++();
|
||||
self operator++(int);
|
||||
|
||||
self& operator--();
|
||||
self operator--(int);
|
||||
|
||||
self& operator+=(difference_type n);
|
||||
self operator+(difference_type n) const;
|
||||
friend self operator+(difference_type n, self x);
|
||||
|
||||
self& operator-=(difference_type n);
|
||||
self operator-(difference_type n) const;
|
||||
difference_type operator-(const self& n) const;
|
||||
|
||||
reference operator[](difference_type n) const;
|
||||
};
|
||||
|
||||
void test() {
|
||||
(void) std::contiguous_iterator<no_element_type>;
|
||||
// expected-error@*:* {{implicit instantiation of undefined template}}
|
||||
// expected-note@*:* {{to_address}}
|
||||
}
|
Loading…
Reference in New Issue