6namespace Stroika::Foundation::Traversal {
13 template <
typename T,
typename RANGE_TYPE>
14 inline DisjointDiscreteRange<T, RANGE_TYPE>::FindHints::FindHints (value_type seedPosition,
bool forwardFirst)
15 : fSeedPosition{seedPosition}
16 , fForwardFirst{forwardFirst}
25 template <
typename T,
typename RANGE_TYPE>
26 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (
const RangeType& from)
30 template <
typename T,
typename RANGE_TYPE>
31 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (
const initializer_list<RangeType>& from)
35 template <
typename T,
typename RANGE_TYPE>
36 template <IIterableOfTo<RANGE_TYPE> RANGES_OF_T>
37 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (RANGES_OF_T&& from)
38 : DisjointDiscreteRange{begin (forward<RANGES_OF_T> (from)), end (forward<RANGES_OF_T> (from))}
41 template <
typename T,
typename RANGE_TYPE>
42 template <IIterableOfTo<T> TS>
43 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (TS&& from)
44 : DisjointDiscreteRange{begin (forward<TS> (from)), end (forward<TS> (from))}
47 template <
typename T,
typename RANGE_TYPE>
48 template <IInputIterator<RANGE_TYPE> ITERATOR_OF_RANGE_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_RANGE_OF_T>> ITERATOR_OF_RANGE_OF_T2>
49 inline DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (ITERATOR_OF_RANGE_OF_T&& start, ITERATOR_OF_RANGE_OF_T2&& end)
50 : inherited{forward<ITERATOR_OF_RANGE_OF_T> (start), forward<ITERATOR_OF_RANGE_OF_T2> (end)}
53 template <
typename T,
typename RANGE_TYPE>
54 template <IInputIterator<T> ITERATOR_OF_T, sentinel_for<remove_cvref_t<ITERATOR_OF_T>> ITERATOR_OF_T2>
55 DisjointDiscreteRange<T, RANGE_TYPE>::DisjointDiscreteRange (ITERATOR_OF_T&& start, ITERATOR_OF_T2&& end)
57 static_assert (is_convertible_v<Common::ExtractValueType_t<ITERATOR_OF_T>, value_type>);
58 Containers::Sequence<RangeType> srs{};
59 Containers::SortedSet<value_type> ss{forward<ITERATOR_OF_T> (start), forward<ITERATOR_OF_T2> (end)};
61 optional<value_type> endAt;
62 for (
const value_type& i : ss) {
63 if (not endAt.has_value ()) {
67 else if (RangeType::TraitsType::GetNext (*endAt) == i) {
71 Assert (startAt <= *endAt);
72 srs.Append (RangeType{startAt, *endAt});
78 Assert (startAt <= *endAt);
79 srs.Append (RangeType{startAt, *endAt});
81 *
this = move (THIS_CLASS_{srs});
83 template <
typename T,
typename RANGE_TYPE>
84 void DisjointDiscreteRange<T, RANGE_TYPE>::Add (
const value_type& elt)
86 Containers::Sequence<RangeType> srs{this->SubRanges ()};
88 for (Iterator<RangeType> i = srs.begin (); i != srs.end (); ++i) {
89 if (i->Contains (elt)) {
92 else if (elt == i->GetLowerBound () - 1) {
93 srs.Update (i, DiscreteRange<value_type>{elt, i->GetUpperBound ()});
95 *
this = move (THIS_CLASS_{srs});
98 else if (elt == i->GetUpperBound () + 1) {
99 srs.Update (i, DiscreteRange<value_type>{i->GetLowerBound (), elt});
101 *
this = move (THIS_CLASS_{srs});
104 else if (elt < i->GetLowerBound ()) {
110 srs.push_back (DiscreteRange<value_type>{elt, elt});
111 *
this = move (THIS_CLASS_{srs});
113 template <
typename T,
typename RANGE_TYPE>
114 auto DisjointDiscreteRange<T, RANGE_TYPE>::Intersection (
const RangeType& rhs)
const -> DisjointDiscreteRange
117 return DisjointDiscreteRange{inherited::Intersection (rhs).SubRanges ()};
119 template <
typename T,
typename RANGE_TYPE>
120 auto DisjointDiscreteRange<T, RANGE_TYPE>::Intersection (
const DisjointDiscreteRange& rhs)
const -> DisjointDiscreteRange
123 return DisjointDiscreteRange{inherited::Intersection (rhs).SubRanges ()};
125 template <
typename T,
typename RANGE_TYPE>
126 auto DisjointDiscreteRange<T, RANGE_TYPE>::GetNext (value_type elt)
const -> optional<value_type>
128 Containers::Sequence<RangeType> subRanges{this->SubRanges ()};
130 value_type next = RANGE_TYPE::TraitsType::GetNext (elt);
131 Iterator<RangeType> i{subRanges.Find ([next] (
const RangeType& r) ->
bool {
return r.GetUpperBound () >= next; })};
133 return max (next, i->GetLowerBound ());
137 template <
typename T,
typename RANGE_TYPE>
138 auto DisjointDiscreteRange<T, RANGE_TYPE>::GetPrevious (value_type elt)
const -> optional<value_type>
140 Containers::Sequence<RangeType> subRanges{this->SubRanges ()};
142 value_type prev = RANGE_TYPE::TraitsType::GetPrevious (elt);
143 Iterator<RangeType> i{subRanges.Find ([prev] (
const RangeType& r) ->
bool {
return r.GetUpperBound () >= prev; })};
145 if (i->Contains (prev)) {
151 auto prevOfIterator = [&subRanges] (
const Iterator<RangeType>& pOfI) -> Iterator<RangeType> {
152 Iterator<RangeType> result = Iterator<RangeType>::GetEmptyIterator ();
153 for (Iterator<RangeType> i = subRanges.begin (); i != subRanges.end (); ++i) {
163 i = prevOfIterator (subRanges.Find ([prev] (
const RangeType& r) ->
bool { return r.GetUpperBound () > prev; }));
165 Ensure (i->GetUpperBound () < prev);
166 return i->GetUpperBound ();
170 template <
typename T,
typename RANGE_TYPE>
173 using UnsignedDifferenceType =
typename RANGE_TYPE::UnsignedDifferenceType;
177 size_t fSubRangeIdx{};
178 UnsignedDifferenceType fCurrentSubRangeIteratorAt{};
179 context_ () =
delete;
184 context_ (
const context_& from) =
default;
186 auto myContext = make_shared<context_> (context_{subRanges});
187 auto getNext = [myContext] () -> optional<value_type> {
188 if (myContext->fSubRangeIdx < myContext->fSubRanges.size ()) {
189 RangeType curRange{myContext->fSubRanges[myContext->fSubRangeIdx]};
190 UnsignedDifferenceType nEltsPerRange{curRange.GetDistanceSpanned ()};
191 Assert (myContext->fCurrentSubRangeIteratorAt <= nEltsPerRange);
192 value_type result = curRange.GetLowerBound () + myContext->fCurrentSubRangeIteratorAt;
193 if (myContext->fCurrentSubRangeIteratorAt == nEltsPerRange) {
194 ++myContext->fSubRangeIdx;
195 myContext->fCurrentSubRangeIteratorAt = 0;
198 ++myContext->fCurrentSubRangeIteratorAt;
204 return Traversal::CreateGenerator<value_type> (getNext);
206 template <
typename T,
typename RANGE_TYPE>
209 return this->empty () ? optional<value_type>{} : Find (that,
FindHints (this->GetBounds ().GetLowerBound (),
true));
211 template <
typename T,
typename RANGE_TYPE>
214 Require (this->Contains (hints.fSeedPosition));
215 optional<value_type> o = ScanFindAny_ (that, hints.fSeedPosition, hints.fForwardFirst);
218 value_type firstTrueFor{*o};
219 value_type i{firstTrueFor};
222 optional<value_type> o = GetPrevious (i);
236 template <
typename T,
typename RANGE_TYPE>
239 return this->empty () ? optional<value_type>{} : FindLastThat (testF,
FindHints (this->GetBounds ().GetUpperBound (),
false));
241 template <
typename T,
typename RANGE_TYPE>
243 -> optional<value_type>
245 Require (this->Contains (hints.fSeedPosition));
246 optional<value_type> o = ScanFindAny_ (testF, hints.fSeedPosition, hints.fForwardFirst);
249 value_type lastTrueFor{*o};
250 value_type i{lastTrueFor};
253 optional<value_type> o = GetNext (i);
267 template <
typename T,
typename RANGE_TYPE>
268 auto DisjointDiscreteRange<T, RANGE_TYPE>::ScanTil_ (
const function<
bool (value_type)>& testF,
269 const function<optional<value_type> (value_type)>& iterNext, value_type seedPosition)
const
270 -> optional<value_type>
272 value_type i{seedPosition};
273 while (not testF (i)) {
274 optional<value_type> o = iterNext (i);
285 template <
typename T,
typename RANGE_TYPE>
286 auto DisjointDiscreteRange<T, RANGE_TYPE>::ScanFindAny_ (
const function<
bool (value_type)>& testF, value_type seedPosition,
bool forwardFirst)
const
287 -> optional<value_type>
295 function<optional<value_type> (value_type)> backwardNext = [
this] (value_type i) {
return GetPrevious (i); };
296 function<optional<value_type> (value_type)> forwardNext = [
this] (value_type i) {
return GetNext (i); };
297 value_type i{seedPosition};
298 optional<value_type> o{ScanTil_ (testF, forwardFirst ? forwardNext : backwardNext, i)};
305 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.