/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2021, Danny Robson */ #pragma once #include #include #include #include /////////////////////////////////////////////////////////////////////////////// namespace cruft::iterator { /// An iterator adapter that returns the tuple_element at IndexV for the /// underlying iterator when dereferenced. template class tuple_picker { public: using iterator_category = typename std::iterator_traits::iterator_category; using value_type = std::tuple_element_t< IndexV, // Ideally we'd use iterator_traits::value_type but that removes // constness from value_type for pointers to const, and we need to // retain const semantics to support some existing cases (like // map::keys queries). std::remove_reference_t ())> >; using difference_type = typename std::iterator_traits::difference_type; using pointer = value_type*; using reference = value_type&; tuple_picker (IteratorT _cursor) : m_cursor (_cursor) { ; } reference operator* () { return std::get (*m_cursor); } tuple_picker& operator++ () { ++m_cursor; return *this; } auto operator<=> (tuple_picker const &rhs) const = default; private: IteratorT m_cursor; }; /// A convenience constructor for tuple_picker. /// /// Provided in-lieu of a user deduction guide so that partial template /// parameters can be provided. ie, make_tuple_picker<1> (iter). template auto make_tuple_picker (IteratorT &&iterator) { return tuple_picker< IndexV, std::remove_reference_t > ( std::forward (iterator) ); } }