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 > |
![]() | |
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_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) |
nonvirtual value_type | back () const |
nonvirtual void | clear () |
nonvirtual void | erase (size_t i) |
nonvirtual Sequence & | operator+= (ArgByValueType< value_type > item) |
Alias for Append/AppendAll (). | |
![]() | |
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. | |
![]() | |
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 | |
![]() | |
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. | |
![]() | |
template<same_as< Characters::String > RESULT_T = Characters::String> | |
static const function< RESULT_T(T)> | kDefaultToStringConverter |
![]() | |
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. | |
![]() | |
_SharedByValueRepType | _fRep |
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.
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 187 of file Sequence.h.
using Stroika::Foundation::Containers::Sequence< T >::value_type = typename inherited::value_type |
Definition at line 198 of file 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 204 of file 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 327 of file 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 129 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 499 of file Sequence.inl.
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.
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 209 of file Sequence.inl.
auto Stroika::Foundation::Containers::Sequence< T >::GetAt | ( | size_t | i | ) | const |
Definition at line 237 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. 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.
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 258 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 281 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 313 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 330 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 351 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 358 of file Sequence.inl.
auto Stroika::Foundation::Containers::Sequence< T >::First | ( | ) | const |
Definition at line 403 of file Sequence.inl.
auto Stroika::Foundation::Containers::Sequence< T >::FirstValue | ( | ArgByValueType< value_type > | defaultValue = {} | ) | const |
Definition at line 413 of file Sequence.inl.
auto Stroika::Foundation::Containers::Sequence< T >::Last | ( | ) | const |
Definition at line 418 of file Sequence.inl.
auto Stroika::Foundation::Containers::Sequence< T >::LastValue | ( | ArgByValueType< value_type > | defaultValue = {} | ) | const |
Definition at line 430 of file Sequence.inl.
void Stroika::Foundation::Containers::Sequence< T >::push_back | ( | ArgByValueType< value_type > | item | ) |
auto Stroika::Foundation::Containers::Sequence< T >::back | ( | ) | const |
Read the last element (GetLast()). Requires not empty.
Definition at line 441 of file Sequence.inl.
void Stroika::Foundation::Containers::Sequence< T >::clear | ( | ) |
Definition at line 451 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 480 of file Sequence.inl.