From a512370240c2af93075b240354afef172f927c52 Mon Sep 17 00:00:00 2001 From: Mateusz Adamczyk Date: Thu, 3 Oct 2019 09:42:24 +0200 Subject: [PATCH] Batch filter --- src/filters.cpp | 51 ++++++++++++++++++++++++++++++++++++++++--- src/filters.h | 4 ++++ test/filters_test.cpp | 19 ++++++++++++++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/filters.cpp b/src/filters.cpp index 340d5508..a23a1d8a 100644 --- a/src/filters.cpp +++ b/src/filters.cpp @@ -779,16 +779,61 @@ InternalValue Serialize::Filter(const InternalValue&, RenderContext&) return InternalValue(); } -Slice::Slice(FilterParams, Slice::Mode) +Slice::Slice(FilterParams params, Slice::Mode mode) + : m_mode{mode} { - + if(m_mode == BatchMode) + { + ParseParams({{"linecount"s, true}, {"fill_with"s, false}}, params); + } } -InternalValue Slice::Filter(const InternalValue&, RenderContext&) +InternalValue Slice::Filter(const InternalValue& baseVal, RenderContext& context) { + if(m_mode == BatchMode) + return Batch(baseVal, context); + return InternalValue(); } +InternalValue Slice::Batch(const InternalValue& baseVal, RenderContext& context) +{ + auto linecount_value = ConvertToInt(GetArgumentValue("linecount", context)); + InternalValue fillWith = GetArgumentValue("fill_with", context); + + if(linecount_value <= 0) + return InternalValue(); + auto linecount = static_cast(linecount_value); + + bool isConverted = false; + auto list = ConvertToList(baseVal, isConverted); + if (!isConverted) + return InternalValue(); + + auto elementsCount = list.GetSize().value_or(0); + if(!elementsCount) + return InternalValue(); + + InternalValueList resultList; + resultList.reserve(linecount); + + const auto remainder = elementsCount % linecount; + const auto columns = elementsCount / linecount + (remainder > 0 ? 1 : 0); + for(std::size_t line = 0, idx = 0; line < linecount; ++line) + { + const auto elems = columns - (remainder && line >= remainder ? 1 : 0); + InternalValueList row; + row.reserve(columns); + std::fill_n(std::back_inserter(row), columns, fillWith); + + for(std::size_t column = 0; column < elems; ++column) + row[column] = list.GetValueByIndex(idx++); + + resultList.push_back(ListAdapter::CreateAdapter(std::move(row))); + } + return ListAdapter::CreateAdapter(std::move(resultList)); +} + StringFormat::StringFormat(FilterParams, StringFormat::Mode) { diff --git a/src/filters.h b/src/filters.h index f7f683a0..2c1c0b43 100644 --- a/src/filters.h +++ b/src/filters.h @@ -154,6 +154,10 @@ class Slice : public FilterBase Slice(FilterParams params, Mode mode); InternalValue Filter(const InternalValue& baseVal, RenderContext& context); +private: + InternalValue Batch(const InternalValue& baseVal, RenderContext& context); + + Mode m_mode; }; class Sort : public FilterBase diff --git a/test/filters_test.cpp b/test/filters_test.cpp index b31a146f..54365380 100644 --- a/test/filters_test.cpp +++ b/test/filters_test.cpp @@ -489,3 +489,22 @@ INSTANTIATE_TEST_CASE_P(Escape, FilterGenericTest, ::testing::Values( InputOutputPair{"'abcd&>