diff --git a/adapter.cpp b/adapter.cpp index 6ce9bc10..82d66e3e 100644 --- a/adapter.cpp +++ b/adapter.cpp @@ -9,47 +9,15 @@ #include "adapter.hpp" -//#include -//#include -//#include -// -// -//using cruft::adapter::scalar; -// -// -//void -//foo (void) { -// std::vector> vals; -// -// using iterator_t = cruft::adapter::scalar<0, decltype(vals.begin ())>; -// -// static_assert ( -// std::is_same< -// typename std::iterator_traits< -// decltype(vals.begin ()) -// >::value_type, -// std::tuple -// >::value -// ); -// -// static_assert ( -// std::is_same< -// typename std::tuple_element<0, std::tuple>::type, -// int -// >::value -// ); -// -// iterator_t end (vals.end ()); -// -// //static_assert ( -// // std::is_same< -// // typename iterator_t::reference, -// // //decltype(*std::declval >> ()), -// // //typename scalar<0,decltype(vals.begin ())>::value_type, -// // int& -// // >::value -// //); -// -// for (auto p = iterator_t (vals.begin ()), last = iterator_t (vals.end ()); p != last; ++p) -// int b = *p; -//} +#include "concepts/named.hpp" +#include + +static std::array v; +static cruft::adapter::container::transform t (v, [](auto const&) { return false; }); + +static_assert ( + std::is_same_v< + typename std::iterator_traits::value_type, + bool + > +); \ No newline at end of file diff --git a/adapter.hpp b/adapter.hpp index 190968cc..3d4f4e63 100644 --- a/adapter.hpp +++ b/adapter.hpp @@ -3,14 +3,15 @@ * 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-2019 Danny Robson + * Copyright 2015-2022 Danny Robson */ +#include "concepts/named.hpp" + #include #include #include - namespace cruft::adapter { namespace container { /// An identity proxy for a referenced container. @@ -93,6 +94,95 @@ namespace cruft::adapter { private: T &m_target; }; + + + template < + typename ContainerT, + typename FunctionT + > + requires ( + std::is_invocable_v< + FunctionT, + typename std::iterator_traits::value_type + > + ) + class transform { + public: + using value_type = std::invoke_result_t< + FunctionT, + typename std::iterator_traits::value_type + >; + using pointer = void; + using reference = void; + + using difference_type = typename std::iterator_traits< + typename ContainerT::iterator + >::difference_type; + + + template + transform (_ContainerT &&_container, _FunctionT &&_function) + : m_container (std::forward<_ContainerT> (_container)) + , m_function (std::forward< _FunctionT> (_function )) + { ; } + + auto begin (void) const { return iterator (m_container.begin (), m_function); } + auto end (void) const { return iterator (m_container.end (), m_function); } + + class iterator { + private: + using underlying = typename ContainerT::iterator; + + public: + // HACK: We really should be using the underlying iterator's + // category. However it's a massive PITA to write this code + // right now. + using iterator_category = std::forward_iterator_tag; //typename std::iterator_traits::iterator_category; + using difference_type = typename std::iterator_traits::difference_type; + using value_type = transform::value_type; + using pointer = void; + using reference = void; + + iterator ( + typename ContainerT::iterator _cursor, + FunctionT const &_function + ) + : m_cursor (_cursor) + , m_function (_function) + { ; } + + decltype(auto) operator* () + { + return m_function (*m_cursor); + } + + iterator& operator++ ()& + { + ++m_cursor; + return *this; + } + + bool operator== (iterator const &rhs) const noexcept + { + return m_cursor == rhs.m_cursor; + } + + private: + typename ContainerT::iterator m_cursor; + FunctionT const &m_function; + }; + + private: + ContainerT m_container; + FunctionT m_function; + + }; + + template + transform (ContainerT, FunctionT) -> transform< + std::remove_cvref_t, + std::remove_cvref_t< FunctionT> + >; } diff --git a/iterator/transform.hpp b/iterator/transform.hpp index 39e4578e..3f3f49d8 100644 --- a/iterator/transform.hpp +++ b/iterator/transform.hpp @@ -8,6 +8,12 @@ #pragma once +#include "../view.hpp" + +#include +#include + + namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// template