67 lines
2.2 KiB
C++
67 lines
2.2 KiB
C++
/*
|
|
* 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)
|
|
);
|
|
}
|
|
} |