iterator: add tuple_picker adapter

This commit is contained in:
Danny Robson 2021-02-05 12:03:18 +10:00
parent 774ccb763d
commit 146996c4ef
2 changed files with 68 additions and 0 deletions

View File

@ -426,6 +426,7 @@ list (
iterator/placement_output.hpp
iterator/referencing.hpp
iterator/transform.hpp
iterator/tuple_picker.hpp
iterator/unequal.hpp
iterator/unordered_insert.hpp
iterator/zip.hpp

67
iterator/tuple_picker.hpp Normal file
View File

@ -0,0 +1,67 @@
/*
* 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 <danny@nerdcruft.net>
*/
#pragma once
#include <iterator>
#include <tuple>
#include <type_traits>
#include <compare>
///////////////////////////////////////////////////////////////////////////////
namespace cruft::iterator {
/// An iterator adapter that returns the tuple_element at IndexV for the
/// underlying iterator when dereferenced.
template <std::size_t IndexV, typename IteratorT>
class tuple_picker {
public:
using iterator_category = typename std::iterator_traits<IteratorT>::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<decltype(*std::declval<IteratorT> ())>
>;
using difference_type = typename std::iterator_traits<IteratorT>::difference_type;
using pointer = value_type*;
using reference = value_type&;
tuple_picker (IteratorT _cursor)
: m_cursor (_cursor)
{ ; }
reference operator* () { return std::get<IndexV> (*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 <std::size_t IndexV, typename IteratorT>
auto
make_tuple_picker (IteratorT &&iterator)
{
return tuple_picker<
IndexV,
std::remove_reference_t<IteratorT>
> (
std::forward<IteratorT> (iterator)
);
}
}