7namespace Stroika::Foundation::Traversal {
14 template <
typename T,
typename RANGE_TYPE>
15 inline DisjointDiscreteRange<T, RANGE_TYPE>::FindHints::FindHints (value_type seedPosition,
bool forwardFirst)
16 : fSeedPosition{seedPosition}
17 , fForwardFirst{forwardFirst}
26 template <
typename T,
typename RANGE_TYPE>
27 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (
const RangeType& from)
31 template <
typename T,
typename RANGE_TYPE>
32 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (
const initializer_list<RangeType>& from)
36 template <
typename T,
typename RANGE_TYPE>
37 template <IIterableOfTo<RANGE_TYPE> RANGES_OF_T>
38 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (RANGES_OF_T&& from)
39 : DisjointDiscreteRange{begin (forward<RANGES_OF_T> (from)), end (forward<RANGES_OF_T> (from))}
42 template <
typename T,
typename RANGE_TYPE>
43 template <IIterableOfTo<T> TS>
44 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (TS&& from)
45 : DisjointDiscreteRange{begin (forward<TS> (from)), end (forward<TS> (from))}
48 template <
typename T,
typename RANGE_TYPE>
49 template <IInputIterator<RANGE_TYPE> ITERATOR_OF_RANGE_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_RANGE_OF_T>> ITERATOR_OF_RANGE_OF_T2>
50 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (ITERATOR_OF_RANGE_OF_T&& start, ITERATOR_OF_RANGE_OF_T2&& end)
51 : inherited{forward<ITERATOR_OF_RANGE_OF_T> (start), forward<ITERATOR_OF_RANGE_OF_T2> (end)}
54 template <
typename T,
typename RANGE_TYPE>
55 template <IInputIterator<T> ITERATOR_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_T>> ITERATOR_OF_T2>
56 DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (ITERATOR_OF_T&& start, ITERATOR_OF_T2&& end)
58 static_assert (is_convertible_v<Common::ExtractValueType_t<ITERATOR_OF_T>, value_type>);
59 Containers::Sequence<RangeType> srs{};
60 Containers::SortedSet<value_type> ss{forward<ITERATOR_OF_T> (start), forward<ITERATOR_OF_T2> (end)};
62 optional<value_type> endAt;
63 for (
const value_type& i : ss) {
64 if (not endAt.has_value ()) {
68 else if (RangeType::TraitsType::GetNext (*endAt) == i) {
72 Assert (startAt <= *endAt);
73 srs.Append (RangeType{startAt, *endAt});
79 Assert (startAt <= *endAt);
80 srs.Append (RangeType{startAt, *endAt});
82 *
this = move (THIS_CLASS_{srs});
84 template <
typename T,
typename RANGE_TYPE>
85 void DisjointDiscreteRange<T, RANGE_TYPE>::Add (
const value_type& elt)
87 Containers::Sequence<RangeType> srs{this->SubRanges ()};
89 for (Iterator<RangeType> i = srs.begin (); i != srs.end (); ++i) {
90 if (i->Contains (elt)) {
93 else if (elt == i->GetLowerBound () - 1) {
94 srs.Update (i, DiscreteRange<value_type>{elt, i->GetUpperBound ()});
96 *
this = move (THIS_CLASS_{srs});
99 else if (elt == i->GetUpperBound () + 1) {
100 srs.Update (i, DiscreteRange<value_type>{i->GetLowerBound (), elt});
102 *
this = move (THIS_CLASS_{srs});
105 else if (elt < i->GetLowerBound ()) {
111 srs.push_back (DiscreteRange<value_type>{elt, elt});
112 *
this = move (THIS_CLASS_{srs});
114 template <
typename T,
typename RANGE_TYPE>
115 auto DisjointDiscreteRange<T, RANGE_TYPE>::Intersection (
const RangeType& rhs)
const -> DisjointDiscreteRange
118 return DisjointDiscreteRange{inherited::Intersection (rhs).SubRanges ()};
120 template <
typename T,
typename RANGE_TYPE>
121 auto DisjointDiscreteRange<T, RANGE_TYPE>::Intersection (
const DisjointDiscreteRange& rhs)
const -> DisjointDiscreteRange
124 return DisjointDiscreteRange{inherited::Intersection (rhs).SubRanges ()};
126 template <
typename T,
typename RANGE_TYPE>
127 auto DisjointDiscreteRange<T, RANGE_TYPE>::GetNext (value_type elt)
const -> optional<value_type>
129 Containers::Sequence<RangeType> subRanges{this->SubRanges ()};
131 value_type next = RANGE_TYPE::TraitsType::GetNext (elt);
132 Iterator<RangeType> i{subRanges.Find ([next] (
const RangeType& r) ->
bool {
return r.GetUpperBound () >= next; })};
134 return max (next, i->GetLowerBound ());
138 template <
typename T,
typename RANGE_TYPE>
139 auto DisjointDiscreteRange<T, RANGE_TYPE>::GetPrevious (value_type elt)
const -> optional<value_type>
141 Containers::Sequence<RangeType> subRanges{this->SubRanges ()};
143 value_type prev = RANGE_TYPE::TraitsType::GetPrevious (elt);
144 Iterator<RangeType> i{subRanges.Find ([prev] (
const RangeType& r) ->
bool {
return r.GetUpperBound () >= prev; })};
146 if (i->Contains (prev)) {
152 auto prevOfIterator = [&subRanges] (
const Iterator<RangeType>& pOfI) -> Iterator<RangeType> {
153 Iterator<RangeType> result = Iterator<RangeType>::GetEmptyIterator ();
154 for (Iterator<RangeType> i = subRanges.begin (); i != subRanges.end (); ++i) {
164 i = prevOfIterator (subRanges.Find ([prev] (
const RangeType& r) ->
bool { return r.GetUpperBound () > prev; }));
166 Ensure (i->GetUpperBound () < prev);
167 return i->GetUpperBound ();
171 template <
typename T,
typename RANGE_TYPE>
174 using UnsignedDifferenceType =
typename RANGE_TYPE::UnsignedDifferenceType;
178 size_t fSubRangeIdx{};
179 UnsignedDifferenceType fCurrentSubRangeIteratorAt{};
180 context_ () =
delete;
185 context_ (
const context_& from) =
default;
187 auto myContext = Memory::MakeSharedPtr<context_> (context_{subRanges});
188 auto getNext = [myContext] () -> optional<value_type> {
189 if (myContext->fSubRangeIdx < myContext->fSubRanges.size ()) {
190 RangeType curRange{myContext->fSubRanges[myContext->fSubRangeIdx]};
191 UnsignedDifferenceType nEltsPerRange{curRange.GetDistanceSpanned ()};
192 Assert (myContext->fCurrentSubRangeIteratorAt <= nEltsPerRange);
193 value_type result = curRange.GetLowerBound () + myContext->fCurrentSubRangeIteratorAt;
194 if (myContext->fCurrentSubRangeIteratorAt == nEltsPerRange) {
195 ++myContext->fSubRangeIdx;
196 myContext->fCurrentSubRangeIteratorAt = 0;
199 ++myContext->fCurrentSubRangeIteratorAt;
205 return Traversal::CreateGenerator<value_type> (getNext);
207 template <
typename T,
typename RANGE_TYPE>
210 return this->empty () ? optional<value_type>{} : Find (that,
FindHints (this->GetBounds ().GetLowerBound (),
true));
212 template <
typename T,
typename RANGE_TYPE>
215 Require (this->Contains (hints.fSeedPosition));
216 optional<value_type> o = ScanFindAny_ (that, hints.fSeedPosition, hints.fForwardFirst);
219 value_type firstTrueFor{*o};
220 value_type i{firstTrueFor};
223 optional<value_type> o = GetPrevious (i);
237 template <
typename T,
typename RANGE_TYPE>
240 return this->empty () ? optional<value_type>{} : FindLastThat (testF,
FindHints (this->GetBounds ().GetUpperBound (),
false));
242 template <
typename T,
typename RANGE_TYPE>
244 -> optional<value_type>
246 Require (this->Contains (hints.fSeedPosition));
247 optional<value_type> o = ScanFindAny_ (testF, hints.fSeedPosition, hints.fForwardFirst);
250 value_type lastTrueFor{*o};
251 value_type i{lastTrueFor};
254 optional<value_type> o = GetNext (i);
268 template <
typename T,
typename RANGE_TYPE>
269 auto DisjointDiscreteRange<T, RANGE_TYPE>::ScanTil_ (
const function<
bool (value_type)>& testF,
270 const function<optional<value_type> (value_type)>& iterNext, value_type seedPosition)
const
271 -> optional<value_type>
273 value_type i{seedPosition};
274 while (not testF (i)) {
275 optional<value_type> o = iterNext (i);
286 template <
typename T,
typename RANGE_TYPE>
287 auto DisjointDiscreteRange<T, RANGE_TYPE>::ScanFindAny_ (
const function<
bool (value_type)>& testF, value_type seedPosition,
bool forwardFirst)
const
288 -> optional<value_type>
296 function<optional<value_type> (value_type)> backwardNext = [
this] (value_type i) {
return GetPrevious (i); };
297 function<optional<value_type> (value_type)> forwardNext = [
this] (value_type i) {
return GetNext (i); };
298 value_type i{seedPosition};
299 optional<value_type> o{ScanTil_ (testF, forwardFirst ? forwardNext : backwardNext, i)};
306 o = ScanTil_ (testF, forwardFirst ? backwardNext : forwardNext, i);
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.