Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
600a282
[libc++] P2770R0: "Stashing stashing iterators for proper flattening"
JMazurkiewicz Sep 8, 2023
743b01d
Merge branch 'main' into libcxx/ranges/stashing2
JMazurkiewicz Nov 27, 2023
f601c07
Enable `__as_lvalue` in >C++03 modes
JMazurkiewicz Nov 27, 2023
be16b57
Split `as-lvalue.verify.cpp`
JMazurkiewicz Nov 27, 2023
181cd85
Add missing `explicit` specifier in `__iterator(_Parent& __parent)`
JMazurkiewicz Nov 27, 2023
d11d81c
Restore old `__sentinel<C>` friendship in `join_view::_sentinel`
JMazurkiewicz Nov 27, 2023
03454c2
Un-experimental more `join_view` related tests
JMazurkiewicz Nov 27, 2023
7de9a77
Make `join_view::__iterator::__outer_` private
JMazurkiewicz Nov 27, 2023
f256e1f
Add test with code from LWG-3698
JMazurkiewicz Nov 27, 2023
1f00358
Whitespace amendments
JMazurkiewicz Nov 27, 2023
d5d0610
Add extra static assertion for `[range.join.iterator] Note 1`
JMazurkiewicz Nov 27, 2023
3861ffa
Fix comment: `!forward_range<iterator_t<Base>>` -> `!forward_range<Ba…
JMazurkiewicz Nov 27, 2023
0e92781
Make `as-lvalue.pass.cpp` C++11 friendly
JMazurkiewicz Nov 27, 2023
54c31fc
Add `return 0;` in LWG-3698 test
JMazurkiewicz Nov 29, 2023
62fa3a7
Revert "Make `as-lvalue.pass.cpp` C++11 friendly"
JMazurkiewicz Nov 29, 2023
aebbbac
Make `as-lvalue.pass.cpp` C++14 friendly
JMazurkiewicz Nov 29, 2023
ca61a70
Test `iterator(Parent& parent, OuterIter outer)` constructor
JMazurkiewicz Dec 5, 2023
024b9e2
Test `iterator(Parent& parent)` constructor
JMazurkiewicz Dec 5, 2023
857aae1
Merge branch 'main' into libcxx/ranges/stashing
JMazurkiewicz Dec 5, 2023
710398a
Address GCC's complaints
JMazurkiewicz Dec 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Test iterator(Parent& parent, OuterIter outer) constructor
Comments:
* #66033 (comment)
* #66033 (comment) (partially)
  • Loading branch information
JMazurkiewicz committed Dec 5, 2023
commit ca61a7060e4f0004da00fabd2ace58f8d523ccff
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//===----------------------------------------------------------------------===//
//
// 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

// constexpr iterator(Parent& parent, OuterIter outer)
// requires forward_range<Base>; // exposition only

#include <cassert>
#include <ranges>
#include <string>
#include <utility>

#include "types.h"

constexpr bool test() {
std::string strings[4] = {"aaaa", "bbbb", "cccc", "dddd"};

{ // Check if `outer_` is initialized with `std::move(outer)` for `iterator<false>`
MoveOnAccessSubrange r(DieOnCopyIterator(strings), sentinel_wrapper(strings + 4));
std::ranges::join_view jv(std::move(r));
auto iter = jv.begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
assert(*iter == 'a');
}

{ // Check if `outer_` is initialized with `std::move(outer)` for `iterator<true>`
MoveOnAccessSubrange r(DieOnCopyIterator(strings), sentinel_wrapper(strings + 4));
std::ranges::join_view jv(std::ranges::ref_view{r});
auto iter = std::as_const(jv).begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
assert(*iter == 'a');
}

{
// LWG3569 Inner iterator not default_initializable
// With the current spec, the constructor under test invokes Inner iterator's default constructor
// even if it is not default constructible.
// This test is checking that this constructor can be invoked with an inner range with non default
// constructible iterator.
using NonDefaultCtrIter = cpp20_input_iterator<int*>;
static_assert(!std::default_initializable<NonDefaultCtrIter>);
using NonDefaultCtrIterView = BufferView<NonDefaultCtrIter, sentinel_wrapper<NonDefaultCtrIter>>;
static_assert(std::ranges::input_range<NonDefaultCtrIterView>);

int buffer[2][2] = {{1, 2}, {3, 4}};
NonDefaultCtrIterView inners[] = {buffer[0], buffer[1]};
auto outer = std::views::all(inners);
std::ranges::join_view jv(outer);
auto iter = jv.begin(); // Calls `iterator(Parent& parent, OuterIter outer)`
assert(*iter == 1);
}

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//===----------------------------------------------------------------------===//
//
// 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 TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H
#define TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H

#include <cassert>
#include <cstddef>
#include <ranges>

#include "test_iterators.h"

template <std::forward_iterator Iter>
struct DieOnCopyIterator {
using value_type = std::iter_value_t<Iter>;
using difference_type = std::iter_difference_t<Iter>;

DieOnCopyIterator() = default;
constexpr explicit DieOnCopyIterator(Iter iter) : iter_(std::move(iter)) {}
constexpr DieOnCopyIterator(DieOnCopyIterator&& other) = default;
DieOnCopyIterator& operator=(DieOnCopyIterator&&) = default;

constexpr DieOnCopyIterator(const DieOnCopyIterator&) { assert(false); }
constexpr DieOnCopyIterator& operator=(const DieOnCopyIterator&) { assert(false); }

constexpr DieOnCopyIterator& operator++() {
++iter_;
return *this;
}

constexpr void operator++(int) { iter_++; }

constexpr DieOnCopyIterator operator++(int)
requires std::forward_iterator<Iter>
{
auto tmp = *this;
++tmp;
return tmp;
}

constexpr decltype(auto) operator*() const { return *iter_; }

friend constexpr bool operator==(const DieOnCopyIterator& left, const DieOnCopyIterator& right)
requires std::equality_comparable<Iter>
{
return left.iter_ == right.iter_;
}

friend constexpr bool operator==(const DieOnCopyIterator& it, const sentinel_wrapper<Iter>& se) {
return it.iter_ == se;
}

private:
Iter iter_ = Iter();
};

template <class Iter>
explicit DieOnCopyIterator(Iter) -> DieOnCopyIterator<Iter>;

static_assert(std::forward_iterator<DieOnCopyIterator<int*>>);
static_assert(!std::bidirectional_iterator<DieOnCopyIterator<int*>>);
static_assert(std::sentinel_for<sentinel_wrapper<int*>, DieOnCopyIterator<int*>>);

template <std::input_iterator Iter, std::sentinel_for<Iter> Sent = Iter>
struct MoveOnAccessSubrange : std::ranges::view_base {
constexpr explicit MoveOnAccessSubrange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {}

MoveOnAccessSubrange(MoveOnAccessSubrange&&) = default;
MoveOnAccessSubrange& operator=(MoveOnAccessSubrange&&) = default;

MoveOnAccessSubrange(const MoveOnAccessSubrange&) = delete;
MoveOnAccessSubrange& operator=(const MoveOnAccessSubrange&) = delete;

constexpr Iter begin() { return std::move(iter_); }
constexpr Sent end() { return std::move(sent_); }

private:
Iter iter_;
Sent sent_;
};

template <class Iter, class Sent>
MoveOnAccessSubrange(Iter, Sent) -> MoveOnAccessSubrange<Iter, Sent>;

static_assert(std::ranges::input_range<MoveOnAccessSubrange<int*, sentinel_wrapper<int*>>>);
static_assert(std::ranges::forward_range<MoveOnAccessSubrange<DieOnCopyIterator<int*>>>);

template <class Iter, class Sent>
requires(!std::same_as<Iter, Sent>)
struct BufferView : std::ranges::view_base {
using T = std::iter_value_t<Iter>;
T* data_;
std::size_t size_;

template <std::size_t N>
constexpr BufferView(T (&b)[N]) : data_(b), size_(N) {}

constexpr Iter begin() const { return Iter(data_); }
constexpr Sent end() const { return Sent(Iter(data_ + size_)); }
};

static_assert(std::ranges::input_range<BufferView<int*, sentinel_wrapper<int*>>>);

#endif // TEST_LIBCXX_RANGES_RANGE_ADAPTORS_RANGE_JOIN_RANGE_JOIN_ITERATOR_TYPES_H