Skip to content

Commit

Permalink
#60 Added Associate operation and transform operation
Browse files Browse the repository at this point in the history
  • Loading branch information
xthebat committed Feb 11, 2024
1 parent d663d9f commit 6e2dc1c
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 4 deletions.
43 changes: 43 additions & 0 deletions Source/Cloud9/Tests/Unit/Tools/TestContainer.spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,48 @@ void FRangeSpec::Define()
| ETContainer::ToArray{};
TestEqual("Result == {3, 4, 5}", Result, {3, 4, 5});
});

It("Transform", [=]
{
{
let Result = Container
| ETContainer::Transform{[&](let It) { return It * 2; }}
| ETContainer::ToArray{};
TestEqual("Result == {2, 4, 6, 8, 10}", Result, {2, 4, 6, 8, 10});
}

{
let Result = Container
| ETContainer::Transform{[&](let It) { return It; }}
| ETContainer::ToArray{};
TestEqual("Result == {1, 2, 3, 4, 5}", Result, {1, 2, 3, 4, 5});
}
});

It("Associate", [=]
{
let Result = Container
| ETContainer::Associate
{
[&](let It) { return It; },
[&](let It) { return static_cast<float>(It) / 2.0f; }
};

let Expected = TMap<int, float>{
{1, 0.5f},
{2, 1.0f},
{3, 1.5f},
{4, 2.0f},
{5, 2.5f},
};

for (let It : Result)
{
let Key = It.Get<0>();
let Value = It.Get<1>();
TestTrue("Contains Result / 2.0f", Expected.Contains(Key));
TestEqual("Result / 2.0f", Value, Expected[Key]);
}
});
});
}
94 changes: 90 additions & 4 deletions Source/Cloud9/Tools/Extensions/TContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ namespace ETIterator

namespace Private_ETContainer
{
template <typename OperatorType, typename ContainerType>
struct TTransformIterator;

template <typename OperatorType, typename ContainerType>
struct TFilterIterator;

Expand Down Expand Up @@ -102,17 +105,64 @@ namespace ETContainer
{
for (let& It : Self)
{
if constexpr (TIsSame<decltype(It), int>::Value)
{
log(Error, "%d", It);
}
Block(It);
}
}

OPERATOR_BODY(ForEach)
};

template <typename BlockType>
struct ForEachIndexed
{
const BlockType& Block;

template <typename ContainerType>
constexpr void operator()(ContainerType&& Self) const
{
int Index = 0;
for (let& It : Self)
{
Block(Index++, It);
}
}

OPERATOR_BODY(ForEachIndexed)
};

template <typename KeyBlockType, typename ValueBlockType>
struct Associate
{
const KeyBlockType& KeyBlock;
const ValueBlockType& ValueBlock;

template <typename ContainerType>
constexpr auto operator()(ContainerType&& Self) const
{
using FKeyType = typename TInvokeResult<KeyBlockType, typename ContainerType::ElementType>::Type;
using FValueType = typename TInvokeResult<ValueBlockType, typename ContainerType::ElementType>::Type;

TMap<FKeyType, FValueType> Output;
for (let& It : Self)
{
Output.Emplace(KeyBlock(It), ValueBlock(It));
}
return Output;
}

OPERATOR_BODY(Associate)
};

template <typename InOperationType>
struct Transform
{
using OperationType = InOperationType;

const OperationType& Operation;

SEQUENCE_OPERATOR_BODY(Transform, Private_ETContainer::TTransformIterator)
};

template <typename PredicateType>
struct Filter
{
Expand Down Expand Up @@ -249,6 +299,42 @@ namespace ETContainer

namespace Private_ETContainer
{
template <typename OperatorType, typename ContainerType>
struct TTransformIterator
{
using ElementType = typename TInvokeResult<
typename OperatorType::OperationType,
typename TDecay<ContainerType>::Type::ElementType
>::Type;

constexpr TTransformIterator(ContainerType&& Container, OperatorType&& Operator)
: Container(Container)
, Iterator(Container.CreateConstIterator())
, Operator(Operator) {}

// ReSharper disable once CppMemberFunctionMayBeStatic
constexpr void Initialize() {}

constexpr TTransformIterator& operator++()
{
++Iterator;
return *this;
}

// constexpr const ElementType& operator->() const { return Iterator; }

constexpr ElementType operator*() const { return Operator.Operation(*Iterator); }

constexpr explicit operator bool() const { return not Iterator; }

private:
using IteratorType = typename TDecay<ContainerType>::Type::TConstIterator;

ContainerType Container;
IteratorType Iterator;
OperatorType Operator;
};

template <typename OperatorType, typename ContainerType>
struct TFilterIterator
{
Expand Down

0 comments on commit 6e2dc1c

Please sign in to comment.