Stroika Library 3.0d24
 
Loading...
Searching...
No Matches
Collection_Factory.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
7
8namespace Stroika::Foundation::Containers::Factory {
9
10 /*
11 ********************************************************************************
12 ****************************** Collection_Factory<T> ***************************
13 ********************************************************************************
14 */
15 template <typename T>
16 constexpr Collection_Factory<T>::Collection_Factory (const FactoryFunctionType& f)
17 : fFactory_{f}
18 {
19 }
20 template <typename T>
22 : Collection_Factory{AccessDefault_ ()}
23 {
24 }
25 template <typename T>
26 constexpr Collection_Factory<T>::Collection_Factory (const Hints& hints)
27 : fFactory_{nullptr}
28 , fHints_OptimizeForLookupSpeedOverUpdateSpeed{hints.fOptimizeForLookupSpeedOverUpdateSpeed.value_or (true)}
29 {
30 }
31 template <typename T>
33 {
34 return AccessDefault_ ();
35 }
36 template <typename T>
38 {
39 if (this->fFactory_ == nullptr) [[likely]] {
40 if constexpr (totally_ordered<T>) {
41 if (fHints_OptimizeForLookupSpeedOverUpdateSpeed) [[likely]] {
42 /*
43 * The default, and measurement says it is the right one - see the Tests/52 probes
44 * ("Contains () each PRESENT/ABSENT, Collection_Array<...> vs sorted default").
45 * Recorded HERE, rather than in a TODO, so it does not get re-litigated. All
46 * 3.0d24, Windows x86_64 release, 500 elements, versus Collection_Array:
47 * COSTS adding one at a time ~8x more; AddAll () of a contiguous range ~200x
48 * more - every element pays a tree insertion, which batching the
49 * _IRep::Add () span cannot remove
50 * BUYS Contains () ~10x faster on a hit and 23x (int) / 34x (String) faster
51 * on a miss, since Find_equal_to () is overridden to descend the tree
52 * instead of scanning
53 * Net: building 500 elements costs ~21us more, one 500-lookup sweep saves ~130us,
54 * so a single lookup pass repays construction ~6x. Only a Collection that is
55 * essentially never searched wants the array - which is what the hint below is for.
56 */
57 static const auto kDefault_ = Concrete::SortedCollection_stdmultiset<T>{};
58 return kDefault_;
59 }
60 else {
61 /*
62 * Asked for update speed, so give up the O(log n) lookup for the array: AddAll ()
63 * of a contiguous range hands the whole span to Array::Insert (), which reserves
64 * once - measured ~20-30x cheaper per element than the per-element path, and ~200x
65 * cheaper than doing it through the sorted multiset above.
66 *
67 * Before this, the totally_ordered branch ignored the hint entirely, so a caller
68 * asking for update speed was silently given the sorted multiset anyway.
69 */
70 static const auto kDefault_ = Concrete::Collection_Array<T>{};
71 return kDefault_;
72 }
73 }
74 else {
75 if (fHints_OptimizeForLookupSpeedOverUpdateSpeed) [[likely]] {
76 // questionable choice. For smaller sizes, probably faster, due to better locality.
77 // but adds can occasionally be slow (realloc/O(N)) instead of O(1).
78 static const auto kDefault_ = Concrete::Collection_Array<T>{};
79 return kDefault_;
80 }
81 else {
82 // This generally performs well, so long as you don't call 'size'
83 static const auto kDefault_ = Concrete::Collection_LinkedList<T>{};
84 return kDefault_;
85 }
86 }
87 }
88 else {
89 return this->fFactory_ ();
90 }
91 }
92 template <typename T>
93 void Collection_Factory<T>::Register (const optional<Collection_Factory>& f)
94 {
95 AccessDefault_ () = f.has_value () ? *f : Collection_Factory{Hints{}};
96 }
97 template <typename T>
99 {
100 static Collection_Factory sDefault_{Hints{}};
101 return sDefault_;
102 }
103
104}
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
Collection_Array<T> is an Array-based concrete implementation of the Collection<T> container pattern.
Collection_LinkedList<T> is an LinkedList-based concrete implementation of the Collection<T> containe...
SortedCollection_stdmultiset<T> is an stdmultiset-based concrete implementation of the SortedCollecti...
Singleton factory object - Used to create the default backend implementation of a Collection<> contai...
static void Register(const optional< Collection_Factory > &f=nullopt)