Stroika Library 3.0d24
 
Loading...
Searching...
No Matches
DiscreteRange.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
6
7namespace Stroika::Foundation::Traversal {
8
9 /*
10 ********************************************************************************
11 ***************** DiscreteRange<T, TRAITS>::MyIteratorRep_ *********************
12 ********************************************************************************
13 */
14 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
15 struct DiscreteRange<T, TRAITS>::MyIteratorRep_ : Iterator<T>::IRep, public Memory::UseBlockAllocationIfAppropriate<MyIteratorRep_> {
16 using inherited = typename Iterator<T>::IRep;
17 T fCur;
18 T fEnd;
19 bool fAtEnd;
20 MyIteratorRep_ ()
21 : fCur{TRAITS::kLowerBound}
22 , fEnd{TRAITS::kLowerBound}
23 , fAtEnd{true}
24 {
25 }
26 MyIteratorRep_ (T start, T end)
27 : fCur{start}
28 , fEnd{end}
29 , fAtEnd{false}
30 {
31 }
32 bool AtEnd () const override
33 {
34 return fAtEnd;
35 }
36 optional<T> Current () const override
37 {
38 if (fAtEnd) {
39 return nullopt;
40 }
41 else {
42 return fCur;
43 }
44 }
45 virtual optional<T> More () override
46 {
47 Require (not fAtEnd);
48 if (fCur == fEnd) {
49 fAtEnd = true;
50 }
51 else {
52 fCur = TRAITS::GetNext (fCur);
53 }
54 if (not fAtEnd) {
55 return fCur;
56 }
57 return nullopt;
58 }
59 virtual bool Equals ([[maybe_unused]] const typename Iterator<T>::IRep* rhs) const override
60 {
61 RequireNotNull (rhs);
63 return false;
64 }
65 virtual unique_ptr<typename Iterator<T>::IRep> Clone () const override
66 {
67 unique_ptr<MyIteratorRep_> tmp = make_unique<MyIteratorRep_> (fCur, fEnd);
68 tmp->fAtEnd = fAtEnd;
69 return tmp;
70 }
71 };
72
73 /*
74 ********************************************************************************
75 ***************** DiscreteRange<T, TRAITS>::MyIterable_ ************************
76 ********************************************************************************
77 */
78 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
79 struct DiscreteRange<T, TRAITS>::MyIterable_ : Iterable<T> {
80 struct MyRep_ : Iterable<T>::_IRep, public Memory::UseBlockAllocationIfAppropriate<MyRep_> {
81 using inherited = typename Iterable<T>::_IRep;
82 T fStart;
83 T fEnd;
84 bool fForcedEnd;
85 MyRep_ ()
86 : fStart{TRAITS::kLowerBound}
87 , fEnd{TRAITS::kLowerBound}
88 , fForcedEnd{true}
89 {
90 }
91 MyRep_ (T start, T end)
92 : fStart{start}
93 , fEnd{end}
94 , fForcedEnd{false}
95 {
96 }
97 virtual shared_ptr<typename Iterable<T>::_IRep> Clone () const override
98 {
99 return Memory::MakeSharedPtr<MyRep_> (*this);
100 }
101 virtual Iterator<T> MakeIterator () const override
102 {
103 if (fForcedEnd) {
104 return Iterator<T>{make_unique<DiscreteRange::MyIteratorRep_> ()};
105 }
106 else {
107 return Iterator<T>{make_unique<DiscreteRange::MyIteratorRep_> (fStart, fEnd)};
108 }
109 }
110 virtual size_t size () const override
111 {
112 using SignedDifferenceType = typename TRAITS::SignedDifferenceType;
113 if (fForcedEnd) {
114 return TRAITS::DifferenceToSizeT (SignedDifferenceType{0});
115 }
116 else {
117 return TRAITS::DifferenceToSizeT (SignedDifferenceType{1} + DiscreteRange{fStart, fEnd}.GetDistanceSpanned ());
118 }
119 }
120 virtual bool empty () const override
121 {
122 if (fForcedEnd) {
123 return true;
124 }
125 else {
126 return false;
127 //return fStart == fEnd;
128 }
129 }
130 };
131 MyIterable_ ()
132 : Iterable<T>{Memory::MakeSharedPtr<MyRep_> ()}
133 {
134 }
135 MyIterable_ (T start, T end)
136 : Iterable<T>{Memory::MakeSharedPtr<MyRep_> (start, end)}
137 {
138 }
139 };
140
141 /*
142 ********************************************************************************
143 ***************************** DiscreteRange<T> *********************************
144 ********************************************************************************
145 */
146 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
147 constexpr DiscreteRange<T, TRAITS>::DiscreteRange (T begin, T end)
148 : inherited{begin, end}
149 {
150 Require (begin <= end);
151 }
152 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
153 constexpr DiscreteRange<T, TRAITS>::DiscreteRange (const optional<T>& begin, const optional<T>& end)
154 : inherited{begin, end}
155 {
156 }
157 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
158 constexpr DiscreteRange<T, TRAITS>::DiscreteRange (const Range<T, TRAITS>& r)
159 {
160 // Could do more efficiently
161 if (not r.empty ()) {
162 Require (r.GetLowerBoundOpenness () == Openness::eClosed);
163 Require (r.GetUpperBoundOpenness () == Openness::eClosed);
164 *this = DiscreteRange{r.GetLowerBound (), r.GetUpperBound ()};
165 }
166 }
167 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
169 {
170 return DiscreteRange{TRAITS::kLowerBound, TRAITS::kUpperBound};
171 }
172 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
174 {
175 return inherited::Intersection (rhs);
176 }
177 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
179 {
180 return DiscreteRange{inherited::Intersection (rhs)};
181 }
182 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
184 {
185 return inherited::UnionBounds (rhs);
186 }
187 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
189 {
190 auto r = inherited::UnionBounds (rhs);
191 return DiscreteRange{r.GetLowerBound (), r.GetUpperBound ()};
192 }
193 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
194 constexpr typename DiscreteRange<T, TRAITS>::UnsignedDifferenceType DiscreteRange<T, TRAITS>::GetNumberOfContainedPoints () const
195 {
196 if (this->empty ()) {
197 return 0;
198 }
199 else {
200 return this->GetDistanceSpanned () + 1;
201 }
202 }
203 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
204 constexpr auto DiscreteRange<T, TRAITS>::Offset (SignedDifferenceType o) const -> DiscreteRange
205 {
206 Require (not this->empty ());
207 return inherited::Offset (o);
208 }
209 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
211 {
212 return this->empty () ? MyIterable_{} : MyIterable_{this->GetLowerBound (), this->GetUpperBound ()};
213 }
214 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
216 {
217 return Elements ();
218 }
219 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
221 {
222 if (this->empty ()) {
224 }
225 else {
226 return Iterator<T>{make_unique<MyIteratorRep_> (this->GetLowerBound (), this->GetUpperBound ())};
227 }
228 }
229 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
231 {
233 }
234
235 /*
236 ********************************************************************************
237 *********************************** operator^ **********************************
238 ********************************************************************************
239 */
240 template <IDiscreteRangeable T, IDiscreteRangeableTraits<T> TRAITS>
242 {
243 return lhs.Intersection (rhs);
244 }
245
246}
#define AssertNotImplemented()
Definition Assertions.h:402
#define RequireNotNull(p)
Definition Assertions.h:348
bool Equals(const T *lhs, const T *rhs)
strcmp or wsccmp() as appropriate == 0
A DiscreteRange is a Range where the underlying endpoints are integral (discrete, not continuous); th...
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:238
An Iterator<T> is a copyable object which allows traversing the contents of some container.
Definition Iterator.h:253
constexpr T GetLowerBound() const
Definition Range.inl:395