/* * 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 2015-2018 Danny Robson */ #include #include #include namespace cruft::adapter { namespace container { /// Creates a reversed proxy for a referenced container. /// /// The target container must remain an l-value. /// /// It is the caller's job to ensure the targeted container remains /// valid for the duration of the proxy's lifetime. template class reverse { public: explicit reverse (T &_target): m_target (_target) { ; } auto begin (void) & { return m_target.rbegin (); } auto end (void) & { return m_target.rend (); } auto begin (void) const& { return m_target.rbegin (); } auto end (void) const& { return m_target.rend (); } auto cbegin (void) const& { return m_target.crbegin (); } auto cend (void) const& { return m_target.crend (); } private: T &m_target; }; //--------------------------------------------------------------------- template reverse (Container&) -> reverse; /////////////////////////////////////////////////////////////////////// /// Adapter's a container to return indices of the container's data /// rather than the values themselves. /// /// The targeted container must be an l-value. /// /// It is the caller's job to ensure the targeted container remains /// valid for the duration of the proxy's lifetime. template class indices { public: using typename T::size_type; explicit indices (T &_target): m_target (_target) { ; } size_type begin (void)& { return 0; } size_type end (void)& { return m_target.size (); } private: T &m_target; }; } namespace iterator { /////////////////////////////////////////////////////////////////////// /// Adapt's an iterator to return the n-th element of the tuple that /// corresponds to the underlying iterator::value_type when /// dereferenced. template struct scalar : public std::iterator< typename std::iterator_traits::iterator_category, typename std::tuple_element< I, typename std::iterator_traits< IteratorT >::value_type >::type, typename std::iterator_traits::difference_type > { public: using inner_type = typename std::iterator_traits::value_type; using value_type = decltype (std::get (std::declval ())); using reference = value_type&; using const_reference = value_type const&; explicit scalar (IteratorT _inner): m_inner (_inner) { ; } const_reference operator* (void) const& { return std::get (*m_inner); } reference operator* (void)& { return std::get (*m_inner); } bool operator== (scalar rhs) { return m_inner == rhs.m_inner; } bool operator!= (scalar rhs) { return m_inner != rhs.m_inner; } scalar& operator++ (void) { ++m_inner; return *this; } private: IteratorT m_inner; }; } }