• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
node_iteratornode_iterator32     constexpr node_iterator() noexcept : it_(nullptr) {}
node_iteratornode_iterator33     constexpr node_iterator(node<T> * it) noexcept : it_(it) {}
34     //]
35 
36     //[ node_iterator_user_ops
operator *node_iterator37     constexpr T & operator*() const noexcept { return it_->value_; }
operator ++node_iterator38     constexpr node_iterator & operator++() noexcept
39     {
40         it_ = it_->next_;
41         return *this;
42     }
43     friend constexpr bool
operator ==(node_iterator lhs,node_iterator rhs)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.
BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(node_iterator,std::forward_iterator)63 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(node_iterator, std::forward_iterator)
64 //]
65 
66 
67 int main()
68 {
69     std::array<node<int>, 5> nodes;
70     std::generate(nodes.begin(), nodes.end(), [] {
71         static int i = 0;
72         return node<int>{i++};
73     });
74     std::adjacent_find(
75         nodes.begin(), nodes.end(), [](node<int> & a, node<int> & b) {
76             a.next_ = &b;
77             return false;
78         });
79     nodes.back().next_ = nullptr;
80 
81     //[ node_iterator_usage
82     node_iterator<int> const first(&nodes[0]);
83     node_iterator<int> const last;
84     for (auto it = first; it != last; it++) {
85         std::cout << *it << " "; // Prints 0 1 2 3 4
86     }
87     std::cout << "\n";
88     //]
89 }
90