• 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