A generalization of a vector: a container whose elements are keyed by the natural numbers. More...
#include <Sequence.h>
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 () | |
| nonvirtual BidirectionalIterator< T > | MakeBidirectionalIterator () const |
| Create a BidirectionalIterator for this sequence (note inherited Iterable<T>::MakeIterator () returns a forward iterator, not a random access or bidirectional iterator). | |
| nonvirtual RandomAccessIterator< T > | MakeRandomAccessIterator () const |
| Create a RandomAccessIterator for this sequence (note inherited Iterable<T>::MakeIterator () returns a forward iterator, not a random access iterator). | |
|
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) |
| template<typename CONTAINER_OF_ADDABLE > | |
| nonvirtual void | As (CONTAINER_OF_ADDABLE *into) const |
| write this Sequence into an existing container | |
| nonvirtual optional< value_type > | First () const |
| nonvirtual value_type | FirstValue (ArgByValueType< value_type > defaultValue={}) const |
| nonvirtual optional< value_type > | Last () const |
| nonvirtual value_type | LastValue (ArgByValueType< value_type > defaultValue={}) const |
| nonvirtual void | push_back (ArgByValueType< value_type > item) |
| template<IIterableOfTo< T > ITERABLE_OF_ADDABLE> | |
| nonvirtual void | append_range (ITERABLE_OF_ADDABLE &&s) |
| STL-style spelling of AppendAll () - the same operation std::vector calls append_range () | |
| nonvirtual value_type | back () const |
| nonvirtual void | clear () |
| nonvirtual void | insert (const Iterator< value_type > &i, ArgByValueType< value_type > item) |
| nonvirtual void | erase (size_t i) |
| nonvirtual Sequence & | operator+= (ArgByValueType< value_type > item) |
| Alias for Append/AppendAll (). | |
| template<IIterableOfFrom< T > CONTAINER_OF_T, typename... CONTAINER_OF_T_CONSTRUCTOR_ARGS> | |
| nonvirtual CONTAINER_OF_T | As (CONTAINER_OF_T_CONSTRUCTOR_ARGS... args) const |
| Convert Sequence<T> losslessly into a standard supported C++ type - vector<T>, list<T>, ... | |
| template<IIterableOfFrom< T > CONTAINER_OF_T, typename... CONTAINER_OF_T_CONSTRUCTOR_ARGS> | |
| CONTAINER_OF_T | As (CONTAINER_OF_T_CONSTRUCTOR_ARGS... args) const |
| Convert Sequence<T> losslessly into a standard supported C++ type - vector<T>, list<T>, ... | |
Public Member Functions inherited from Stroika::Foundation::Traversal::Iterable< T > | |
| Iterable (const Iterable &) noexcept=default | |
| Iterable are safely copyable (by value). Since Iterable uses COW, this just copies the underlying pointer and increments the reference count. | |
| Iterable (Iterable &&) noexcept=default | |
| Iterable are safely moveable. | |
| template<IIterableOfTo< T > CONTAINER_OF_T> requires (not derived_from<remove_cvref_t<CONTAINER_OF_T>, Iterable<T>> and (copyable<remove_cvref_t<CONTAINER_OF_T>> or same_as<remove_cvref_t<CONTAINER_OF_T>, initializer_list<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) 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) const |
| Run the argument bool-returning function (or lambda) on the elements of the container, and return an iterator pointing at AN element for which it returned true - not necessarily the first (see the note below; use First () if you need the first). | |
| 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 optional< T > | Top () const |
| return the top/largest value (or the 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{}) 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::SharedByValueSupport::SharingState | _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{}) |
| 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 Attributes inherited from Stroika::Foundation::Traversal::Iterable< T > | |
| _SharedByValueRepType | _fRep |
A generalization of a vector: a container whose elements are keyed by the natural numbers.
SmallTalk book page 153
TODO:
-> 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.
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.
Concrete Implementations: o
Factory:
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.
Definition at line 144 of file Library/Sources/Stroika/Foundation/Containers/Sequence.h.
| using Stroika::Foundation::Containers::Sequence< T >::value_type = typename inherited::value_type |
Definition at line 155 of file Library/Sources/Stroika/Foundation/Containers/Sequence.h.
| 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 161 of file Library/Sources/Stroika/Foundation/Containers/Sequence.h.
| 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:
or
to compare with an alternative comparer.
Definition at line 335 of file Library/Sources/Stroika/Foundation/Containers/Sequence.h.
| 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.
Definition at line 241 of file Sequence.inl.
| BidirectionalIterator< T > Stroika::Foundation::Containers::Sequence< T >::MakeBidirectionalIterator | ( | ) | const |
Create a BidirectionalIterator for this sequence (note inherited Iterable<T>::MakeIterator () returns a forward iterator, not a random access or bidirectional iterator).
Definition at line 285 of file Sequence.inl.
| RandomAccessIterator< T > Stroika::Foundation::Containers::Sequence< T >::MakeRandomAccessIterator | ( | ) | const |
Create a RandomAccessIterator for this sequence (note inherited Iterable<T>::MakeIterator () returns a forward iterator, not a random access iterator).
begin () hands back a FORWARD-only Iterator<T>, and end () is not an iterator at all -
it is a default_sentinel_t. So 'i != s.end ()' works, but these two - both of them
reflexes carried over from std::vector - do NOT compile:
\code
for (auto i = s.begin (); i < s.end (); ++i) {...} // no operator< against a sentinel
size_t idx = i - s.begin (); // forward iterators have no difference
\endcode
Neither failure names its remedy - you get a 'no matching operator' template error - so:
\code
for (auto i = s.begin (); i != s.end (); ++i) {...} // just use !=
size_t idx = s.IndexOf (i); // position of an iterator - see IndexOf ()
auto ri = s.MakeRandomAccessIterator (); // or a real RA iterator: Difference (),
// operator+/-, operator--, ordering
\endcode
Prefer IndexOf () when all you want is the position - it is one call and builds no second
iterator. Reach for this method when you actually need the arithmetic or the ordering.
Definition at line 290 of file Sequence.inl.
| 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.
| nonvirtual Sequence Stroika::Foundation::Containers::Sequence< T >::OrderBy | ( | INORDER_COMPARER_TYPE && | inorderComparer = INORDER_COMPARER_TYPE{} | ) | const |
| bool Stroika::Foundation::Containers::Sequence< T >::operator== | ( | const Sequence< T > & | rhs | ) | const |
simply indirect to @Sequence<>EqualsComparer
Definition at line 851 of file Sequence.inl.
| auto Stroika::Foundation::Containers::Sequence< T >::operator<=> | ( | const Sequence< T > & | rhs | ) | const |
simply indirect to @Sequence<>::operator
Definition at line 857 of file Sequence.inl.
| 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.
Definition at line 361 of file Sequence.inl.
| auto Stroika::Foundation::Containers::Sequence< T >::GetAt | ( | size_t | i | ) | const |
Definition at line 389 of file Sequence.inl.
| void Stroika::Foundation::Containers::Sequence< T >::SetAt | ( | size_t | i, |
| ArgByValueType< value_type > | item | ||
| ) |
| auto Stroika::Foundation::Containers::Sequence< T >::operator[] | ( | size_t | i | ) | const |
alias for GetAt (i) - but returning const T
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.
COW is correct only because every write to the rep is preceded by a clone-if-shared check (_GetWriteableRep ()). Handing out a T& moves that check from WRITE time to REFERENCE-ACQUISITION time, and the reference count is free to rise in between. Unlike a non-COW container - where copying never introduces aliasing - copying a Sequence makes a previously exclusive reference shared, without anything touching the reference itself.
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). That returns TemporaryElementReference_, which deliberately holds a Sequence*, an index, and a COPY of the value - never a pointer into the rep - and writes back through SetAt (), so the clone-if-shared check happens at the right moment.
Definition at line 403 of file Sequence.inl.
| 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.
is equivalent to
Definition at line 410 of file Sequence.inl.
| 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>) -
| 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.
Definition at line 464 of file Sequence.inl.
| 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'.
| void Stroika::Foundation::Containers::Sequence< T >::Prepend | ( | ArgByValueType< value_type > | item | ) |
Definition at line 598 of file Sequence.inl.
| nonvirtual void Stroika::Foundation::Containers::Sequence< T >::PrependAll | ( | ITERABLE_OF_ADDABLE && | s | ) |
| 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.
Definition at line 615 of file Sequence.inl.
| 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.
| 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'.
| 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) |
Definition at line 716 of file Sequence.inl.
| 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.
Definition at line 723 of file Sequence.inl.
| nonvirtual void Stroika::Foundation::Containers::Sequence< T >::As | ( | CONTAINER_OF_ADDABLE * | into | ) | const |
write this Sequence into an existing container
| auto Stroika::Foundation::Containers::Sequence< T >::First | ( | ) | const |
Definition at line 749 of file Sequence.inl.
| auto Stroika::Foundation::Containers::Sequence< T >::FirstValue | ( | ArgByValueType< value_type > | defaultValue = {} | ) | const |
Definition at line 759 of file Sequence.inl.
| auto Stroika::Foundation::Containers::Sequence< T >::Last | ( | ) | const |
Definition at line 764 of file Sequence.inl.
| auto Stroika::Foundation::Containers::Sequence< T >::LastValue | ( | ArgByValueType< value_type > | defaultValue = {} | ) | const |
Definition at line 776 of file Sequence.inl.
| void Stroika::Foundation::Containers::Sequence< T >::push_back | ( | ArgByValueType< value_type > | item | ) |
| nonvirtual void Stroika::Foundation::Containers::Sequence< T >::append_range | ( | ITERABLE_OF_ADDABLE && | s | ) |
STL-style spelling of AppendAll () - the same operation std::vector calls append_range ()
Named for C++23's vector::append_range (), which is what the standard library calls appending a whole range.
| auto Stroika::Foundation::Containers::Sequence< T >::back | ( | ) | const |
Read the last element (GetLast()). Requires not empty.
Definition at line 793 of file Sequence.inl.
| void Stroika::Foundation::Containers::Sequence< T >::clear | ( | ) |
Definition at line 803 of file Sequence.inl.
| void Stroika::Foundation::Containers::Sequence< T >::insert | ( | const Iterator< value_type > & | i, |
| ArgByValueType< value_type > | item | ||
| ) |
Definition at line 485 of file Sequence.inl.
| void Stroika::Foundation::Containers::Sequence< T >::erase | ( | size_t | 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 832 of file Sequence.inl.
| nonvirtual CONTAINER_OF_T Stroika::Foundation::Traversal::Iterable< T >::As | ( | CONTAINER_OF_T_CONSTRUCTOR_ARGS... | args | ) | const |
Convert Sequence<T> losslessly into a standard supported C++ type - vector<T>, list<T>, ...
| CONTAINER_OF_T Stroika::Foundation::Traversal::Iterable< T >::As | ( | CONTAINER_OF_T_CONSTRUCTOR_ARGS... | args | ) | const |
Convert Sequence<T> losslessly into a standard supported C++ type - vector<T>, list<T>, ...
Definition at line 1432 of file Iterable.inl.