2019-03-18 16:18:27 +11:00
|
|
|
/*
|
|
|
|
* 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 <danny@nerdcruft.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2022-06-23 10:58:17 +10:00
|
|
|
#include "../view.hpp"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
2019-03-18 16:18:27 +11:00
|
|
|
namespace cruft::iterator {
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename OutputIt, typename FunctionT>
|
|
|
|
OutputIt
|
|
|
|
_transform_by_block (
|
|
|
|
const cruft::view<OutputIt> &,
|
|
|
|
OutputIt cursor,
|
|
|
|
FunctionT &&
|
|
|
|
) {
|
|
|
|
return cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
template <typename OutputIt, typename FunctionT, typename InputT, typename ...TailT>
|
|
|
|
OutputIt
|
|
|
|
_transform_by_block (
|
|
|
|
const cruft::view<OutputIt> &dst,
|
|
|
|
OutputIt cursor,
|
|
|
|
FunctionT &&func,
|
|
|
|
const InputT &_src,
|
|
|
|
TailT &&...tail
|
|
|
|
) {
|
|
|
|
auto remain = _src;
|
|
|
|
if (cursor != dst.begin ()) {
|
|
|
|
auto infill = std::distance (cursor, dst.end ());
|
|
|
|
if (remain.size () < static_cast<size_t> (infill)) {
|
|
|
|
return _transform_by_block (
|
|
|
|
dst,
|
|
|
|
std::copy_n (remain.begin (), remain.size (), cursor),
|
|
|
|
std::forward<FunctionT> (func),
|
|
|
|
std::forward<TailT> (tail)...
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::copy_n (remain.begin (), infill, cursor);
|
|
|
|
func (dst);
|
|
|
|
cursor = dst.begin ();
|
|
|
|
remain = { remain.begin () + infill, remain.end () };
|
|
|
|
}
|
|
|
|
|
|
|
|
while (remain.size () >= dst.size ()) {
|
|
|
|
std::copy_n (remain.begin (), dst.size (), dst.begin ());
|
|
|
|
func (dst);
|
|
|
|
remain = { remain.begin () + dst.size (), remain.end () };
|
|
|
|
}
|
|
|
|
|
|
|
|
return _transform_by_block (
|
|
|
|
dst,
|
|
|
|
std::copy (remain.begin (), remain.end (), cursor),
|
|
|
|
std::forward<FunctionT> (func),
|
|
|
|
std::forward<TailT> (tail)...
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
template <typename OutputIt, typename FunctionT, typename ...Args>
|
|
|
|
OutputIt
|
|
|
|
transform_by_block (const cruft::view<OutputIt> &dst, FunctionT &&func, Args &&...src)
|
|
|
|
{
|
|
|
|
return _transform_by_block (
|
|
|
|
dst,
|
|
|
|
dst.begin (),
|
|
|
|
std::forward<FunctionT> (func),
|
|
|
|
std::forward<Args> (src)...
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|