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