From c157b1637a18419e78902092464a9bb7dc4d3ba9 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Mon, 5 Dec 2022 20:11:03 -0600 Subject: [PATCH] Add a test to cover #59 so that it does not pop up again. Fixes #60. --- test/CMakeLists.txt | 1 + test/Jamfile.v2 | 1 + test/compile_sfinae_path_mutable_iterator.cpp | 77 +++++++++++++++++++ test/compile_tests_main.cpp | 2 + 4 files changed, 81 insertions(+) create mode 100644 test/compile_sfinae_path_mutable_iterator.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 19d8d2b..ac69786 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -49,6 +49,7 @@ add_executable( compile_tests compile_tests_main.cpp compile_seq_cont_rvalue_constrained_pop_back.cpp + compile_sfinae_path_mutable_iterator.cpp ) target_link_libraries(compile_tests stl_interfaces) if (clang_on_linux) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 4a4efac..d728ec8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -26,3 +26,4 @@ run random_access.cpp ; run static_vec.cpp ; compile compile_seq_cont_rvalue_constrained_pop_back.cpp ; +compile compile_sfinae_path_mutable_iterator.cpp ; diff --git a/test/compile_sfinae_path_mutable_iterator.cpp b/test/compile_sfinae_path_mutable_iterator.cpp new file mode 100644 index 0000000..1528609 --- /dev/null +++ b/test/compile_sfinae_path_mutable_iterator.cpp @@ -0,0 +1,77 @@ +// 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< + iterator, + 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_v && + !std::is_const_v && std::is_const_v>> + 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< + iterator, + 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; + } +} diff --git a/test/compile_tests_main.cpp b/test/compile_tests_main.cpp index 9da4759..a75764f 100644 --- a/test/compile_tests_main.cpp +++ b/test/compile_tests_main.cpp @@ -4,8 +4,10 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) void compile_seq_cont_constrained_pop_back(); +void compile_sfinae_path_mutable_iterator(); int main() { compile_seq_cont_constrained_pop_back(); + compile_sfinae_path_mutable_iterator(); }