forked from OSchip/llvm-project
[libc++] Implement LWG3435 (constraints on reverse_iterator and move_iterator)
This commit is contained in:
parent
1dff8637b1
commit
e4d3a993c2
|
@ -6,7 +6,7 @@
|
|||
"`3211 <https://wg21.link/LWG3211>`__","``std::tuple<>`` should be trivially constructible","November 2020","",""
|
||||
"`3236 <https://wg21.link/LWG3236>`__","Random access iterator requirements lack limiting relational operators domain to comparing those from the same range","November 2020","",""
|
||||
"`3265 <https://wg21.link/LWG3265>`__","``move_iterator``'s conversions are more broken after P1207","November 2020","Fixed by `LWG3435 <https://wg21.link/LWG3435>`__",""
|
||||
"`3435 <https://wg21.link/LWG3435>`__","``three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>``","November 2020","",""
|
||||
"`3435 <https://wg21.link/LWG3435>`__","``three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>``","November 2020","|Complete|","13.0"
|
||||
"`3432 <https://wg21.link/LWG3432>`__","Missing requirement for comparison_category","November 2020","",""
|
||||
"`3447 <https://wg21.link/LWG3447>`__","Deduction guides for ``take_view`` and ``drop_view`` have different constraints","November 2020","",""
|
||||
"`3450 <https://wg21.link/LWG3450>`__","The const overloads of ``take_while_view::begin/end`` are underconstrained","November 2020","",""
|
||||
|
|
|
|
@ -669,27 +669,53 @@ public:
|
|||
#ifndef _LIBCPP_ABI_NO_ITERATOR_BASES
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator() : __t(), current() {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
|
||||
{ __t = current = __u.base(); return *this; }
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator(const reverse_iterator<_Up>& __u)
|
||||
: __t(__u.base()), current(__u.base())
|
||||
{ }
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value &&
|
||||
is_convertible<_Up const&, _Iter>::value &&
|
||||
is_assignable<_Up const&, _Iter>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
|
||||
__t = current = __u.base();
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator() : current() {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
explicit reverse_iterator(_Iter __x) : current(__x) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator(const reverse_iterator<_Up>& __u) : current(__u.base()) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator=(const reverse_iterator<_Up>& __u)
|
||||
{ current = __u.base(); return *this; }
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator(const reverse_iterator<_Up>& __u)
|
||||
: current(__u.base())
|
||||
{ }
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value &&
|
||||
is_convertible<_Up const&, _Iter>::value &&
|
||||
is_assignable<_Up const&, _Iter>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reverse_iterator& operator=(const reverse_iterator<_Up>& __u) {
|
||||
current = __u.base();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
_Iter base() const {return current;}
|
||||
|
@ -1217,11 +1243,27 @@ public:
|
|||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
move_iterator() : __i() {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
explicit move_iterator(_Iter __x) : __i(__x) {}
|
||||
template <class _Up>
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value && is_convertible<_Up const&, _Iter>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {}
|
||||
|
||||
template <class _Up, class = _EnableIf<
|
||||
!is_same<_Up, _Iter>::value &&
|
||||
is_convertible<_Up const&, _Iter>::value &&
|
||||
is_assignable<_Iter&, _Up const&>::value
|
||||
> >
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
move_iterator& operator=(const move_iterator<_Up>& __u) {
|
||||
__i = __u.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
|
||||
reference operator*() const { return static_cast<reference>(*__i); }
|
||||
|
|
|
@ -6,37 +6,20 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// GCC 5 does not evaluate static assertions dependent on a template parameter.
|
||||
// UNSUPPORTED: gcc-5
|
||||
|
||||
// <iterator>
|
||||
|
||||
// move_iterator
|
||||
|
||||
// template <class U>
|
||||
// requires HasConstructor<Iter, const U&>
|
||||
// move_iterator(const move_iterator<U> &u);
|
||||
|
||||
// test requires
|
||||
// requires !same_as<U, Iter> && convertible_to<const U&, Iter>
|
||||
// move_iterator(const move_iterator<U> &u);
|
||||
|
||||
#include <iterator>
|
||||
|
||||
template <class It, class U>
|
||||
void
|
||||
test(U u)
|
||||
{
|
||||
std::move_iterator<U> r2(u);
|
||||
std::move_iterator<It> r1 = r2;
|
||||
}
|
||||
|
||||
struct base {};
|
||||
struct derived {};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
derived d;
|
||||
|
||||
test<base*>(&d);
|
||||
|
||||
return 0;
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
void test() {
|
||||
std::move_iterator<Base*> base;
|
||||
std::move_iterator<Derived*> derived(base); // expected-error {{no matching constructor for initialization of 'std::move_iterator<Derived *>'}}
|
||||
}
|
|
@ -6,30 +6,18 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// GCC 5 does not evaluate static assertions dependent on a template parameter.
|
||||
// UNSUPPORTED: gcc-5
|
||||
|
||||
// <iterator>
|
||||
|
||||
// move_iterator
|
||||
|
||||
// explicit move_iterator(Iter );
|
||||
|
||||
// test explicit
|
||||
// test explicitness
|
||||
|
||||
#include <iterator>
|
||||
|
||||
template <class It>
|
||||
void
|
||||
test(It i)
|
||||
{
|
||||
std::move_iterator<It> r = i;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
char s[] = "123";
|
||||
test(s);
|
||||
|
||||
return 0;
|
||||
int main(int, char**) {
|
||||
char const* it = "";
|
||||
std::move_iterator<char const*> r = it; // expected-error{{no viable conversion from 'const char *' to 'std::move_iterator<const char *>'}}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <iterator>
|
||||
|
||||
// move_iterator
|
||||
|
||||
// template <class U>
|
||||
// requires !same_as<U, Iter> && convertible_to<const U&, Iter> && assignable_from<Iter&, const U&>
|
||||
// move_iterator& operator=(const move_iterator<U>& u);
|
||||
|
||||
#include <iterator>
|
||||
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
void test() {
|
||||
std::move_iterator<Base*> base;
|
||||
std::move_iterator<Derived*> derived;
|
||||
derived = base; // expected-error {{no viable overloaded '='}}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// GCC 5 does not evaluate static assertions dependent on a template parameter.
|
||||
// UNSUPPORTED: gcc-5
|
||||
|
||||
// <iterator>
|
||||
|
||||
// move_iterator
|
||||
|
||||
// template <class U>
|
||||
// requires HasAssign<Iter, const U&>
|
||||
// move_iterator&
|
||||
// operator=(const move_iterator<U>& u);
|
||||
|
||||
// test requires
|
||||
|
||||
#include <iterator>
|
||||
|
||||
template <class It, class U>
|
||||
void
|
||||
test(U u)
|
||||
{
|
||||
const std::move_iterator<U> r2(u);
|
||||
std::move_iterator<It> r1;
|
||||
r1 = r2;
|
||||
}
|
||||
|
||||
struct base {};
|
||||
struct derived {};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
derived d;
|
||||
test<base*>(&d);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -29,7 +29,7 @@ test(U u)
|
|||
{
|
||||
const std::move_iterator<U> r2(u);
|
||||
std::move_iterator<It> r1;
|
||||
std::move_iterator<It>& rr = r1 = r2;
|
||||
std::move_iterator<It>& rr = (r1 = r2);
|
||||
assert(r1.base() == u);
|
||||
assert(&rr == &r1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <iterator>
|
||||
|
||||
// reverse_iterator
|
||||
|
||||
// template <class U>
|
||||
// requires !same_as<U, Iter> && convertible_to<const U&, Iter> && assignable_from<Iter&, const U&>
|
||||
// reverse_iterator& operator=(const reverse_iterator<U>& u);
|
||||
|
||||
#include <iterator>
|
||||
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
void test() {
|
||||
std::reverse_iterator<Base*> base;
|
||||
std::reverse_iterator<Derived*> derived;
|
||||
derived = base; // expected-error {{no viable overloaded '='}}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <iterator>
|
||||
|
||||
// reverse_iterator
|
||||
|
||||
// template <class U>
|
||||
// requires !same_as<U, Iter> && convertible_to<const U&, Iter>
|
||||
// reverse_iterator(const reverse_iterator<U> &);
|
||||
|
||||
#include <iterator>
|
||||
|
||||
struct Base { };
|
||||
struct Derived : Base { };
|
||||
|
||||
void test() {
|
||||
std::reverse_iterator<Base*> base;
|
||||
std::reverse_iterator<Derived*> derived(base); // expected-error {{no matching constructor for initialization of 'std::reverse_iterator<Derived *>'}}
|
||||
}
|
Loading…
Reference in New Issue