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

A generalization of a vector: a container whose elements are keyed by the natural numbers. More...

#include <Sequence.h>

Inheritance diagram for Stroika::Foundation::Containers::Sequence< T >:
Stroika::Foundation::Traversal::Iterable< T > Stroika::Foundation::Containers::Private::ArrayBasedContainer< Sequence_Array< T >, Sequence< T >, false > Stroika::Foundation::Containers::Private::StdVectorBasedContainer< Sequence_stdvector< T >, Sequence< T > > Stroika::Foundation::Containers::Concrete::Sequence_ChunckedArray< T, CHUNK_SIZE > Stroika::Foundation::Containers::Concrete::Sequence_DoublyLinkedList< T > Stroika::Foundation::Containers::Concrete::Sequence_LinkedList< T > Stroika::Foundation::Containers::Concrete::Sequence_SparseSortedMapping< T > Stroika::Foundation::Containers::Concrete::Sequence_Array< T > Stroika::Foundation::Containers::Concrete::Sequence_stdvector< T >

Classes

class  _IRep
 Implementation detail for Sequence<T> implementors. More...
 

Public Types

using value_type = typename inherited::value_type
 
using ArchetypeContainerType = Sequence
 
template<Common::IEqualsComparer< T > T_EQUALS_COMPARER = equal_to<T>>
using EqualsComparer = typename Iterable< value_type >::template SequentialEqualsComparer< T_EQUALS_COMPARER >
 
- 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 >
 

Public Member Functions

 Sequence ()
 
template<typename RESULT_CONTAINER = Sequence<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
 'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Sequence, and improve that case to clone properties from this rep (such is rep type, etc).
 
template<derived_from< Iterable< T > > RESULT_CONTAINER = Sequence<T>, predicate< T > INCLUDE_PREDICATE>
nonvirtual RESULT_CONTAINER Where (INCLUDE_PREDICATE &&includeIfTrue) const
 
template<IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual Sequence OrderBy (INORDER_COMPARER_TYPE &&inorderComparer=INORDER_COMPARER_TYPE{}) const
 
nonvirtual bool operator== (const Sequence &rhs) const
 
nonvirtual auto operator<=> (const Sequence &rhs) const
 
nonvirtual void RemoveAll ()
 RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items.
 
nonvirtual value_type GetAt (size_t i) const
 
nonvirtual void SetAt (size_t i, ArgByValueType< value_type > item)
 
nonvirtual const value_type operator[] (size_t i) const
 alias for GetAt (i) - but returning const T
 
nonvirtual TemporaryElementReference_ operator() (size_t i)
 operator() is similar to operator[] - but returning TemporaryElementReference_, and so is updatable/writable
 
template<Common::IEqualsComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual optional< size_t > IndexOf (ArgByValueType< value_type > i, EQUALS_COMPARER &&equalsComparer={}) const
 
nonvirtual void Insert (size_t i, ArgByValueType< value_type > item)
 
template<IInputIterator< T > ITERATOR_OF_ADDABLE, sentinel_for< ITERATOR_OF_ADDABLE > ITERATOR_OF_ADDABLE2>
nonvirtual void InsertAll (size_t i, ITERATOR_OF_ADDABLE &&start, ITERATOR_OF_ADDABLE2 &&end)
 Insert all the given items into this sequence, starting at offset 'i'.
 
nonvirtual void Prepend (ArgByValueType< value_type > item)
 
template<IIterableOfTo< T > ITERABLE_OF_ADDABLE>
nonvirtual void PrependAll (ITERABLE_OF_ADDABLE &&s)
 
nonvirtual void Append (ArgByValueType< value_type > item)
 
template<IIterableOfTo< T > ITERABLE_OF_ADDABLE>
nonvirtual void AppendAll (ITERABLE_OF_ADDABLE &&s)
 
nonvirtual void Update (const Iterator< value_type > &i, ArgByValueType< value_type > newValue, Iterator< value_type > *nextI=nullptr)
 
nonvirtual void Remove (size_t i)
 
nonvirtual optional< value_typeFirst () const
 
nonvirtual value_type FirstValue (ArgByValueType< value_type > defaultValue={}) const
 
nonvirtual optional< value_typeLast () const
 
nonvirtual value_type LastValue (ArgByValueType< value_type > defaultValue={}) const
 
nonvirtual void push_back (ArgByValueType< value_type > item)
 
nonvirtual value_type back () const
 
nonvirtual void clear ()
 
nonvirtual void erase (size_t i)
 
nonvirtual Sequenceoperator+= (ArgByValueType< value_type > item)
 Alias for Append/AppendAll ().
 
- 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.
 

Protected Member Functions

nonvirtual tuple< _IRep *, Iterator< value_type > > _GetWritableRepAndPatchAssociatedIterator (const Iterator< value_type > &i)
 Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ()) but where we also handle the cloning/patching of the associated iterator.
 
- 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
 

Additional Inherited Members

- 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 Attributes inherited from Stroika::Foundation::Traversal::Iterable< T >
_SharedByValueRepType _fRep
 

Detailed Description

template<typename T>
class Stroika::Foundation::Containers::Sequence< T >

A generalization of a vector: a container whose elements are keyed by the natural numbers.

SmallTalk book page 153

TODO:

-> At some point in the near future we may add the ability to start at an arbitrary point in a sequence, and end at an arbitrary point. This requires more thought though. That functionality is probably not too important in light of being able to compute the current index easily in an iteration. Also, it requires more thought how to fit in with the sequenceDirection. Do we have a separate constructor specifying two start and endpoints and use their relative order to decide a direction? Do we just add the two start and end values to the end of the param list? How hard is this todo with Sequence_DLL?? If this functionality is subsumed by smart-iterators, does it make sense to wait to we provide that functionality?

-> Figure out exactly what we will do about sorting/lookup function specification. Stroustrup like class param with somehow defaulting to op==????

-> Add SetLength() method. Make sure it is optimally efficient, but try to avoid introducing a virtual function. Probably overload, and 1 arg version will use T default CTOR. If done non-virtually with templates then we only require no arg CTOR when this function called - GOOD. Cannot really do with GenClass (would need to compile in separate .o, even that wont work - need to not compile except when called).

-> Consider patching iterators on insertions??? If not, document more clearly why not. Document exact details of patching in SEQUENCE as part of API!!!!

Notes:

 Note: the decision on arguments to a Sort() function was difficult.

Making the arg default to op <= would not work since for type int it wouldn't be defined, and sometimes people define it as a member function, or taking const T& args. Thus the function pointer type would not match. The other alternative is to overload, and have the no arg function just have a static private CompareFunction that calls op<=. This does work pretty well, BUT it fails in cases like Sequence(Picture) where there is no op<= defined. Here, we could force the definition of this function, but that would be generally awkward and was judged not worth the trouble. Just define your own little compare function that does op <=. That simple.

The other approach sterl's been pushing is that of functional objects

described in Coplain, and the latest Stroustrup book (Nov 91). I haven't looked closely enuf to decide.

Another important addition was the CurrentIndex method. This was

decided since it allowed for easy filtering (like only third thru eight elements, or only odd elements) without keeping an extra index variable which was often very awkward. This feature will probably be seldom used, and is seldom needed, but is one of the few things that differentiate a SequenceForEach from a Sequence (ie SequenceIterator from CollectionIterator). This statement really comes down to our really only needing sequence iterators rarely, and mostly using CollectionIterators.

Note
Iterators Note that iterators always run in Sequence order, from smallest index to largest. Items inserted before the current iterator index will not be encountered, and items inserted after the current index will be encountered. Items inserted at the current index remain undefined if they will be encountered or not.

Concrete Implementations: o

See also
Concrete::Sequence_Array<> o
Concrete::Sequence_DoublyLinkedList<> o
Concrete::Sequence_LinkedList<> o
Concrete::Sequence_stdvector<>

Factory:

See also
Sequence_Factory<> to see default implementations.
Note
Thread-Safety C++-Standard-Thread-Safety
Design Note - TRAITS for equals versus COMPARER template param to methods that need it We experimented (until Stroika 2.0a20 apx) with using TRAITS that were optional with Sequence<> - and had the equals comparer. This worked OK. The advantage of having the 'equals' method in the TRAITS was that it assured (for a given instance of Sequence) that all comparisons/notions of equality were tied to the instance.

The idea WAS that you could even have a comparer that stored data in the instance (we never implemented that).

But this notion of equals has problems for defining Sequence<>::Equals() - do you use the one from the RHS or LHS?

Plus - making it a template param just added to the syntactic garbage in the template names (like in the debugger how the names printed out). This is no biggie, but it wasn't a plus.

So now (as of v2.0a20) - we just have the EQUALS_COMPARER be a templated param to the methods that need it.

Note
See ReadMe.md for common features of all Stroika containers (especially constructors, iterators, etc)
Comparisons: o static_assert (equality_comparable<T> ==> equality_comparable<Sequence<T>>); o static_assert (totally_ordered<T> ==> totally_ordered<Sequence<T>>); o using EqualsComparer = typename Iterable<T>::template SequentialEqualsComparer<T_EQUALS_COMPARER>; o using ThreeWayComparer = typename Iterable<T>::template SequentialThreeWayComparer<T_EQUALS_COMPARER>;

Definition at line 187 of file Sequence.h.

Member Typedef Documentation

◆ value_type

template<typename T >
using Stroika::Foundation::Containers::Sequence< T >::value_type = typename inherited::value_type
See also
inherited::value_type

Definition at line 198 of file Sequence.h.

◆ ArchetypeContainerType

template<typename T >
using Stroika::Foundation::Containers::Sequence< T >::ArchetypeContainerType = Sequence

Use this typedef in templates to recover the basic functional container pattern of concrete types.

Definition at line 204 of file Sequence.h.

◆ EqualsComparer

template<typename T >
template<Common::IEqualsComparer< T > T_EQUALS_COMPARER = equal_to<T>>
using Stroika::Foundation::Containers::Sequence< T >::EqualsComparer = typename Iterable<value_type>::template SequentialEqualsComparer<T_EQUALS_COMPARER>

simply indirect to @Iterable<T>::SequentialEqualsComparer

A Sequence<T> doesn't generally require a comparison for individual elements be be defined, but obviously to compare if the containers are equal, you must compare the individual elements (at least sometimes).

If operator==(T,T) is predefined, you can just call:

Example Usage
if (a == b) {
}
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187

or

if (Sequence<int>::EqualsComparer{eltComparer} (a, b)) {
}
typename Iterable< value_type >::template SequentialEqualsComparer< T_EQUALS_COMPARER > EqualsComparer
Definition Sequence.h:327

to compare with an alternative comparer.

Definition at line 327 of file Sequence.h.

Constructor & Destructor Documentation

◆ Sequence()

template<typename T >
Stroika::Foundation::Containers::Sequence< T >::Sequence ( )

For the CTOR overload with ITERABLE_OF_ADDABLE, its anything that supports c.begin(), c.end () to find all the elements.

Note
See general information about container constructors that applies here
Example Usage
std::vector<int> v;
Sequence<int> s1 = {1, 2, 3};
Sequence<int> s2 = s1;
Sequence<int> s3{ s1 };
Sequence<int> s4{ s1.begin (), s1.end () };
Sequence<int> s5{ c };
Sequence<int> s6{ v };
Sequence<int> s7{ v.begin (), v.end () };
Sequence<int> s8{ move (s1) };
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
Definition Collection.h:102
nonvirtual Iterator< T > begin() const
Support for ranged for, and STL syntax in general.
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.

Definition at line 129 of file Sequence.inl.

Member Function Documentation

◆ Where()

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

Apply the function function to each element, and return all the ones for which it was true.

See also
Iterable<T>::Where

◆ OrderBy()

template<typename T >
template<IPotentiallyComparer< T > INORDER_COMPARER_TYPE = less<T>>
nonvirtual Sequence Stroika::Foundation::Containers::Sequence< T >::OrderBy ( INORDER_COMPARER_TYPE &&  inorderComparer = INORDER_COMPARER_TYPE{}) const
Example Usage
Sequence<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_TRUE (c.OrderBy () == Sequence<int> { 3, 3, 5, 5, 9, 38 });
Example Usage
Sequence<int> c { 3, 5, 9, 38, 3, 5 };
EXPECT_TRUE (c.OrderBy ([](int lhs, int rhs) -> bool { return lhs < rhs; }) == Sequence<int> { 3, 3, 5, 5, 9, 38 });
Note
hides Iterable<T>::OrderBy since provides more specific types
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)

◆ operator==()

template<typename T >
requires (equality_comparable<T>)
bool Stroika::Foundation::Containers::Sequence< T >::operator== ( const Sequence< T > &  rhs) const

simply indirect to @Sequence<>EqualsComparer

Definition at line 499 of file Sequence.inl.

◆ operator<=>()

template<typename T >
requires (three_way_comparable<T>)
auto Stroika::Foundation::Containers::Sequence< T >::operator<=> ( const Sequence< T > &  rhs) const

simply indirect to @Sequence<>::operator

Definition at line 505 of file Sequence.inl.

◆ RemoveAll()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::RemoveAll ( )

RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items.

The no-arg overload removes all (quickly).

The overloads that remove some subset of the items returns the number of items so removed.

Note
mutates container

Definition at line 209 of file Sequence.inl.

◆ GetAt()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::GetAt ( size_t  i) const
Precondition
i < size ()

Definition at line 237 of file Sequence.inl.

◆ SetAt()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::SetAt ( size_t  i,
ArgByValueType< value_type item 
)
Precondition
i < size ()
Note
mutates container

Definition at line 244 of file Sequence.inl.

◆ operator[]()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::operator[] ( size_t  i) const

alias for GetAt (i) - but returning const T

Aliases
GetAt
Precondition
i < size ().
Note
this returns const value_type, so you cannot accidentally assign to the result a[3] = 4; // wont compile because return type const
- we investigated having operator[] (int) return TemporaryElementReference_, but the trouble is that, though this almost works, the COST of TemporaryElementReference_ is much higher than returning the cost value_type, and its not super obvious at call point that you are getting the expensive or inexpensive version (depends on constness of this pointer).

Also considered having this return T&, the way you would with std c++ vector (etc). This would avoid a lot of issues. BUT - it would BREAK the COW (copy-on-write) semantics. Consider if we had a single reference to a sequence. And we grab the value_type& (to update it; this doesn't increase refCnt for container). Then in another thread, we access the sequence (incrementing its reps ref count). We could be updating through that saved reference to T while the other thread is looking at the sequence - a dangerous race.

So because all of this, use the syntax a(3) instead of a[3] if you want a modifiable reference (to call non-const methods on or to assign to).

Definition at line 251 of file Sequence.inl.

◆ operator()()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::operator() ( size_t  i)

operator() is similar to operator[] - but returning TemporaryElementReference_, and so is updatable/writable

See the notes on operator[]. The semantics of this method are similar to operator[], except that it returns a proxy object which allows (immediately) updating the element of the sequence.

Example Usage
Sequence<T> s = ...;
s(2) = 4; // s[2] = 4; WONT COMPILE

is equivalent to

auto t = s.GetAt (2);
t = 4;
s.SetAt (2, i); // note when using operator() - this SetAt() dont even if t not updated so wasteful unless updating
nonvirtual void SetAt(size_t i, ArgByValueType< value_type > item)
Definition Sequence.inl:244
nonvirtual value_type GetAt(size_t i) const
Definition Sequence.inl:237
Precondition
i < size ()
Note
mutates container

Definition at line 258 of file Sequence.inl.

◆ IndexOf()

template<typename T >
template<Common::IEqualsComparer< T > EQUALS_COMPARER = equal_to<T>>
nonvirtual optional< size_t > Stroika::Foundation::Containers::Sequence< T >::IndexOf ( ArgByValueType< value_type i,
EQUALS_COMPARER &&  equalsComparer = {} 
) const
Search the sequence and see if the given item is contained in

it, and return the index of that item. Comparison is done with TRAITS::EqualsCompareFunctionType (which defaults to operator== (T, T)) for first two overloads - third taking iterator always works)

Note that the IndexOf(Iterator<T>) overload ignores the EQUALS_COMPARER but still must be a template method because non-template methods cannot be overloaded with template members.

If not found for the by value overloads, IndexOf () return {}; For the IndexOf(Iterator<T>) -

Precondition
it is found/legal iterator

◆ Insert()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::Insert ( size_t  i,
ArgByValueType< value_type item 
)
Insert the given item into the sequence at the given index.

Any active iterators will encounter the given item if their cursor encounters the new index in the course of iteration. Put another way, If you are iterating forwards, and you add an item after what you are up to you will hit it - if you are iterating backwards and you add an item before where you are, you will hit it - otherwise you will miss the added item during iteration.

NB: Adding an item at the CURRENT index has no effect on

what the iterator says is the current item.

Note
mutates container

Definition at line 281 of file Sequence.inl.

◆ InsertAll()

template<typename T >
template<IInputIterator< T > ITERATOR_OF_ADDABLE, sentinel_for< ITERATOR_OF_ADDABLE > ITERATOR_OF_ADDABLE2>
nonvirtual void Stroika::Foundation::Containers::Sequence< T >::InsertAll ( size_t  i,
ITERATOR_OF_ADDABLE &&  start,
ITERATOR_OF_ADDABLE2 &&  end 
)

Insert all the given items into this sequence, starting at offset 'i'.

Precondition
IInputIterator<ITERATOR_OF_ADDABLE, T> or IIterableOfTo<ITERABLE_OF_ADDABLE, T>

◆ Prepend()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::Prepend ( ArgByValueType< value_type item)
Note
mutates container

Definition at line 313 of file Sequence.inl.

◆ PrependAll()

template<typename T >
template<IIterableOfTo< T > ITERABLE_OF_ADDABLE>
nonvirtual void Stroika::Foundation::Containers::Sequence< T >::PrependAll ( ITERABLE_OF_ADDABLE &&  s)
Precondition
IInputIterator<ITERATOR_OF_ADDABLE, T> or IIterableOfTo<ITERABLE_OF_ADDABLE, T>
Note
mutates container

◆ Append()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::Append ( ArgByValueType< value_type item)

This is roughly Insert (size(), item), except that there is a race after you call size, and before Insert, which calling Append () avoids.

Note
mutates container

Definition at line 330 of file Sequence.inl.

◆ AppendAll()

template<typename T >
template<IIterableOfTo< T > ITERABLE_OF_ADDABLE>
nonvirtual void Stroika::Foundation::Containers::Sequence< T >::AppendAll ( ITERABLE_OF_ADDABLE &&  s)

This is roughly AppendAll (size(), s), except that there is a race after you call size, and before Insert, which calling Append () avoids. Also note - if used in a multithreaded environment, the appended items wont necessarily all get appended at once, since other threads could make changes in between.

Note
mutates container

◆ Update()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::Update ( const Iterator< value_type > &  i,
ArgByValueType< value_type newValue,
Iterator< value_type > *  nextI = nullptr 
)

This function requires that the iterator 'i' came from this container.

The value pointed to by 'i' is updated - replaced with the value 'newValue'.

Parameters
nextI- if provided (not null) - will be filled in with a valid iterator pointing where i is pointing - since i is invalidated by changing the container)
Note
- this differs from Collection::Update() (which advances *nextI); since for a sequence, there is no need to ever invalidate the current item on a removal (order doesnt change on update to a Sequence).
mutates container

Definition at line 351 of file Sequence.inl.

◆ Remove()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::Remove ( size_t  i)

This function requires that the iterator 'i' came from this container.

The value pointed to by 'i' is removed.

Remove the item at the given position of the sequence. Make sure that iteration is not disturbed by this removal. In particular, any items (other than the one at index) that would have been seen, will still be, and no new items will be seen that wouldn't have been.

Note
mutates container

Definition at line 358 of file Sequence.inl.

◆ First()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::First ( ) const
See also
Iterable<T>::First ()

Definition at line 403 of file Sequence.inl.

◆ FirstValue()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::FirstValue ( ArgByValueType< value_type defaultValue = {}) const
See also
Iterable<T>::FirstValue ()

Definition at line 413 of file Sequence.inl.

◆ Last()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::Last ( ) const
See also
Iterable<T>::Last ()

Definition at line 418 of file Sequence.inl.

◆ LastValue()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::LastValue ( ArgByValueType< value_type defaultValue = {}) const
See also
Iterable<T>::LastValue ()

Definition at line 430 of file Sequence.inl.

◆ push_back()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::push_back ( ArgByValueType< value_type item)
Aliases
Append
Note
mutates container

Definition at line 436 of file Sequence.inl.

◆ back()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::back ( ) const

Read the last element (GetLast()). Requires not empty.

Definition at line 441 of file Sequence.inl.

◆ clear()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::clear ( )
Aliases
RemoveAll ().

Definition at line 451 of file Sequence.inl.

◆ erase()

template<typename T >
void Stroika::Foundation::Containers::Sequence< T >::erase ( size_t  i)
Aliases
Remove ().
Note
mutates container

Definition at line 456 of file Sequence.inl.

◆ _GetWritableRepAndPatchAssociatedIterator()

template<typename T >
auto Stroika::Foundation::Containers::Sequence< T >::_GetWritableRepAndPatchAssociatedIterator ( const Iterator< value_type > &  i)
protected

Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRepAccessor<_IRep>{this}._GetWriteableRep ()) but where we also handle the cloning/patching of the associated iterator.

When you have a non-const operation (such as Remove) with an argument of an Iterator<>, then due to COW, you may end up cloning the container rep, and yet the Iterator<> contains a pointer to the earlier rep (and so maybe unusable).

Prior to Stroika 2.1b14, this was handled elegantly, and automatically, by the iterator patching mechanism. But that was deprecated (due to cost, and rarity of use), in favor of this more restricted feature, where we just patch the iterators on an as-needed basis.

Definition at line 480 of file Sequence.inl.


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