Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE > Class Template Reference

#include <FunctionalApplication.h>

Inheritance diagram for Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE >:
Stroika::Foundation::Traversal::Iterable< T >

Public Member Functions

template<typename OUT_T >
FunctionalApplicationContext< OUT_T, MAPPER_ENGINE > Map (const function< OUT_T(T)> &do2Each)
 
template<typename OUT_T >
OUT_T Reduce (const function< OUT_T(T, OUT_T)> &do2Each, OUT_T memo=OUT_T())
 
- Public Member Functions inherited from Stroika::Foundation::Traversal::Iterable< T >
 Iterable (const Iterable &) noexcept=default
 Iterable are safely copyable (by value). Since Iterable uses COW, this just copies the underlying pointer and increments the reference count.
 
 Iterable (Iterable &&) noexcept=default
 Iterable are safely moveable.
 
template<IIterableOfTo< T > CONTAINER_OF_T>
requires (not derived_from<remove_cvref_t<CONTAINER_OF_T>, Iterable<T>>)
 Iterable (CONTAINER_OF_T &&from)
 
 Iterable (const initializer_list< T > &from)
 
nonvirtual operator bool () const
 
nonvirtual Iterator< T > MakeIterator () const
 Create an iterator object which can be used to traverse the 'Iterable'.
 
nonvirtual size_t size () const
 Returns the number of items contained.
 
nonvirtual bool empty () const
 Returns true iff size() == 0.
 
template<Common::IPotentiallyComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual bool Contains (ArgByValueType< T > element, EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{}) const
 
nonvirtual Iterator< T > begin () const
 Support for ranged for, and STL syntax in general.
 
nonvirtual void Apply (const function< void(ArgByValueType< T > item)> &doToElement, Execution::SequencePolicy seq=Execution::SequencePolicy::eDEFAULT) const
 Run the argument function (or lambda) on each element of the container.
 
template<predicate< T > THAT_FUNCTION>
nonvirtual Iterator< T > Find (THAT_FUNCTION &&that, Execution::SequencePolicy seq=Execution::SequencePolicy::eDEFAULT) const
 Run the argument bool-returning function (or lambda) on each element of the container, and return an iterator pointing at the first element (depending on seq) found true. (or use First() to do same thing but return optional<>)
 
template<IIterableOfFrom< T > CONTAINER_OF_T, typename... CONTAINER_OF_T_CONSTRUCTOR_ARGS>
nonvirtual CONTAINER_OF_T As (CONTAINER_OF_T_CONSTRUCTOR_ARGS... args) const
 
nonvirtual T Nth (ptrdiff_t n) const
 Find the Nth element of the Iterable<>
 
nonvirtual T NthValue (ptrdiff_t n, ArgByValueType< T > defaultValue={}) const
 Find the Nth element of the Iterable<>, but allow for n to be out of range, and just return argument default-value.
 
template<derived_from< Iterable< T > > RESULT_CONTAINER = Iterable<T>, predicate< T > INCLUDE_PREDICATE>
nonvirtual RESULT_CONTAINER Where (INCLUDE_PREDICATE &&includeIfTrue) const
 produce a subset of this iterable where argument function returns true
 
template<Common::IPotentiallyComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual Iterable< T > Distinct (EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{}) const
 
template<ranges::range RESULT_CONTAINER = Iterable<T>, invocable< T > ELEMENT_MAPPER>
requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, typename RESULT_CONTAINER::value_type> or convertible_to<invoke_result_t<ELEMENT_MAPPER, T>, optional<typename RESULT_CONTAINER::value_type>>)
nonvirtual RESULT_CONTAINER Map (ELEMENT_MAPPER &&elementMapper) const
 functional API which iterates over all members of an Iterable, applies a map function to each element, and collects the results in a new Iterable
 
template<typename REDUCED_TYPE = T>
nonvirtual optional< REDUCED_TYPE > Reduce (const function< REDUCED_TYPE(ArgByValueType< T >, ArgByValueType< T >)> &op) const
 Walk the entire list of items, and use the argument 'op' to combine (reduce) items to a resulting single item.
 
template<typename REDUCED_TYPE = T>
nonvirtual REDUCED_TYPE ReduceValue (const function< REDUCED_TYPE(ArgByValueType< T >, ArgByValueType< T >)> &op, ArgByValueType< REDUCED_TYPE > defaultValue={}) const
 
template<typename RESULT_T = Characters::String, invocable< T > CONVERT_TO_RESULT = decltype (kDefaultToStringConverter<>), invocable< RESULT_T, RESULT_T, bool > COMBINER = decltype (Characters::kDefaultStringCombiner)>
requires (convertible_to<invoke_result_t<CONVERT_TO_RESULT, T>, RESULT_T> and convertible_to<invoke_result_t<COMBINER, RESULT_T, RESULT_T, bool>, RESULT_T>)
nonvirtual RESULT_T Join (const CONVERT_TO_RESULT &convertToResult=kDefaultToStringConverter<>, const COMBINER &combiner=Characters::kDefaultStringCombiner) const
 ape the JavaScript/python 'join' function - take the parts of 'this' iterable and combine them into a new object (typically a string)
 
nonvirtual Iterable< T > Skip (size_t nItems) const
 
nonvirtual Iterable< T > Take (size_t nItems) const
 
nonvirtual Iterable< T > Slice (size_t from, size_t to) const
 
nonvirtual Iterable< T > Top () const
 return the top/largest (possibly just top N) values from this Iterable<T>
 
template<Common::IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual Iterable< T > OrderBy (INORDER_COMPARER_TYPE &&inorderComparer=INORDER_COMPARER_TYPE{}, Execution::SequencePolicy seq=Execution::SequencePolicy::ePar) const
 
template<Common::IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual bool IsOrderedBy (INORDER_COMPARER_TYPE &&inorderComparer=INORDER_COMPARER_TYPE{}) const
 
nonvirtual optional< T > First () const
 return first element in iterable, or if 'that' specified, first where 'that' is true, (or return nullopt if none)
 
nonvirtual T FirstValue (ArgByValueType< T > defaultValue={}) const
 return first element in iterable provided default
 
nonvirtual optional< T > Last () const
 return last element in iterable, or if 'that' specified, last where 'that' is true, (or return missing)
 
nonvirtual T LastValue (ArgByValueType< T > defaultValue={}) const
 
nonvirtual bool All (const function< bool(ArgByValueType< T >)> &testEachElt) const
 return true iff argument predicate returns true for each element of the iterable
 
nonvirtual optional< T > Min () const
 
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE MinValue (ArgByValueType< RESULT_TYPE > defaultValue={}) const
 
nonvirtual optional< T > Max () const
 
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE MaxValue (ArgByValueType< RESULT_TYPE > defaultValue={}) const
 
template<typename RESULT_TYPE = T>
nonvirtual optional< RESULT_TYPE > Mean () const
 
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE MeanValue (ArgByValueType< RESULT_TYPE > defaultValue={}) const
 
template<typename RESULT_TYPE = T>
nonvirtual optional< RESULT_TYPE > Sum () const
 
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE SumValue (ArgByValueType< RESULT_TYPE > defaultValue={}) const
 
template<constructible_from< T > RESULT_TYPE = T, Common::IPotentiallyComparer< RESULT_TYPE > INORDER_COMPARE_FUNCTION = less<RESULT_TYPE>>
nonvirtual optional< RESULT_TYPE > Median (const INORDER_COMPARE_FUNCTION &compare={}) const
 
template<constructible_from< T > RESULT_TYPE = T>
nonvirtual RESULT_TYPE MedianValue (ArgByValueType< RESULT_TYPE > defaultValue={}) const
 
nonvirtual Iterable< T > Repeat (size_t count) const
 
nonvirtual bool Any () const
 Any() same as not empty (); Any (includeIfTrue) returns true iff includeIfTrue returns true on any values in iterable.
 
nonvirtual size_t Count () const
 with no args, same as size, with function filter arg, returns number of items that pass.
 
nonvirtual size_t length () const
 STL-ish alias for size() - really in STL only used in string, I think, but still makes sense as an alias.
 

Additional Inherited Members

- Public Types inherited from Stroika::Foundation::Traversal::Iterable< T >
using value_type = T
 value_type is an alias for the type iterated over - like vector<T>::value_type
 
using iterator = Iterator< T >
 
using const_iterator = Iterator< T >
 
- Static Public Member Functions inherited from Stroika::Foundation::Traversal::Iterable< T >
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, IEqualsComparer< T > EQUALS_COMPARER = equal_to<T>>
static bool SetEquals (const LHS_CONTAINER_TYPE &lhs, const RHS_CONTAINER_TYPE &rhs, EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{})
 
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, IEqualsComparer< T > EQUALS_COMPARER = equal_to<T>>
static bool MultiSetEquals (const LHS_CONTAINER_TYPE &lhs, const RHS_CONTAINER_TYPE &rhs, EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{})
 
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, IEqualsComparer< T > EQUALS_COMPARER = equal_to<T>>
static bool SequentialEquals (const LHS_CONTAINER_TYPE &lhs, const RHS_CONTAINER_TYPE &rhs, EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{}, bool useIterableSize=false)
 
static constexpr default_sentinel_t end () noexcept
 Support for ranged for, and STL syntax in general.
 
- Static Public Attributes inherited from Stroika::Foundation::Traversal::Iterable< T >
template<same_as< Characters::String > RESULT_T = Characters::String>
static const function< RESULT_T(T)> kDefaultToStringConverter
 
- Protected Types inherited from Stroika::Foundation::Traversal::Iterable< T >
using _SharedByValueRepType = Memory::SharedByValue< _IRep, Memory::SharedByValue_Traits< _IRep, shared_ptr< _IRep >, Rep_Cloner_ > >
 Lazy-copying smart pointer mostly used by implementors (can generally be ignored by users). However, protected because manipulation needed in some subclasses (rarely) - like UpdatableIteratable.
 
- Protected Member Functions inherited from Stroika::Foundation::Traversal::Iterable< T >
 Iterable (const shared_ptr< _IRep > &rep) noexcept
 Iterable's are typically constructed as concrete subtype objects, whose CTOR passed in a shared copyable rep.
 
nonvirtual Memory::SharedByValue_State _GetSharingState () const
 
- Protected Attributes inherited from Stroika::Foundation::Traversal::Iterable< T >
_SharedByValueRepType _fRep
 

Detailed Description

template<typename T, typename MAPPER_ENGINE = DirectPushMapEngine>
class Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE >

Design Overview The gist is to have a MAPPING_ENGINE - which can either do direct applicaiton and buffering, or pull based compuation (where calls are done in final iterator as you pull results) or done with the first case - applicaiton context/buffering - but via thread pools, or some other strategy.

All this is to do the computation for traditional basic functional programming algorithms, like map/reduce, and filters etc.

To use, you simple instantiate a FunctionalApplicationContext object, and then chain together a series of filters. typically, the end result - last filter step - will be to produce an iterable (which can be trivially converted to another container type).

Example Usage
COMMON/SETUP:
Sequence<int> s = { 1, 2, 3 };
DANGEROUS/BAD EXAMPLE
{
int countSoFar = 0;
int answer =
Filter ([&countSoFar] (int) -> bool { ++countSoFar; return countSoFar & 1; }).
Map<int> ([] (int s) { return s + 5; }).
Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; })
;
EXPECT_TRUE (answer == 2);
}

This will work, but ONLY because all resulting objects from the compuation will be destroyed before the countSoFar goes out of scope. Since FunctionalApplicationContext<> is often used to produce an iterable that is 'returned' - its best to use a smart-pointer to store any catpured values.

Example Usage
{
shared_ptr<int> countSoFar = shared_ptr<int> (new int (0));
int answer =
Filter ([countSoFar] (int) -> bool { ++(*countSoFar); return (*countSoFar) & 1; }).
Map<int> ([] (int s) { return s + 5; }).
Reduce<size_t> ([] (int s, size_t memo) { return memo + 1; })
;
EXPECT_TRUE (answer == 2);
}
Example Usage
{
shared_ptr<int> countSoFar = shared_ptr<int> (new int (0));
Sequence<int> r = Sequence<int> (
Filter ([countSoFar] (int) -> bool { ++(*countSoFar); return (*countSoFar) & 1; }).
Map<int> ([] (int s) { return s + 5; })
);
EXPECT_TRUE (r.length () == 2);
EXPECT_TRUE (r[0] == 6 and r[1] == 8);
}

So you create a FunctionalApplicationContext<> - with the template parameter refering to the type of the input container.

Then you chain together as many steps as you want (methods of FunctionalApplicationContext) and the final result is the end of the computation.

You can optionally create the initial FunctionalApplicationContext with a selected 'mapping engine' that will use thread pools, or whatever mechanism you choose to orchestrate the computation.

Note that we use std::function<> intead of typename FUNCTION - though I think this will perform the same or slower - just because I think using the explicit types will produce more comprehensible error messages from the compiler. We can always relax the definition to use typename FUNCTION in the future - hopefully - without breaking existing using code.

What Methods and why? Much of this list of methods is based on

See also
http://underscorejs.org/#reduce But much doesn't make sense in stroika. So here is a rough partial summary of what is NOT included from there and why
>   each() - not reason to include because Iterable has 'Apply' - use that instead.
>   reject() - not included cuz its the same as filter() - except with NOT on lambda

Definition at line 205 of file FunctionalApplication.h.

Member Function Documentation

◆ Map()

template<typename T , typename MAPPER_ENGINE >
template<typename OUT_T >
FunctionalApplicationContext< OUT_T, MAPPER_ENGINE > Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE >::Map ( const function< OUT_T(T)> &  do2Each)

◆ Reduce()

template<typename T , typename MAPPER_ENGINE >
template<typename OUT_T >
OUT_T Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE >::Reduce ( const function< OUT_T(T, OUT_T)> &  do2Each,
OUT_T  memo = OUT_T () 
)

The documentation for this class was generated from the following files: