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

Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them. More...

#include <Iterable.h>

Inheritance diagram for Stroika::Foundation::Traversal::Iterable< T >:
Stroika::Foundation::Containers::Collection< Stroika::Foundation::IO::Network::Transfer::Connection::Ptr > Stroika::Foundation::Containers::Collection< Stroika::Foundation::Execution::Function > Stroika::Foundation::Containers::Collection< Stroika::Foundation::IO::Network::ConnectionlessSocket::Ptr > Stroika::Foundation::Containers::Collection< ConnectionlessSocket::Ptr > Stroika::Foundation::Containers::Collection< Stroika::Foundation::Database::SQL::ORM::Schema::Field > Stroika::Foundation::Containers::Collection< TPInfo_ > Stroika::Foundation::Containers::Collection< pair< WaitForIOReady_Support::SDKPollableType, TypeOfMonitorSet > > Stroika::Foundation::Containers::Collection< Stroika::Foundation::IO::Network::HTTP::Cookie > Stroika::Foundation::Containers::Collection< Stroika::Foundation::Common::KeyValuePair< Stroika::Foundation::Characters::String, Stroika::Foundation::Characters::String > > Stroika::Foundation::Containers::Collection< Stroika::Foundation::IO::Network::CIDR > Stroika::Foundation::Containers::Collection< Stroika::Foundation::IO::Network::InternetAddress > Stroika::Foundation::Containers::Collection< Stroika::Frameworks::SystemPerformance::CaptureSet > Stroika::Foundation::Containers::Collection< Stroika::Frameworks::SystemPerformance::Measurement > Stroika::Foundation::Containers::Collection< shared_ptr< Stroika::Frameworks::WebServer::Connection > > Stroika::Foundation::Containers::Collection< pair< shared_ptr< Stroika::Frameworks::WebServer::Connection >, TypeOfMonitorSet > > Stroika::Foundation::Containers::DataHyperRectangle< T, INDEXES... > Stroika::Foundation::Containers::KeyedCollection< T, KEY_TYPE, KeyedCollection_DefaultTraits< T, KEY_TYPE > > Stroika::Foundation::Containers::KeyedCollection< Stroika::Foundation::DataExchange::ObjectVariantMapper::TypeMappingDetails, type_index, Stroika::Foundation::Containers::KeyedCollection_DefaultTraits > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::DataExchange::InternetMediaType, Stroika::Foundation::DataExchange::InternetMediaTypeRegistry::OverrideRecord > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, Stroika::Foundation::DataExchange::InternetMediaType > Stroika::Foundation::Containers::Mapping< PriorityAndMessageType_, LastMsgInfoType_ > Stroika::Foundation::Containers::Mapping< Stroika::Frameworks::WebServer::Message *, shared_ptr< ILogHandler::MessageInstance > > Stroika::Foundation::Containers::Mapping< SignalID, Set< Stroika::Foundation::Execution::SignalHandler > > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, Stroika::Foundation::Characters::String > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, Stroika::Foundation::DataExchange::VariantValue > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::DataExchange::StructuredStreamEvents::Name, Stroika::Foundation::DataExchange::StructFieldMetaInfo > Stroika::Foundation::Containers::Mapping< type_index, ReaderFromVoidStarFactory > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, Stroika::Foundation::DataExchange::Variant::INI::Section > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, Stroika::Foundation::IO::Network::URI > Stroika::Foundation::Containers::Mapping< SignalID, Stroika::Foundation::Containers::Set< Stroika::Foundation::Execution::SignalHandler > > Stroika::Foundation::Containers::Mapping< type_index, Stroika::Foundation::DataExchange::Atom > Stroika::Foundation::Containers::Mapping< DynamicDiskIDType, Stroika::Frameworks::SystemPerformance::Instruments::Filesystem::DiskInfoType > Stroika::Foundation::Containers::Mapping< MountedFilesystemNameType, Stroika::Frameworks::SystemPerformance::Instruments::Filesystem::MountedFilesystemInfoType > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, std::shared_ptr< PerInstanceData_ > > Stroika::Foundation::Containers::Mapping< Stroika::Foundation::Characters::String, PDH_HCOUNTER > Stroika::Foundation::Containers::MultiSet< T, DefaultTraits::MultiSet< T > > Stroika::Foundation::Containers::Queue< PriorityAndMessageType_ > Stroika::Foundation::Containers::Sequence< OperationItemType > Stroika::Foundation::Containers::Sequence< ContentEncoding > Stroika::Foundation::Containers::Sequence< TransferEncoding > Stroika::Foundation::Containers::Sequence< RangeType > Stroika::Foundation::Containers::Sequence< Advertisement > Stroika::Foundation::Containers::Sequence< Stroika::Frameworks::WebServer::Interceptor > Stroika::Foundation::Containers::Sequence< Stroika::Frameworks::WebServer::Route > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::Characters::String > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::Common::SystemConfiguration::CPU::CoreDetails > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::DataExchange::VariantValue > Stroika::Foundation::Containers::Sequence< MixinEltTraits > Stroika::Foundation::Containers::Sequence< shared_ptr< Stroika::Foundation::DataExchange::StructuredStreamEvents::ObjectReader::IElementConsumer > > Stroika::Foundation::Containers::Sequence< shared_ptr< Stroika::Foundation::Execution::Function > > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::IO::Network::InternetAddress > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::IO::Network::HTTP::ETag > Stroika::Foundation::Containers::Sequence< shared_ptr< const IRep > > Stroika::Foundation::Containers::Sequence< FLOAT_TYPE > Stroika::Foundation::Containers::Sequence< Stroika::Foundation::IO::Network::URI > Stroika::Foundation::Containers::Set< Stroika::Foundation::Characters::Character > Stroika::Foundation::Containers::Set< shared_ptr< Stroika::Foundation::DataExchange::StructuredStreamEvents::ObjectReader::IElementConsumer > > Stroika::Foundation::Containers::Set< Stroika::Foundation::Characters::String > Stroika::Foundation::Containers::Set< Stroika::Frameworks::SystemPerformance::Instrument > Stroika::Foundation::Containers::Set< Stroika::Foundation::DataExchange::Atom > Stroika::Foundation::Containers::Stack< variant< MapElt, SeqElt > > Stroika::Foundation::Containers::Stack< Stroika::Foundation::Execution::Activity<> > Stroika::Foundation::Containers::Association< KEY_TYPE, MAPPED_VALUE_TYPE > Stroika::Foundation::Containers::Bijection< DOMAIN_TYPE, RANGE_TYPE > Stroika::Foundation::Containers::Collection< T > Stroika::Foundation::Containers::DataHyperRectangle< T, INDEXES > Stroika::Foundation::Containers::KeyedCollection< T, KEY_TYPE, TRAITS > Stroika::Foundation::Containers::Mapping< KEY_TYPE, MAPPED_VALUE_TYPE > Stroika::Foundation::Containers::MultiSet< T, TRAITS > Stroika::Foundation::Containers::Queue< T > Stroika::Foundation::Containers::Sequence< T > Stroika::Foundation::Containers::Set< T > Stroika::Foundation::Containers::Stack< T > Stroika::Foundation::Traversal::FunctionalApplicationContext< T, MAPPER_ENGINE > Stroika::Foundation::Traversal::IterableFromIterator< T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR >

Classes

class  _IRep
 Implementation detail for iterator implementors. More...
 
class  _SafeReadRepAccessor
 
class  _SafeReadWriteRepAccessor
 
struct  SequentialEqualsComparer
 
struct  SequentialThreeWayComparer
 

Public Types

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 >
 

Public Member Functions

 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.
 

Static Public Member Functions

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

template<same_as< Characters::String > RESULT_T = Characters::String>
static const function< RESULT_T(T)> kDefaultToStringConverter
 

Protected Types

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

 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

_SharedByValueRepType _fRep
 

Detailed Description

template<typename T>
class Stroika::Foundation::Traversal::Iterable< T >

Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.

The Stroika iterators can be used either directly (similar to std::range), or in the STL begin/end style - and this class supports both styles of usage.

Iterable<T> also supports read-only applicative operations on the contained data.

Iterable<T> is much like idea of 'abstract readonly container', but which only supports an exceedingly simplistic pattern of access.

Note
Satisfies Concepts: o static_assert (copyable<Iterable<T>>); // not not default-unitarizable, and not equals_comparable

Important Design Note (lifetime of iterators): The Lifetime of Iterator<T> objects created by an Iterable<T> instance must always be less than the creating Iterable's lifetime.

This may not be enforced by implementations (but generally will be in debug builds). But it is a rule!

The reason for this is that the underlying memory referenced by the iterator may be going away. We could avoid this by adding a shared_ptr<> reference count into each iterator, but that would make iterator objects significantly more expensive, and with little apparent value added. Similarly for weak_ptr<> references.

Important Design Note (construct with rep, no setrep): We have no: nonvirtual void _SetRep (IterableRepSharedPtr rep);

because allowing a _SetRep() method would complicate the efforts of subclasses of Iterable<T> to assure that the underlying type is of the appropriate subtype.

For example - see Bag_Array<T>::GetRep_().

Note - instead - you can 'assign' (operator=) to replace the value (and dynamic type) of an Iterable<> (or subclass) instance.

Important Design Note (copy on write/COW): Iterable uses 'SharedByValue', so that subclasses of Iterable (especially containers) CAN implement Copy-On-Write (COW). However, not ALL Iterables implement COW. In fact, not all Iterables are mutable!

Iterable's data can come from arbitrary, programmatic sources (like a sequence of uncomputed random numbers). If you wish to capture something like an Iterable for later use, but don't want its value to change once you've captured it, consider using Collection<T> or Sequence<> which is almost the same, but will make a copy of the data, and not allow it to change without preserve COW semantics.

Design Note: Why does Iterable<T> contain a size () method?

o   It’s always well defined what size() means (what you would get if you called
    MakeIterable() and iterated a bunch of times til the end).

o   Its almost always (and trivial) to perform that computation more efficiently than the
    iterate over each element approach.

The gist of these two consideration means that if you need to find the length of
an Iterable<T>, if it was defined as a method, you can access the trivial implementation,
and if it was not defined, you would be forced into the costly implementation.

Adding size () adds no conceptual cost – because its already so well and clearly defined in terms of its basic operation (iteration). And it provides value (maybe just modest value).

Design Note: Order of Iteration.

Iterables<T> provide no promises about the order of iteration. Specific subclasses (like SortedSet<>) often will make specific guarantees about order of iteration.

We do NOT even promise you will see the same items, or seem them in the same order as you iterate (so for example, you can have a "RandomSequence<>" subclass from Iterable<> and return a different sequence of numbers each time you make an iterate and run.

Design Note:

Note
Comparisons: Chose NOT to include an equal_to<Iterable<T>> partial specialization here, but instead duplicatively in each subclass, so that it could more easily be implemented efficiently (not a biggie), but more importantly because it doesn't appear to me to make sense so say that a Stack<T> == Set<T>, even if their values were the same. In other words, the meaning of 'equals' varies between different kinds of iterables (over the same type).

We DO have methods SetEquals/MultiSetEquals/SequentialEquals (see below), as well as SequentialThreeWayComparer<> etc.

Design Note Methods like Min/Max/Median/Sum make little sense on empty Iterables. There were several choices available to deal with this: > Assertion > throw range_error() > return a sensible default value (e.g. 0) for empty lists > overloads to let callers select the desired behavior

Because I wanted these methods to be useful in scenarios like with database queries (inspired by Linq/ORMs) assertions seemed a poor choice.

throw range_error makes sense, but then requires lots of checking when used for throws, and that makes use needlessly complex.

So we eventually decided to use the return optional and have a variant named XXXValue () that returns the plain T with a default - since we use that pattern in so many places.

Design Note - Microsoft Linq: This API implements some of the Microsoft Linq API. https://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods(v=vs.100).aspx

For example, we implement: o Map most important o Reduce important - aka accumulate o Where o Take o Skip o OrderBy o First/Last/FirstValue/LastValue (though semantics and later names differ somewhat from .net FirstOrDefault)

We choose explicitly not to implement o ToList/ToArray, no need because we have As<>, plus no List/Array classes (exactly).

Note
Thread-Safety C++-Standard-Thread-Safety

Definition at line 237 of file Iterable.h.

Member Typedef Documentation

◆ iterator

template<typename T >
using Stroika::Foundation::Traversal::Iterable< T >::iterator = Iterator<T>

For Stroika containers, all iterators are really const_iterators, but this allows for better STL interoperability.

Definition at line 254 of file Iterable.h.

◆ const_iterator

template<typename T >
using Stroika::Foundation::Traversal::Iterable< T >::const_iterator = Iterator<T>

For better STL interoperability.

Definition at line 260 of file Iterable.h.

Constructor & Destructor Documentation

◆ Iterable() [1/3]

template<typename T >
requires (not derived_from<remove_cvref_t<CONTAINER_OF_T>, Iterable<T>>)
template<IIterableOfTo< T > CONTAINER_OF_T>
requires (not derived_from<remove_cvref_t<CONTAINER_OF_T>, Iterable<T>>)
Stroika::Foundation::Traversal::Iterable< T >::Iterable ( CONTAINER_OF_T &&  from)
explicit

Make a copy of the given argument, and treat it as an iterable.

Example Usage
Iterable<int> aa6{3, 4, 6};
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
Note
Don't apply this constructor to non-containers (non-iterables), and don't allow it to apply to SUBCLASSES of Iterable (since then we want to select the Iterable (const Iterable& from) constructor)

Definition at line 249 of file Iterable.inl.

◆ Iterable() [2/3]

template<typename T >
Stroika::Foundation::Traversal::Iterable< T >::Iterable ( const initializer_list< T > &  from)
Note
Use of initializer_list<T> (
See also
http://stroika-bugs.sophists.com/browse/STK-739) Because of quirks of C++ overload resolution (https://en.cppreference.com/w/cpp/language/list_initialization) use of mem-initializers with Iterable<T> constructor calls have the unintuitive behavior of invoking the initializer_list<T> constructor preferentially (see docs above and 'Otherwise, the constructors of T are considered, in two phases'

Definition at line 256 of file Iterable.inl.

◆ Iterable() [3/3]

template<typename T >
Stroika::Foundation::Traversal::Iterable< T >::Iterable ( const shared_ptr< _IRep > &  rep)
explicitprotectednoexcept

Iterable's are typically constructed as concrete subtype objects, whose CTOR passed in a shared copyable rep.

Note
- the repPtr in construction can be, so that we don't need to increment its reference count as we pass it though the call chain to where it will be finally stored.

Member Function Documentation

◆ operator bool()

template<typename T >
Stroika::Foundation::Traversal::Iterable< T >::operator bool ( ) const
explicit

Often handy short-hand (punning) for a container to see if zero elts, then if on it returns false.

Definition at line 261 of file Iterable.inl.

◆ MakeIterator()

template<typename T >
Iterator< T > Stroika::Foundation::Traversal::Iterable< T >::MakeIterator ( ) const

Create an iterator object which can be used to traverse the 'Iterable'.

Create an iterator object which can be used to traverse the 'Iterable' - this object - and visit each element.

Note
LIFETIME NOTE: Iterators created this way, become invalidated (generally detected in debug builds), and cannot be used after the underlying Iterable is modified.

Definition at line 294 of file Iterable.inl.

◆ size()

template<typename T >
size_t Stroika::Foundation::Traversal::Iterable< T >::size ( ) const

Returns the number of items contained.

size () returns the number of elements in this 'Iterable' object. Its defined to be the same number of elements you would visit if you created an iterator (MakeIterator()) and visited all items. In practice, as the actual number might vary as the underlying iterable could change while being iterated over.

For example, a filesystem directory iterable could return a different length each time it was called, as files are added and removed from the filesystem.

Also note that size () can return a ridiculous number - like numeric_limits<size_t>::max () - for logically infinite sequences... like a sequence of random numbers.

Aliases
GetLength () - in fact in Stroika before 2.1b14, this was called GetLength ()
Note
Design Note: noexcept We chose to allow the empty () method to allow exceptions, since an Iterable<T> is general enough (say externally network data sourced) - it could be temporarily or otherwise unavailable.

Performance: The performance of size() may vary wildly. It could be anywhere from O(1) to O(N) depending on the underlying type of Iterable<T>.

Definition at line 300 of file Iterable.inl.

◆ empty()

template<typename T >
bool Stroika::Foundation::Traversal::Iterable< T >::empty ( ) const

Returns true iff size() == 0.

Aliases
IsEmpty () - called IsEmpty () in Stroika 2.1b13 and prior
Note
Design Note: noexcept We chose to allow the empty () method to allow exceptions, since an Iterable<T> is general enough (say externally network data sourced) - it could be temporarily or otherwise unavailable.
Runtime performance/complexity: The performance of empty() may vary wildly (
See also
size) but will nearly always be constant complexity.

Definition at line 306 of file Iterable.inl.

◆ Contains()

template<typename T >
template<Common::IPotentiallyComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual bool Stroika::Foundation::Traversal::Iterable< T >::Contains ( ArgByValueType< T >  element,
EQUALS_COMPARER &&  equalsComparer = EQUALS_COMPARER{} 
) const

Apply the (template argument) EQUALS_COMPARER to each element in the Iterable<T> and return true iff found. This invokes no virtual methods dependent (except MakeIterable or some such) and so gains no performance benefits from the organization of the underlying Iterable<T>. This is just a short hand for the direct iteration one would trivially code by hand. Still - its easier to call Contains() that to code that loop!

And note - subclasses (like Containers::Set<T>) will hide this implementation with a more efficient one (that does indirect to the backend).

Performance: This algorithm is O(N).

◆ SetEquals()

template<typename T >
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, Common::IEqualsComparer< T > EQUALS_COMPARER>
bool Stroika::Foundation::Traversal::Iterable< T >::SetEquals ( const LHS_CONTAINER_TYPE &  lhs,
const RHS_CONTAINER_TYPE &  rhs,
EQUALS_COMPARER &&  equalsComparer = EQUALS_COMPARER{} 
)
static

SetEquals () - very inefficiently - but with constant small memory overhead - returns true if each element in the each iterable is contained in the other. The lengths CAN be different and the two Iterables<> be SetEquals().

Performance: This algorithm is O(N) * O(M) where N and M are the length of the two respective iterables.

Note

Definition at line 320 of file Iterable.inl.

◆ MultiSetEquals()

template<typename T >
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, Common::IEqualsComparer< T > EQUALS_COMPARER>
bool Stroika::Foundation::Traversal::Iterable< T >::MultiSetEquals ( const LHS_CONTAINER_TYPE &  lhs,
const RHS_CONTAINER_TYPE &  rhs,
EQUALS_COMPARER &&  equalsComparer = EQUALS_COMPARER{} 
)
static

MultiSetEquals () - very inefficiently - but with constant small memory overhead - returns true if each element in the each iterable is contained in the other. They lengths CAN be different and the two Iterables<> be SetEquals().

Performance: This algorithm is O(N^^3)

Definition at line 361 of file Iterable.inl.

◆ SequentialEquals()

template<typename T >
template<ranges::range LHS_CONTAINER_TYPE, ranges::range RHS_CONTAINER_TYPE, Common::IEqualsComparer< T > EQUALS_COMPARER>
bool Stroika::Foundation::Traversal::Iterable< T >::SequentialEquals ( const LHS_CONTAINER_TYPE &  lhs,
const RHS_CONTAINER_TYPE &  rhs,
EQUALS_COMPARER &&  equalsComparer = EQUALS_COMPARER{},
bool  useIterableSize = false 
)
static

SequentialEquals () - measures if iteration over the two containers produces identical sequences of elements (identical by compare with EQUALS_COMPARER). It does not call 'size' - by default - but just iterates (unless the paraemter useIterableSize)

Note
- RHS_CONTAINER_TYPE can be any iterable, including an STL container like vector or initializer_list
If useIterableSize == true (Defaults false), size() method must be quick, and unchanged during the lifetime of the the comparison.

Performance: This algorithm is O(N)

Definition at line 396 of file Iterable.inl.

◆ begin()

template<typename T >
Iterator< T > Stroika::Foundation::Traversal::Iterable< T >::begin ( ) const

Support for ranged for, and STL syntax in general.

begin ()/end() are similar to MakeIterator(), except that they allow for iterators to be used in an STL-style, which is critical for using C++ ranged iteration.

Example Usage
for (Iterator<T> i = c.begin (); i != c.end (); ++i) {
if (*i = T{}) {
break;
}
}
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225

OR

for (const T& i : c) {
if (*i = T{}) {
break;
}
}

Definition at line 1099 of file Iterable.inl.

◆ end()

template<typename T >
constexpr default_sentinel_t Stroika::Foundation::Traversal::Iterable< T >::end ( )
staticconstexprnoexcept

Support for ranged for, and STL syntax in general.

Note
in INCOMPATIBLE change in Stroika v3.0d1 - from v2.1 - making this instance method instead of static method (needed for 'std::ranges' concept compatibility).
in Stroika v3.0d10 - changed return type to default_sentinel_t (from Iterator<T>).

Definition at line 1104 of file Iterable.inl.

◆ Apply()

template<typename T >
void Stroika::Foundation::Traversal::Iterable< T >::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.

Take the given function argument, and call it for each element of the container. This is equivalent to:

for (Iterator<T> i = begin (); i != end (); ++i) {
    (doToElement) (*i);
}

However, Apply () MAY perform the entire iteration more quickly (depending on the kind of the container).

Apply () also MAY be much faster than normal iteration (some simple tests

  • around 2015-02-15 - suggest Apply () is perhaps 10x faster than using an iterator).
Example Usage
unsigned int cnt { 0 };
s.Apply ([&cnt] (int i) {
cnt += i;
});
DbgTrace ("cnt={}"_f, cnt);
#define DbgTrace
Definition Trace.h:309
Note
on 'seq' parameter, if you pass anything but (the default) eSeq value, be sure to check function argument is threadsafe.
Aliases: o Apply could have logically been called ForEach, and is nearly identical to std::for_each (), except for not taking iterators as arguments, and not having any return value.
Why Apply takes std::function argument instead of templated FUNCTION parameter? Because Stroika iterables use a 'virtual' APPLY, you cannot pass arbitrary templated function calls passed that boundary. That choice ALLOWS traversal to be implemented quickly, and without and subsequent (virtual) calls on the container side, but one
  • CALL per iteration to the function itself.
Thread-Safety The argument function (lambda) may directly (or indirectly) access the Iterable<> being iterated over.

Definition at line 1109 of file Iterable.inl.

◆ Find()

template<typename T >
template<predicate< T > THAT_FUNCTION>
nonvirtual Iterator< T > Stroika::Foundation::Traversal::Iterable< 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<>)

Take the given function argument, and call it for each element of the container. This is equivalent to:

for (Iterator<T> i = begin (); i != end (); ++i) {
    if (that (*i)) {
        return it;
    }
}
return end();

This function returns an iterator pointing to the element that triggered the abrupt loop end (for example the element you were searching for?). It returns the special iterator end() to indicate no doToElement() functions returned true.

Also, note that this function does NOT change any elements of the Iterable.

Note
about seq - eSeq - then the item returned will be first in iteration order. But if you pass in some other Execution::SequencePolicy 'seq', the algorithm will return the 'first it finds'.

If you really care that the result is first, probably better to call Iterable<>::First (). Though it amounts to the same thing (setting SequencePolicy::eSeq) - its better documenting.

Note that this used to be called 'ContainsWith' - because it can act the same way (due to operator bool () method of Iterator<T>).

Note
This is much like First(), except that it optional takes a different starting point, and it returns an Iterator<T> instead of an optional<T> First () - often more handy.
though semantically similar to iterating, it maybe faster, due to delegating 'search' to backend container implementation (though then call to lambda/checker maybe indirected countering this performance benefit).
Aliases
FirstThat
See also
Apply
Note
Thread-Safety The argument function (lambda) may directly (or indirectly) access the Iterable<> being iterated over.
Example Usage
bool IsAllWhitespace (String s) const
{
return not s.Find ([] (Character c) -> bool { return not c.IsWhitespace (); });
}
See also
See Also First (f) - if you just want the first one...
Note
- because the lifetime of the iterable must exceed that of the iterator, its generally unsafe to use Find() on a temporary (except with the trick if (auto i = x().Find(...)) { ok to access i here cuz x() temporary not destroyed yet).
despite the name EQUALS_COMPARER, we allow EQUALS_COMPARER to just be IPotentiallyComparer<> and don't require EqualsComparer, just to simplify use, and because we cannot anticipate any real ambiguity or confusion resulting from this loose restriction.

◆ As()

template<typename T >
template<IIterableOfFrom< T > CONTAINER_OF_T, typename... CONTAINER_OF_T_CONSTRUCTOR_ARGS>
nonvirtual CONTAINER_OF_T Stroika::Foundation::Traversal::Iterable< T >::As ( CONTAINER_OF_T_CONSTRUCTOR_ARGS...  args) const

As<CONTAINER_OF_T> () can be used to easily map an iterable to another container (for example STL container) which supports begin/end iterator constructor. This is really just a shorthand for CONTAINER_OF_T{this->begin (), this->end ()};

Note - this also works with (nearly all) of the Stroika containers as well (e.g. Set<T> x; x.As<Sequence<T>> ());

Design Note: We chose NOT to include an overload taking iterators because there was no connection between 'this' and the used iterators, so you may as well just directly call CONTAINER_OF_T{it1, it2}.

◆ Nth()

template<typename T >
T Stroika::Foundation::Traversal::Iterable< T >::Nth ( ptrdiff_t  n) const

Find the Nth element of the Iterable<>

if n < 0, treated as from the end, so actual index = size () + n

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_EQ (c.Nth (1), 2);
EXPECT_EQ (c.Nth (-1), 6);
Precondition
n < size () // for size_t overload
n < size () and n > -size() // for ptrdiff_t overload

Definition at line 1174 of file Iterable.inl.

◆ NthValue()

template<typename T >
T Stroika::Foundation::Traversal::Iterable< 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.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_EQ (c.NthValue (1), 2);
EXPECT_EQ (c.NthValue (99), int{});

Definition at line 1190 of file Iterable.inl.

◆ Where()

template<typename T >
template<derived_from< Iterable< T > > RESULT_CONTAINER = Iterable<T>, predicate< T > INCLUDE_PREDICATE>
nonvirtual RESULT_CONTAINER Stroika::Foundation::Traversal::Iterable< T >::Where ( INCLUDE_PREDICATE &&  includeIfTrue) const

produce a subset of this iterable where argument function returns true

BASED ON Microsoft .net Linq.

Aliases
Filter
Aliases
AllThat, AllOf

This returns either an Iterable<T>, or a concrete container (provided template argument). If returning just an Iterable<T>, then the result is lazy evaluated. If a concrete container is provided, its fully constructed when Where returns.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Where ([] (int i) { return i % 2 == 0; }).SequentialEquals (Iterable<int> { 2, 4, 6 }));
Note
Could have been called EachWith, EachWhere, EachThat (), AllThat, AllWhere, Filter, or SubsetWhere.
This is NEARLY IDENTICAL to the Map<RESULT_CONTAINER> function - where it uses its optional returning filter function. Please where cannot be used to transform the shape of the data (e.g. projections) whereas Map() can. But for the filter use case, this is a bit terser, so maybe still useful –LGP 2022-11-15
See also
See also Map<RESULT_CONTAINER,ELEMENT_MAPPER> ()

◆ Distinct()

template<typename T >
template<Common::IPotentiallyComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Distinct ( EQUALS_COMPARER &&  equalsComparer = EQUALS_COMPARER{}) const

BASED ON Microsoft .net Linq.

This returns an Iterable<T> that contains just the subset of the items which are distinct (equality comparer)

Example Usage
Iterable<int> c { 1, 2, 2, 5, 9, 4, 5, 6 };
EXPECT_TRUE (c.Distinct ().SetEquals (Iterable<int> { 1, 2, 4, 5, 6, 9 }));

◆ Map()

template<typename T >
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 Stroika::Foundation::Traversal::Iterable< T >::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

This is like the map() function in so many other languages, like lisp, JavaScript, etc, not like the STL::map class.

The transformation may be a projection, or complete transformation. If the 'extract' function returns optional<RESULT_COLLECTION::value_type>, then a missing value is treated as removal from the source list (in the resulting generated list).

Note
-
See also
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map as it does essentially the same thing. It can be used to completely transform a container of one thing into a (possibly smaller) container of something else by iterating over all the members, applying a function, and (optionally) appending the result of that function to the new container.
Note
Prior to Stroika v3.0d5, this template look 2 template parameters, the first an element type and the second the collection to be produced. But since that release, we just take the second parameter (as first) - and infer the RESULT_ELELMENT_TYPE.
Prior to Stroika v2.1.10, this was called Select ()
- The overloads returning Iterable<RESULT> do NOT IMMEDIATELY traverse its argument, but uses
See also
CreateGenerator - to create a new iterable that dynamically pulls from 'this' Iterable<>'.

The overloads returning RESULT_CONTAINER DO however immediately construct RESULT_CONTAINER, and fill it in the the result of traversal before Map () returns.

Note
This can be used to filter data, but if that is the only goal, 'Where' is a better choice. If the argument function returns optional<THE RETURN TYPE> - then only accumulate those that are returned with has_value () (so also can be used to filter).
Example Usage
Iterable<pair<int,char>> c { {1, 'a'}, {2, 'b'}, {3, 'c'} };
EXPECT_TRUE (c.Map<Iterable<int>> ([] (pair<int,char> p) { return p.first; }).SequentialEquals (Iterable<int> { 1, 2, 3 }));

This can also easily be used to TRANSFORM an iterable.

Example Usage
Iterable<int> c { 3, 4, 7 };
EXPECT_TRUE (c.Map<Iterable<String>> ([] (int i) { return Characters::Format ("{}"_f, i); }).SequentialEquals (Iterable<String> { "3", "4", "7" }));
static bool SequentialEquals(const LHS_CONTAINER_TYPE &lhs, const RHS_CONTAINER_TYPE &rhs, EQUALS_COMPARER &&equalsComparer=EQUALS_COMPARER{}, bool useIterableSize=false)
Definition Iterable.inl:396
Example Usage
or transform into another container type
Iterable<int> c { 3, 4, 7 };
EXPECT_TRUE ((c.Map<vector<String>> ([] (int i) { return Characters::Format ("{}"_f, i); }) == vector<String>{"3", "4", "7"}));
Example Usage
void ExpectedMethod (const Request* request, const Set<String>& methods, const optional<String>& fromInMessage)
{
String method{request->GetHTTPMethod ()};
Set<String> lcMethods = methods.Map<Iterable<String>> ([](const String& s) { return s.ToLowerCase (); });
if (not methods.Contains (method.ToLowerCase ())) {
...

Overload which returns optional<RESULT> and nullopt interpreted as skipping that element

Example Usage
Filtering a list example:
// GetAssociatedContentType -> optional<String> - skip items that are 'missing'
possibleFileSuffixes.Map<Set<InternetMediaType>> ([&] (String suffix) -> optional<InternetMediaType> { return r.GetAssociatedContentType (suffix); })
Note
This could have been written as one function/overload, but then for the RESULT_CONTAINER=Iterable<T> case we would be forced to uselessly create a bogus Iterable, and then throw it away.

◆ Reduce()

template<typename T >
template<typename REDUCED_TYPE = T>
nonvirtual optional< REDUCED_TYPE > Stroika::Foundation::Traversal::Iterable< T >::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.

See also
https://en.wikipedia.org/wiki/Reduction_operator
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?redirectedfrom=MSDN&view=net-7.0#overloads
Aliases
Accumulate
Note
This was called Accumulate in Stroika up until 2.1.10
Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 9 };
EXPECT_TRUE (c.Reduce ([] (T lhs, T rhs) { return lhs + rhs; }) == 24);
Implementation As if:
optional<RESULT_TYPE> result;
for (const auto& i : *this) {
if (result) {
result = op (i, *result);
}
else {
result = i;
}
}
Note
returns nullopt if empty list

See:

See also
ReduceValue
Join
Sum
SumValue

◆ ReduceValue()

template<typename T >
template<typename REDUCED_TYPE = T>
nonvirtual REDUCED_TYPE Stroika::Foundation::Traversal::Iterable< T >::ReduceValue ( const function< REDUCED_TYPE(ArgByValueType< T >, ArgByValueType< T >)> &  op,
ArgByValueType< REDUCED_TYPE >  defaultValue = {} 
) const
See also
@Reduce, but if value is missing, returns defaultValue arg or {}

◆ Join()

template<typename T >
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 Stroika::Foundation::Traversal::Iterable< 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)

This Join () API - if you use the template, is fairly generic and lets the caller iterate over subelements of this iterable, and combine them into a new thing (

See also
Reduce - it is similar but more general).

For the very common case of accumulating objects into a String, there are additional (stringish) overloads that more closely mimic what you can do in JavaScript/python.

Gist of arguments o convertToResult: - OPTIONAL converter from T to String o combiner: - OPTIONAL thing that joins two RESULT_T (result of above covertToResult - typically String) and combiner MAYBE replaced with String (separator and optionally finalStringSeparator)

Note
The String returning overload converts to String with kDefaultToStringConverter (Characters::ToString - mostly), so this may not be a suitable conversion in all cases (mostly intended for debugging or quick cheap display)
Example Usage
Iterable<InternetAddress> c{IO::Network::V4::kLocalhost, IO::Network::V4::kAddrAny};
EXPECT_EQ (c.Join (), "localhost, INADDR_ANY");
EXPECT_EQ (c.Join ("; "), "localhost; INADDR_ANY");
Example Usage
const Iterable<String> kT1_{"a", "b"};
const Iterable<String> kT2_{"a", "b", "c"};
EXPECT_EQ (kT1_.Join (Characters::UnoverloadedToString<String>), "'a', 'b'");
EXPECT_EQ (kT1_.Join (Iterable<String>::kDefaultToStringConverter<String>), kT1_.Join ());
// Common::Identity{} produces no transformation, and the combiner function just directly concatenates with no separator
EXPECT_EQ (kT1_.Join (Common::Identity{}, [] (auto l, auto r, bool) { return l + r; }), "ab");
EXPECT_EQ (kT1_.Join (), "a, b");
EXPECT_EQ (kT1_.Join (" "), "a b");
EXPECT_EQ (kT1_.Join (", ", " and "), "a and b");
EXPECT_EQ (kT2_.Join (", ", " and "), "a, b and c");
EXPECT_EQ (kT2_.Join ([] (auto i) { return i.ToUpperCase (); }), "A, B, C");
EXPECT_EQ (kT2_.Join ([] (auto i) { return i.ToUpperCase (); }, "; "sv, " and "sv), "A; B and C");
function object whose action is to map its argument, back to the same value it started with (identity...

See:

See also
Accumulate

◆ Skip()

template<typename T >
Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Skip ( size_t  nItems) const

BASED ON Microsoft .net Linq.

This returns an Iterable<T> with a subset of data after skipping the argument number of items. If the number of items skipped is greater or equal to the length of the original Iterable, then an empty Iterable is returned.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Skip (3).SequentialEquals (Iterable<int> { 4, 5, 6 }));
See also
https://msdn.microsoft.com/en-us/library/bb358985%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396 @Take

Definition at line 655 of file Iterable.inl.

◆ Take()

template<typename T >
Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Take ( size_t  nItems) const

BASED ON Microsoft .net Linq.

This returns an Iterable<T> with up to nItems taken from the front of this starting iterable. If this Iterable is shorter, Take () returns just the original Iterable

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Take (3).SequentialEquals (Iterable<int> { 1, 2, 3 }));
See also
https://msdn.microsoft.com/en-us/library/bb503062(v=vs.110).aspx @Skip

Definition at line 678 of file Iterable.inl.

◆ Slice()

template<typename T >
Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Slice ( size_t  from,
size_t  to 
) const

This returns an Iterable<T> based on the current iterable, with the subset from position from to to. If some items don't exist, the resulting list is shortened (not an assertion error). Item at from is included in the output, but item 'to' is not included.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Slice (3, 5).SequentialEquals ({ 4, 5 }));
Precondition
from <= to
Note
equivalent to Skip (from).Take (to-from)
See also
https://www.w3schools.com/jsref/jsref_slice_array.asp (EXCEPT FOR NOW - we don't support negative indexes or optional args; maybe do that for SEQUENCE subclass?)
Take
Slice

Definition at line 701 of file Iterable.inl.

◆ Top()

template<typename T >
Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Top ( ) const

return the top/largest (possibly just top N) values from this Iterable<T>

Provide a function object that says how you want to compare the 'T' elements. OPTIONALLY, provide a number N, saying to return the top N results (if N < size, just return size elements).

Performance: let S = this->size(); O(S) * ln (N) ; so S*log(S) if you get all of them, but if you just need the top three, its O(S)

Example Usage
Iterable<int> c{ 3, 5, 9, 38, 3, 5 };
EXPECT_TRUE (c.Top ().SequentialEquals (c.OrderBy (std::greater<int>{})));
EXPECT_TRUE (c.Top (2).SequentialEquals ({38, 9}));
EXPECT_TRUE (c.Top (2, std::greater<int>{}).SequentialEquals ({38, 9})); // same as previous line
EXPECT_TRUE (c.Top (3, std::less<int>{}).SequentialEquals ({3, 3, 5}));
Note
Uses IPotentiallyComparer instead of IInOrderComparer since from context, if you pass in a lambda, it should be clear about intent.

Definition at line 777 of file Iterable.inl.

◆ OrderBy()

template<typename T >
template<Common::IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::OrderBy ( INORDER_COMPARER_TYPE &&  inorderComparer = INORDER_COMPARER_TYPE{},
Execution::SequencePolicy  seq = Execution::SequencePolicy::ePar 
) const

BASED ON Microsoft .net Linq.

Example Usage
Iterable<int> c{ 3, 5, 9, 38, 3, 5 };
EXPECT_TRUE (c.OrderBy ().SequentialEquals ({ 3, 3, 5, 5, 9, 38 }));
Example Usage
Iterable<int> c{ 3, 5, 9, 38, 3, 5 };
EXPECT_TRUE (c.OrderBy ([](int lhs, int rhs) -> bool { return lhs < rhs; }).SequentialEquals ({ 3, 3, 5, 5, 9, 38 }));
Note
This defaults to using seq=Execution::SequencePolicy::ePar, parallel sort, so be careful if your compare function doesn't support this - pass in SequencePolicy::eSeq
This performs a stable sort (preserving the relative order of items that compare equal). That maybe less performant than a regular (e.g. quicksort) but works better as a default, in most cases, as it allows combining multi-level sorts.
Aliases
Sort ()
Note
Should be of type IInOrderComparer, but not required - for convenience of use (so can be used with any lambda functor)

See:

See also
https://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderby(v=vs.110).aspx
IsOrderedBy ()
Postcondition
result.IsOrderedBy (inorderComparer);

◆ IsOrderedBy()

template<typename T >
template<Common::IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual bool Stroika::Foundation::Traversal::Iterable< T >::IsOrderedBy ( INORDER_COMPARER_TYPE &&  inorderComparer = INORDER_COMPARER_TYPE{}) const
Aliases
IsSorted ()
See also
OrderBy ()

◆ First()

template<typename T >
optional< T > Stroika::Foundation::Traversal::Iterable< T >::First ( ) const

return first element in iterable, or if 'that' specified, first where 'that' is true, (or return nullopt if none)

Aliases
Find () - but in Stroika, Find () returns an Iterator<>
Example Usage
Iterable<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_EQ (*c.First (), 3);
EXPECT_EQ (*c.First ([](int i){ return i % 2 == 0;}), 38);
Example Usage
Collection<SomeStruct> c;
if (optional<SomeStruct> o = c.First ([=](SomeStruct smi) { return smi.fID == substanceId; })) {
something_with_o (o);
}
Note
BASED ON Microsoft .net Linq.
See also
https://msdn.microsoft.com/en-us/library/system.linq.enumerable.first(v=vs.110).aspx

Definition at line 829 of file Iterable.inl.

◆ FirstValue()

template<typename T >
T Stroika::Foundation::Traversal::Iterable< T >::FirstValue ( ArgByValueType< T >  defaultValue = {}) const

return first element in iterable provided default

Example Usage
Iterable<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_EQ (c.FirstValue (), 3);
Note
BASED ON Microsoft .net Linq. (FirstOrDefault)
See also
https://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault(v=vs.110).aspx

Definition at line 876 of file Iterable.inl.

◆ Last()

template<typename T >
optional< T > Stroika::Foundation::Traversal::Iterable< T >::Last ( ) const

return last element in iterable, or if 'that' specified, last where 'that' is true, (or return missing)

Example Usage
Iterable<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_EQ (*c.Last (), 5);
EXPECT_EQ (*c.Last ([](int i){ return i % 2 == 0;}), 38);
Note
BASED ON Microsoft .net Linq. (Last)
See also
https://msdn.microsoft.com/en-us/library/system.linq.enumerable.last(v=vs.110).aspx

Definition at line 888 of file Iterable.inl.

◆ LastValue()

template<typename T >
T Stroika::Foundation::Traversal::Iterable< T >::LastValue ( ArgByValueType< T >  defaultValue = {}) const

BASED ON Microsoft .net Linq. (LastOrDefault)

Example Usage
Iterable<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_EQ (c.LastValue (), 5);

See:

See also
https://msdn.microsoft.com/en-us/library/system.linq.enumerable.lastordefault(v=vs.110).aspx

Definition at line 928 of file Iterable.inl.

◆ All()

template<typename T >
bool Stroika::Foundation::Traversal::Iterable< T >::All ( const function< bool(ArgByValueType< T >)> &  testEachElt) const

return true iff argument predicate returns true for each element of the iterable

Example Usage
Iterable<int> c { 3, 5, 9, 3, 5 };
EXPECT_TRUE (c.All ([](int i){ return i % 2 == 1;}));
Note
BASED ON Microsoft .net Linq. (Last)
See also
https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.all?view=netframework-4.7.2
also Iterable<T>::Where ()

Definition at line 940 of file Iterable.inl.

◆ Min()

template<typename T >
optional< T > Stroika::Foundation::Traversal::Iterable< T >::Min ( ) const

BASED ON Microsoft .net Linq.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Min () == 1);
Note
returns nullopt if empty list
Equivalent to Reduce ([] (T lhs, T rhs) { return min (lhs, rhs); })

See: https://msdn.microsoft.com/en-us/library/bb503062%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396 @Max

Definition at line 973 of file Iterable.inl.

◆ MinValue()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE Stroika::Foundation::Traversal::Iterable< T >::MinValue ( ArgByValueType< RESULT_TYPE >  defaultValue = {}) const
See also
@Max

◆ Max()

template<typename T >
optional< T > Stroika::Foundation::Traversal::Iterable< T >::Max ( ) const

BASED ON Microsoft .net Linq.

EXAMPLE:

Iterable<int> c { 1, 2, 3, 4, 5, 6 };
EXPECT_TRUE (c.Max () == 6);
Note
returns nullopt if empty list
Equivalent to Reduce ([] (T lhs, T rhs) { return max (lhs, rhs); })

See: https://msdn.microsoft.com/en-us/library/bb503062%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396 @Min

Definition at line 984 of file Iterable.inl.

◆ MaxValue()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE Stroika::Foundation::Traversal::Iterable< T >::MaxValue ( ArgByValueType< RESULT_TYPE >  defaultValue = {}) const
See also
@Max

◆ Mean()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual optional< RESULT_TYPE > Stroika::Foundation::Traversal::Iterable< T >::Mean ( ) const

BASED ON Microsoft .net Linq.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 9 };
EXPECT_EQ (c.Mean (), 4);
Note
returns nullopt if empty list

AKA "Average"

See: https://msdn.microsoft.com/en-us/library/bb548647(v=vs.100).aspx

◆ MeanValue()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE Stroika::Foundation::Traversal::Iterable< T >::MeanValue ( ArgByValueType< RESULT_TYPE >  defaultValue = {}) const
See also
@Mean

◆ Sum()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual optional< RESULT_TYPE > Stroika::Foundation::Traversal::Iterable< T >::Sum ( ) const

BASED ON Microsoft .net Linq.

Example Usage
Iterable<int> c { 1, 2, 3, 4, 5, 9 };
EXPECT_TRUE (c.Sum () == 24);
Note
Equivalent to Reduce ([] (T lhs, T rhs) { return lhs + rhs; })
returns nullopt if empty list

See: https://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum(v=vs.110).aspx

◆ SumValue()

template<typename T >
template<typename RESULT_TYPE = T>
nonvirtual RESULT_TYPE Stroika::Foundation::Traversal::Iterable< T >::SumValue ( ArgByValueType< RESULT_TYPE >  defaultValue = {}) const
See also
@Sum

◆ Median()

template<typename T >
template<constructible_from< T > RESULT_TYPE = T, Common::IPotentiallyComparer< RESULT_TYPE > INORDER_COMPARE_FUNCTION = less<RESULT_TYPE>>
nonvirtual optional< RESULT_TYPE > Stroika::Foundation::Traversal::Iterable< T >::Median ( const INORDER_COMPARE_FUNCTION &  compare = {}) const
Example Usage
Iterable<int> c { 1, 2, 9, 4, 5, 3 };
EXPECT_TRUE (NearlyEquals (c.Median (), 3.5));
Note
returns nullopt if empty list
Should be of type IInOrderComparer, but not required - for convenience of use (so can be used with any lambda functor)

◆ MedianValue()

template<typename T >
template<constructible_from< T > RESULT_TYPE = T>
nonvirtual RESULT_TYPE Stroika::Foundation::Traversal::Iterable< T >::MedianValue ( ArgByValueType< RESULT_TYPE >  defaultValue = {}) const
See also
@Median

◆ Repeat()

template<typename T >
Iterable< T > Stroika::Foundation::Traversal::Iterable< T >::Repeat ( size_t  count) const

Return this iterable n (count) times. count may be zero, or any other unsigned integer. Repeat (0) returns an empty list, and Repeat (1) returns *this;

Similar to https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.repeat?view=netcore-3.1

Example Usage
EXPECT_TRUE (c.Repeat (5).SequentialEquals ({1, 1, 1, 1, 1}));

Definition at line 1039 of file Iterable.inl.

◆ Any()

template<typename T >
bool Stroika::Foundation::Traversal::Iterable< T >::Any ( ) const

Any() same as not empty (); Any (includeIfTrue) returns true iff includeIfTrue returns true on any values in iterable.

Note
BASED ON Microsoft .net Linq. (Last)
See also
https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=netframework-4.7.2#System_Linq_Enumerable_Any__1_System_Collections_Generic_IEnumerable___0__System_Func___0_System_Boolean__
Note
See also
Count
Note
See also
Where
Aliases
AnyThat (predicate)

Definition at line 1068 of file Iterable.inl.

◆ Count()

template<typename T >
size_t Stroika::Foundation::Traversal::Iterable< T >::Count ( ) const

with no args, same as size, with function filter arg, returns number of items that pass.

Note
BASED ON Microsoft .net Linq. (Count)
See also
https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.count?view=net-6.0
Note
Count/1 same as Where (i).size ();
See also
Any

Definition at line 1078 of file Iterable.inl.

◆ _GetSharingState()

template<typename T >
Memory::SharedByValue_State Stroika::Foundation::Traversal::Iterable< T >::_GetSharingState ( ) const
protected
See also
Memory::SharedByValue_State

Don't call this lightly. This is just meant for low level or debugging, and for subclass optimizations based on the state of the shared common object.

Definition at line 289 of file Iterable.inl.

Member Data Documentation

◆ kDefaultToStringConverter

template<typename T >
template<same_as< Characters::String > RESULT_T = Characters::String>
const function<RESULT_T (T)> Stroika::Foundation::Traversal::Iterable< T >::kDefaultToStringConverter
static
Initial value:
= [] () -> function<Characters::String (T)> {
if constexpr (same_as<T, Characters::String> and same_as<RESULT_T, Characters::String>) {
return Common::Identity{};
}
else {
return Characters::UnoverloadedToString<T>;
}
}()

kDefaultToStringConverter encapsulates the algorithm used to map T objects to printable strings. As this is mainly used for debugging, it defaults to using Characters::ToString() - and so maybe lossy.

For plain Strings - however, it just uses Common::Identity (no mapping). So that when used in Join - you get no changes to the argument strings (by default - easy to pass in lambda todo what you want to Join).

Note
- logically - kDefaultToStringConverter takes no template parameter, but in practical use, it must just to postpone the evaluation of its type argument and avoid a direct dependency on the String module, which in turn depends on this module.

Definition at line 879 of file Iterable.h.

◆ _fRep

template<typename T >
_SharedByValueRepType Stroika::Foundation::Traversal::Iterable< T >::_fRep
protected

Rarely access in subclasses, but its occasionally needed, like in UpdatableIterator<T>

Definition at line 1435 of file Iterable.h.


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