/* * 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 2010-2018 Danny Robson */ #pragma once namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// /// Adapts a supplied iterator by dereferencing any operations that deal /// with the underlying value_type of the supplied iterator. template struct dereference_adapter { //--------------------------------------------------------------------- using difference_type = typename std::iterator_traits::difference_type; using iterator_category = typename std::iterator_traits::iterator_category; using value_type = std::remove_reference_t< decltype( *std::declval< typename std::iterator_traits::value_type > () ) >; using pointer = value_type*; using reference = value_type&; //--------------------------------------------------------------------- dereference_adapter (IteratorT _cursor) : m_cursor (_cursor) { ; } //--------------------------------------------------------------------- // Trivial conditional operations decltype(auto) operator== (dereference_adapter const &rhs) const { return m_cursor == rhs.m_cursor; } decltype(auto) operator!= (dereference_adapter const &rhs) const { return !(*this == rhs); } decltype(auto) operator<= (dereference_adapter const &rhs) const { return m_cursor <= rhs.m_cursor; } //--------------------------------------------------------------------- // Iterator movement operations dereference_adapter& operator++ () { ++m_cursor; return *this; } difference_type operator- (dereference_adapter const &rhs) const { return m_cursor - rhs.m_cursor; } auto operator+ (difference_type offset) const { return dereference_adapter { m_cursor + offset }; } //--------------------------------------------------------------------- // value_type operations decltype(auto) operator= (value_type const &rhs) { return **m_cursor = rhs; } decltype(auto) operator* () { return **m_cursor; } decltype(auto) operator-> () { return **m_cursor; } decltype(auto) operator* () const { return **m_cursor; } decltype(auto) operator-> () const { return **m_cursor; } private: IteratorT m_cursor; }; }