]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // Copyright (C) 2019 T. Zachary Laine |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See | |
4 | // accompanying file LICENSE_1_0.txt or copy at | |
5 | // http://www.boost.org/LICENSE_1_0.txt) | |
6 | #include <boost/stl_interfaces/iterator_interface.hpp> | |
7 | ||
8 | #include <algorithm> | |
9 | #include <array> | |
10 | #include <iostream> | |
11 | ||
12 | #include <cassert> | |
13 | ||
14 | ||
15 | //[ node_defn | |
16 | template<typename T> | |
17 | struct node | |
18 | { | |
19 | T value_; | |
20 | node * next_; // == nullptr in the tail node | |
21 | }; | |
22 | //] | |
23 | ||
24 | //[ node_iterator_class_head | |
25 | template<typename T> | |
26 | struct node_iterator | |
27 | : boost::stl_interfaces:: | |
28 | iterator_interface<node_iterator<T>, std::forward_iterator_tag, T> | |
29 | //] | |
30 | { | |
31 | //[ node_iterator_ctors | |
32 | constexpr node_iterator() noexcept : it_(nullptr) {} | |
33 | constexpr node_iterator(node<T> * it) noexcept : it_(it) {} | |
34 | //] | |
35 | ||
36 | //[ node_iterator_user_ops | |
37 | constexpr T & operator*() const noexcept { return it_->value_; } | |
38 | constexpr node_iterator & operator++() noexcept | |
39 | { | |
40 | it_ = it_->next_; | |
41 | return *this; | |
42 | } | |
43 | friend constexpr bool | |
44 | operator==(node_iterator lhs, node_iterator rhs) noexcept | |
45 | { | |
46 | return lhs.it_ == rhs.it_; | |
47 | } | |
48 | //] | |
49 | ||
50 | //[ node_iterator_using_declaration | |
51 | using base_type = boost::stl_interfaces:: | |
52 | iterator_interface<node_iterator<T>, std::forward_iterator_tag, T>; | |
53 | using base_type::operator++; | |
54 | //] | |
55 | ||
56 | private: | |
57 | node<T> * it_; | |
58 | }; | |
59 | ||
60 | //[ node_iterator_concept_check Equivalent to | |
61 | // static_assert(std::forward_iterator<node_iterator>, ""), or nothing in | |
62 | // C++17 and earlier. | |
1e59de90 TL |
63 | BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT( |
64 | node_iterator<int>, std::forward_iterator) | |
20effc67 TL |
65 | //] |
66 | ||
67 | ||
68 | int main() | |
69 | { | |
70 | std::array<node<int>, 5> nodes; | |
71 | std::generate(nodes.begin(), nodes.end(), [] { | |
72 | static int i = 0; | |
73 | return node<int>{i++}; | |
74 | }); | |
75 | std::adjacent_find( | |
76 | nodes.begin(), nodes.end(), [](node<int> & a, node<int> & b) { | |
77 | a.next_ = &b; | |
78 | return false; | |
79 | }); | |
80 | nodes.back().next_ = nullptr; | |
81 | ||
82 | //[ node_iterator_usage | |
83 | node_iterator<int> const first(&nodes[0]); | |
84 | node_iterator<int> const last; | |
85 | for (auto it = first; it != last; it++) { | |
86 | std::cout << *it << " "; // Prints 0 1 2 3 4 | |
87 | } | |
88 | std::cout << "\n"; | |
89 | //] | |
90 | } |