libcruft-util/cruft/util/iterator/tuple_picker.hpp

67 lines
2.2 KiB
C++
Raw Permalink Normal View History

2021-02-05 13:03:18 +11:00
/*
* 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)
);
}
}