adapter: add container transform adapter
This commit is contained in:
parent
9451083f83
commit
2ee2806979
56
adapter.cpp
56
adapter.cpp
@ -9,47 +9,15 @@
|
||||
|
||||
#include "adapter.hpp"
|
||||
|
||||
//#include <vector>
|
||||
//#include <tuple>
|
||||
//#include <iostream>
|
||||
//
|
||||
//
|
||||
//using cruft::adapter::scalar;
|
||||
//
|
||||
//
|
||||
//void
|
||||
//foo (void) {
|
||||
// std::vector<std::tuple<int,int,int>> 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<int,int,int>
|
||||
// >::value
|
||||
// );
|
||||
//
|
||||
// static_assert (
|
||||
// std::is_same<
|
||||
// typename std::tuple_element<0, std::tuple<int,int,int>>::type,
|
||||
// int
|
||||
// >::value
|
||||
// );
|
||||
//
|
||||
// iterator_t end (vals.end ());
|
||||
//
|
||||
// //static_assert (
|
||||
// // std::is_same<
|
||||
// // typename iterator_t::reference,
|
||||
// // //decltype(*std::declval <scalar<0,std::tuple<int,int,int>>> ()),
|
||||
// // //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 <array>
|
||||
|
||||
static std::array<int,5> v;
|
||||
static cruft::adapter::container::transform t (v, [](auto const&) { return false; });
|
||||
|
||||
static_assert (
|
||||
std::is_same_v<
|
||||
typename std::iterator_traits<decltype(t)::iterator>::value_type,
|
||||
bool
|
||||
>
|
||||
);
|
94
adapter.hpp
94
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 <danny@nerdcruft.net>
|
||||
* Copyright 2015-2022 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "concepts/named.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
|
||||
|
||||
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<typename ContainerT::iterator>::value_type
|
||||
>
|
||||
)
|
||||
class transform {
|
||||
public:
|
||||
using value_type = std::invoke_result_t<
|
||||
FunctionT,
|
||||
typename std::iterator_traits<typename ContainerT::iterator>::value_type
|
||||
>;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
|
||||
using difference_type = typename std::iterator_traits<
|
||||
typename ContainerT::iterator
|
||||
>::difference_type;
|
||||
|
||||
|
||||
template <typename _ContainerT, typename _FunctionT>
|
||||
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<underlying>::iterator_category;
|
||||
using difference_type = typename std::iterator_traits<underlying>::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 <typename ContainerT, typename FunctionT>
|
||||
transform (ContainerT, FunctionT) -> transform<
|
||||
std::remove_cvref_t<ContainerT>,
|
||||
std::remove_cvref_t< FunctionT>
|
||||
>;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../view.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace cruft::iterator {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename OutputIt, typename FunctionT>
|
||||
|
Loading…
Reference in New Issue
Block a user