Skip to content

Commit

Permalink
P0896R4 changes to insert iterators (microsoft#589)
Browse files Browse the repository at this point in the history
When `defined(__cpp_lib_concepts)`, `(back_|front_|)insert_iterator` are default constructible, and have `ptrdiff_t` as difference type.

Skip libc++ tests broken by this change.
  • Loading branch information
CaseyCarter authored and JeanPhilippeKernel committed Mar 10, 2020
1 parent 88e5fd2 commit e2da90b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
35 changes: 28 additions & 7 deletions stl/inc/iterator
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ class back_insert_iterator { // wrap pushes to back of container as output itera
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;

using container_type = _Container;

#ifdef __cpp_lib_concepts
using difference_type = ptrdiff_t;

constexpr back_insert_iterator() noexcept = default;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
using difference_type = void;
#endif // __cpp_lib_concepts

explicit back_insert_iterator(_Container& _Cont) noexcept /* strengthened */ : container(_STD addressof(_Cont)) {}

back_insert_iterator& operator=(const typename _Container::value_type& _Val) {
Expand All @@ -56,7 +63,7 @@ public:
}

protected:
_Container* container; // pointer to container
_Container* container = nullptr;
};

// FUNCTION TEMPLATE back_inserter
Expand All @@ -72,12 +79,19 @@ class front_insert_iterator { // wrap pushes to front of container as output ite
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;

using container_type = _Container;

#ifdef __cpp_lib_concepts
using difference_type = ptrdiff_t;

constexpr front_insert_iterator() noexcept = default;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
using difference_type = void;
#endif // __cpp_lib_concepts

explicit front_insert_iterator(_Container& _Cont) : container(_STD addressof(_Cont)) {}

front_insert_iterator& operator=(const typename _Container::value_type& _Val) { // push value into container
Expand All @@ -103,7 +117,7 @@ public:
}

protected:
_Container* container; // pointer to container
_Container* container = nullptr;
};

// FUNCTION TEMPLATE front_inserter
Expand All @@ -119,12 +133,19 @@ class insert_iterator { // wrap inserts into container as output iterator
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = void;
using pointer = void;
using reference = void;

using container_type = _Container;

#ifdef __cpp_lib_concepts
using difference_type = ptrdiff_t;

insert_iterator() = default;
#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv
using difference_type = void;
#endif // __cpp_lib_concepts

insert_iterator(_Container& _Cont, typename _Container::iterator _Where)
: container(_STD addressof(_Cont)), iter(_Where) {}

Expand Down Expand Up @@ -155,8 +176,8 @@ public:
}

protected:
_Container* container; // pointer to container
typename _Container::iterator iter; // iterator into container
_Container* container = nullptr;
typename _Container::iterator iter{};
};

// FUNCTION TEMPLATE inserter
Expand Down
5 changes: 5 additions & 0 deletions tests/libcxx/skipped_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,11 @@ language.support\cmp\cmp.weakord\weakord.pass.cpp
# error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
containers\sequences\array\array.creation\to_array.pass.cpp

# Tests that need to learn that insert iterators have non-void difference type in C++20
iterators\predef.iterators\insert.iterators\back.insert.iterator\types.pass.cpp
iterators\predef.iterators\insert.iterators\front.insert.iterator\types.pass.cpp
iterators\predef.iterators\insert.iterators\insert.iterator\types.pass.cpp


# *** LIKELY STL BUGS ***
# Not yet analyzed, likely STL bugs. Assertions and other runtime failures.
Expand Down
25 changes: 25 additions & 0 deletions tests/std/tests/P0896R4_ranges_iterator_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#include <compare>
#include <concepts>
#include <iterator>
#include <list>
#include <type_traits>
#include <utility>
#include <vector>

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

Expand Down Expand Up @@ -2770,6 +2772,29 @@ namespace iter_ops {
}
} // namespace iter_ops

namespace insert_iterators {
template <class Container>
constexpr bool test() {
using std::back_insert_iterator, std::front_insert_iterator, std::insert_iterator;
using std::default_initializable, std::is_nothrow_default_constructible_v, std::iter_difference_t,
std::ptrdiff_t, std::same_as;

STATIC_ASSERT(default_initializable<back_insert_iterator<Container>>);
STATIC_ASSERT(is_nothrow_default_constructible_v<back_insert_iterator<Container>>);
STATIC_ASSERT(default_initializable<front_insert_iterator<Container>>);
STATIC_ASSERT(is_nothrow_default_constructible_v<front_insert_iterator<Container>>);
STATIC_ASSERT(default_initializable<insert_iterator<Container>>);
STATIC_ASSERT(same_as<iter_difference_t<back_insert_iterator<Container>>, ptrdiff_t>);
STATIC_ASSERT(same_as<iter_difference_t<front_insert_iterator<Container>>, ptrdiff_t>);
STATIC_ASSERT(same_as<iter_difference_t<insert_iterator<Container>>, ptrdiff_t>);

return true;
}

STATIC_ASSERT(test<std::list<double>>());
STATIC_ASSERT(test<std::vector<int>>());
} // namespace insert_iterators

int main() {
iterator_cust_swap_test::test();
iter_ops::test();
Expand Down

0 comments on commit e2da90b

Please sign in to comment.