// Copyright (C) 2022 T. Zachary Laine // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include struct node { using value_type = std::pair; value_type kv_; node * next_; }; template struct iterator : boost::stl_interfaces::iterator_interface< #if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS iterator, #endif std::forward_iterator_tag, Node> { using value_type = typename Node::value_type; constexpr iterator() noexcept = default; constexpr explicit iterator(Node * it) : it_{it} {} template< typename Node2, typename Enable = std::enable_if_t< std::is_convertible{} && !std::is_const{} && std::is_const{}>> constexpr iterator(iterator other) noexcept : it_{other.it_} {} constexpr value_type const & operator*() const noexcept { return it_->kv_; } template< typename T = Node, typename std::enable_if_t{}, bool> = true> constexpr value_type & operator*() noexcept { return it_->kv_; } constexpr iterator & operator++() noexcept { it_ = it_->next_; return *this; } using base_type = boost::stl_interfaces:: iterator_interface, std::forward_iterator_tag, Node>; using base_type::operator++; friend constexpr bool operator==(iterator lhs, iterator rhs) noexcept { return lhs.it_ == rhs.it_; } private: Node * it_; template friend struct iterator; }; void compile_sfinae_path_mutable_iterator() { auto it = iterator{}; if ((*it).first == 42) { (*it).second = 13; } }