[libcxx][ranges] removes default_initializable from weakly_incrementable and view

also:

* removes default constructors from predefined iterators
* makes span and string_view views

Partially implements P2325.
Partially resolves LWG3326.

Differential Revision: https://reviews.llvm.org/D102468
This commit is contained in:
Christopher Di Bella 2021-05-14 06:20:07 +00:00
parent 933df6ca79
commit 462f8f0611
19 changed files with 23 additions and 253 deletions

View File

@ -246,7 +246,7 @@
"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","",""
"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","",""
"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","",""
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","",""
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","|In progress|",""
"`3327 <https://wg21.link/LWG3327>`__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|",""
"`3328 <https://wg21.link/LWG3328>`__","Clarify that ``std::string``\ is not good for UTF-8","Prague","",""
"`3329 <https://wg21.link/LWG3329>`__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0"

1 Issue # Issue Name Meeting Status First released version
246 `3323 <https://wg21.link/LWG3323>`__ ``*has-tuple-element*``\ helper concept needs ``convertible_to``\ Prague
247 `3324 <https://wg21.link/LWG3324>`__ Special-case ``std::strong/weak/partial_order``\ for pointers Prague
248 `3325 <https://wg21.link/LWG3325>`__ Constrain return type of transformation function for ``transform_view``\ Prague
249 `3326 <https://wg21.link/LWG3326>`__ ``enable_view``\ has false positives Prague |In progress|
250 `3327 <https://wg21.link/LWG3327>`__ Format alignment specifiers vs. text direction Prague |Nothing To Do|
251 `3328 <https://wg21.link/LWG3328>`__ Clarify that ``std::string``\ is not good for UTF-8 Prague
252 `3329 <https://wg21.link/LWG3329>`__ ``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ Prague |Complete| 13.0

View File

@ -194,3 +194,4 @@
"`P2106 <https://wg21.link/P2106>`__","LWG","Alternative wording for GB315 and GB316","Prague","* *",""
"`P2116 <https://wg21.link/P2116>`__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0"
"`P2231 <https://wg21.link/P2231>`__","LWG","Missing constexpr in std::optional and std::variant","February 2021","|In progress|","13.0"
"`P2325 <https://wg21.link/P2325>`__","LWG","Views should not be required to be default constructible","June Telecon","|In progress|",""

1 Paper # Group Paper Name Meeting Status First released version
194 `P2106 <https://wg21.link/P2106>`__ LWG Alternative wording for GB315 and GB316 Prague * *
195 `P2116 <https://wg21.link/P2116>`__ LWG Remove tuple-like protocol support from fixed-extent span Prague |Complete| 11.0
196 `P2231 <https://wg21.link/P2231>`__ LWG Missing constexpr in std::optional and std::variant February 2021 |In progress| 13.0
197 `P2325 <https://wg21.link/P2325>`__ LWG Views should not be required to be default constructible June Telecon |In progress|

View File

@ -71,7 +71,6 @@ concept __signed_integer_like = signed_integral<_Tp>;
template<class _Ip>
concept weakly_incrementable =
default_initializable<_Ip> &&
movable<_Ip> &&
requires(_Ip __i) {
typename iter_difference_t<_Ip>;

View File

@ -73,7 +73,6 @@ namespace ranges {
concept view =
range<_Tp> &&
movable<_Tp> &&
default_initializable<_Tp> &&
enable_view<_Tp>;
template<class _Range>

View File

@ -13,7 +13,6 @@
#include <__config>
#include <concepts>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

View File

@ -254,7 +254,6 @@ public:
typedef void reference;
typedef void pointer;
constexpr back_insert_iterator() noexcept = default; // since C++20
explicit back_insert_iterator(Container& x); // constexpr in C++20
back_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
back_insert_iterator& operator*(); // constexpr in C++20
@ -278,7 +277,6 @@ public:
typedef void reference;
typedef void pointer;
constexpr front_insert_iterator() noexcept = default; // since C++20
explicit front_insert_iterator(Container& x); // constexpr in C++20
front_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
front_insert_iterator& operator*(); // constexpr in C++20
@ -303,7 +301,6 @@ public:
typedef void reference;
typedef void pointer;
insert_iterator() = default; // since C++20
insert_iterator(Container& x, typename Container::iterator i); // constexpr in C++20
insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
insert_iterator& operator*(); // constexpr in C++20
@ -436,7 +433,6 @@ public:
typedef traits traits_type;
typedef basic_ostream<charT,traits> ostream_type;
constexpr ostream_iterator() noexcept = default; // since C++20
ostream_iterator(ostream_type& s);
ostream_iterator(ostream_type& s, const charT* delimiter);
ostream_iterator(const ostream_iterator& x);
@ -502,7 +498,6 @@ public:
typedef basic_streambuf<charT, traits> streambuf_type;
typedef basic_ostream<charT, traits> ostream_type;
constexpr ostreambuf_iterator() noexcept = default; // since C++20
ostreambuf_iterator(ostream_type& s) noexcept;
ostreambuf_iterator(streambuf_type* s) noexcept;
ostreambuf_iterator& operator=(charT c);
@ -849,9 +844,6 @@ public:
typedef void reference;
typedef _Container container_type;
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY constexpr back_insert_iterator() noexcept = default;
#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
{container->push_back(__value_); return *this;}
@ -894,9 +886,6 @@ public:
typedef void reference;
typedef _Container container_type;
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY constexpr front_insert_iterator() noexcept = default;
#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
{container->push_front(__value_); return *this;}
@ -927,7 +916,7 @@ class _LIBCPP_TEMPLATE_VIS insert_iterator
_LIBCPP_SUPPRESS_DEPRECATED_POP
protected:
_Container* container;
typename _Container::iterator iter;
typename _Container::iterator iter; // FIXME: `ranges::iterator_t<Container>` in C++20 mode
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
@ -940,9 +929,6 @@ public:
typedef void reference;
typedef _Container container_type;
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY insert_iterator() = default;
#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
: container(_VSTD::addressof(__x)), iter(__i) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
@ -1061,9 +1047,6 @@ private:
ostream_type* __out_stream_;
const char_type* __delim_;
public:
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY constexpr ostream_iterator() noexcept = default;
#endif
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
: __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
@ -1186,9 +1169,6 @@ public:
private:
streambuf_type* __sbuf_;
public:
#if _LIBCPP_STD_VER > 17
_LIBCPP_INLINE_VISIBILITY constexpr ostreambuf_iterator() noexcept = default;
#endif
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
: __sbuf_(__s.rdbuf()) {}
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT

View File

@ -22,6 +22,9 @@ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
template <class ElementType, size_t Extent = dynamic_extent>
class span;
template<class ElementType, size_t Extent>
inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
template<class ElementType, size_t Extent>
inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
@ -127,6 +130,7 @@ template<class Container>
#include <__config>
#include <__debug>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <array> // for array
#include <cstddef> // for byte
#include <iterator> // for iterators
@ -531,6 +535,9 @@ private:
#if !defined(_LIBCPP_HAS_NO_RANGES)
template <class _Tp, size_t _Extent>
inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
template <class _ElementType, size_t _Extent>
inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
// as_bytes & as_writable_bytes

View File

@ -19,6 +19,9 @@ namespace std {
template<class charT, class traits = char_traits<charT>>
class basic_string_view;
template<class charT, class traits>
inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
template<class charT, class traits>
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
@ -184,6 +187,7 @@ namespace std {
#include <__config>
#include <__debug>
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/enable_view.h>
#include <__string>
#include <algorithm>
#include <compare>
@ -654,6 +658,9 @@ private:
};
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
template <class _CharT, class _Traits>
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)

View File

@ -23,13 +23,13 @@ namespace stdr = std::ranges;
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
static_assert(stdr::common_range<range>);
static_assert(stdr::random_access_range<range>);
static_assert(!stdr::view<range>);
static_assert(stdr::view<range> && stdr::enable_view<range>);
static_assert(stdr::sized_range<range>);
static_assert(stdr::borrowed_range<range>);
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
static_assert(stdr::common_range<range const>);
static_assert(stdr::random_access_range<range const>);
static_assert(!stdr::view<range const>);
static_assert(!stdr::view<range const> && !stdr::enable_view<range const>);
static_assert(stdr::sized_range<range const>);
static_assert(stdr::borrowed_range<range const>);

View File

@ -1,33 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: gcc-10
// template<class T>
// concept weakly_incrementable;
#include <iterator>
#include <concepts>
// clang-format off
template<std::default_initializable I>
requires std::movable<I>
[[nodiscard]] constexpr bool check_subsumption() {
return false;
}
template<std::weakly_incrementable>
[[nodiscard]] constexpr bool check_subsumption() {
return true;
}
// clang-format on
static_assert(check_subsumption<int*>());

View File

@ -58,10 +58,10 @@ static_assert(!std::weakly_incrementable<floating_difference_type>);
static_assert(!std::weakly_incrementable<non_const_minus>);
static_assert(!std::weakly_incrementable<non_integral_minus>);
static_assert(!std::weakly_incrementable<bad_difference_type_good_minus>);
static_assert(!std::weakly_incrementable<not_default_initializable>);
static_assert(!std::weakly_incrementable<not_movable>);
static_assert(!std::weakly_incrementable<preinc_not_declared>);
static_assert(!std::weakly_incrementable<postinc_not_declared>);
static_assert(std::weakly_incrementable<not_default_initializable>);
static_assert(std::weakly_incrementable<incrementable_with_difference_type>);
static_assert(std::weakly_incrementable<incrementable_without_difference_type>);
static_assert(std::weakly_incrementable<difference_type_and_void_minus>);

View File

@ -1,38 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <iterator>
// class back_insert_iterator
// constexpr back_insert_iterator() noexcept = default;
#include <iterator>
#include <vector>
#include "test_macros.h"
struct T { };
using Container = std::vector<T>;
constexpr bool test() {
std::back_insert_iterator<Container> it;
(void)it;
return true;
}
int main(int, char**) {
ASSERT_NOEXCEPT(std::back_insert_iterator<Container>());
test();
static_assert(test());
return 0;
}

View File

@ -1,38 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <iterator>
// class front_insert_iterator
// constexpr front_insert_iterator() noexcept = default;
#include <iterator>
#include <vector>
#include "test_macros.h"
struct T { };
using Container = std::vector<T>;
constexpr bool test() {
std::front_insert_iterator<Container> it;
(void)it;
return true;
}
int main(int, char**) {
ASSERT_NOEXCEPT(std::front_insert_iterator<Container>());
test();
static_assert(test());
return 0;
}

View File

@ -1,26 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <iterator>
// class insert_iterator
// insert_iterator() = default;
#include <iterator>
#include <vector>
struct T { };
using Container = std::vector<T>;
int main(int, char**) {
std::insert_iterator<Container> it; (void)it;
return 0;
}

View File

@ -1,42 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <iterator>
// class ostream_iterator
// constexpr ostream_iterator() noexcept = default;
#include <iterator>
#include <string> // char_traits
#include "test_macros.h"
struct MyTraits : std::char_traits<char> {
MyTraits(); // This should not be called.
};
constexpr bool test() {
std::ostream_iterator<int> it;
(void)it;
std::ostream_iterator<int, char, MyTraits> wit;
(void)wit;
return true;
}
int main(int, char**) {
ASSERT_NOEXCEPT(std::ostream_iterator<int>());
ASSERT_NOEXCEPT(std::ostream_iterator<int, char, MyTraits>());
test();
static_assert(test());
return 0;
}

View File

@ -1,37 +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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <iterator>
// class ostreambuf_iterator
// constexpr ostreambuf_iterator() noexcept = default;
#include <iterator>
#include "test_macros.h"
constexpr bool test() {
std::ostreambuf_iterator<char> it;
(void)it;
std::ostreambuf_iterator<wchar_t> wit;
(void)wit;
return true;
}
int main(int, char**) {
ASSERT_NOEXCEPT(std::ostreambuf_iterator<char>());
ASSERT_NOEXCEPT(std::ostreambuf_iterator<wchar_t>());
test();
static_assert(test());
return 0;
}

View File

@ -46,7 +46,7 @@ static_assert(std::ranges::range<NotDefaultInit>);
static_assert(std::movable<NotDefaultInit>);
static_assert(!std::default_initializable<NotDefaultInit>);
static_assert(std::ranges::enable_view<NotDefaultInit>);
static_assert(!std::ranges::view<NotDefaultInit>);
static_assert(std::ranges::view<NotDefaultInit>);
// The type would be a view, but it doesn't enable it with enable_view
struct NotExplicitlyEnabled {

View File

@ -43,11 +43,3 @@ namespace subsume_movable {
constexpr bool test() { return false; }
static_assert(test<View>());
}
namespace subsume_default_initializable {
template <std::ranges::view>
constexpr bool test() { return true; }
template <std::default_initializable>
constexpr bool test() { return false; }
static_assert(test<View>());
}

View File

@ -22,13 +22,13 @@ namespace stdr = std::ranges;
static_assert(std::same_as<stdr::iterator_t<std::string_view>, std::string_view::iterator>);
static_assert(stdr::common_range<std::string_view>);
static_assert(stdr::random_access_range<std::string_view>);
static_assert(!stdr::view<std::string_view>);
static_assert(stdr::view<std::string_view> && stdr::enable_view<std::string_view>);
static_assert(stdr::sized_range<std::string_view>);
static_assert(stdr::borrowed_range<std::string_view>);
static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
static_assert(stdr::common_range<std::string_view const>);
static_assert(stdr::random_access_range<std::string_view const>);
static_assert(!stdr::view<std::string_view const>); // FIXME: string_view needs to be patched so this is true
static_assert(!stdr::view<std::string_view const> && !stdr::enable_view<std::string_view const>);
static_assert(stdr::sized_range<std::string_view const>);
static_assert(stdr::borrowed_range<std::string_view const>);