libcruft-util/iterator/cast.hpp

70 lines
2.0 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 2020, Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include <iterator>
namespace cruft::iterator {
///////////////////////////////////////////////////////////////////////////
/// An iterator that converts the value_type of an underlying iterator to
/// a requested type.
template <typename ValueT, typename IteratorT>
class cast {
public:
cast (IteratorT _inner)
: m_inner (_inner)
{ ; }
using iterator_category = typename std::iterator_traits<IteratorT>::iterator_category;
using value_type = ValueT;
using difference_type = typename std::iterator_traits<IteratorT>::difference_type;
using pointer = value_type*;
using reference = value_type&;
class wrapper {
public:
using inner_value = typename std::iterator_traits<IteratorT>::value;
using inner_pointer = typename std::iterator_traits<IteratorT>::pointer;
using inner_reference = typename std::iterator_traits<IteratorT>::reference;
reference
operator= (ValueT const &val)
{
_value = static_cast<inner_value> (val);
return _value;
}
reference operator= (ValueT &&val)
{
_value = static_cast<inner_value> (val);
}
inner_pointer
operator-> ()
{ return &_value; }
private:
inner_reference _value;
};
wrapper operator* (void) { return wrapper (*m_inner); };
wrapper operator-> (void) { return wrapper (*m_inner); };
cast& operator++ (void)
{
++m_inner;
return *this;
}
private:
IteratorT m_inner;
};
}