Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
DiscreteRange.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Traversal_DiscreteRange_h_
5#define _Stroika_Foundation_Traversal_DiscreteRange_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
11
12/**
13 * \file
14 *
15 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
16 *
17 * TODO:
18 * @todo Consider if clearer having DiscreteRange aggregate Elements() instead of inheriting from
19 * Iterable. Would make construction, and coipying etc cheaper (esp when that feature
20 * is not used).
21
22
23 >>>> DOCUMENT WHY DsicreateRange<> no longer Iterabkle<?>
24 >>> avoids conflict on empty, and provides clearer 'getlength'.
25 >>> avoids shared_ptr stuff (REP) for iterablke unles/until used.
26 >>> this should allow constexpr discrete_rage!!!
27 >>> and see other comments on why - in progress switchover...
28 >>> (NOTE - downside is
29 - for (auto i : DiscreteRange<Color> (optional<Color> (), optional<Color> ())) {
30 + for (auto i : DiscreteRange<Color> (optional<Color> (), optional<Color> ()).Elements ()) {
31
32
33 *
34 * @todo Understand what you must do DiscreteRange<int> (1,10) instead of just DiscreteRange (1,10),
35 * and if something reasonable to be done about it - do so (compiler bug or ambiguity due to optional)
36 * or just that template inference of types doesn't work as well as I thought...
37 *
38 * @todo Try to rewrite using Generator<> code... See if that simplifies things...
39 */
40
41namespace Stroika::Foundation::Traversal {
42
43 /**
44 * \brief A DiscreteRange is a Range where the underlying endpoints are integral (discrete, not continuous);
45 * this implies you can iterate over the members of the range, and its endpoints are closed.
46 *
47 * DiscreteRange<> is an immutable type (once constructed, will never change), except for allowing operator=..
48 *
49 * \par Example Usage
50 * \code
51 * vector<int> v = DiscreteRange<int>{1,10}.Elements ().As<vector<int>> ();
52 * // equiv to vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
53 * \endcode
54 *
55 * \par OR
56 * \code
57 * for (auto i : DiscreteRange<int>{1,10}) {
58 * ...i = 1..10
59 * }
60 * \endcode
61 *
62 * \par OR
63 * \code
64 * enum class Color { red, blue, green, Stroika_Define_Enum_Bounds (red, green) };
65 * for (auto i : DiscreteRange<Color>::FullRange ().Elements ()) {
66 * // iterate over each color - red, green, blue
67 * }
68 * \endcode
69 *
70 * \note Since the default traits for an enum with Stroika type annotation (Stroika_Define_Enum_Bounds)
71 * provides the start/end, DiscreteRange<SOME_ENUM>::FullRange ().Elements () returns an
72 * iterable with all possible legal values of the enum.
73 */
74 template <typename T, typename TRAITS = RangeTraits::Default<T>>
75 class DiscreteRange : public Range<T, TRAITS> {
76 public:
77 static_assert (TRAITS::kLowerBoundOpenness == Openness::eClosed);
78 static_assert (TRAITS::kUpperBoundOpenness == Openness::eClosed);
79
80 private:
82
83 public:
84 /**
85 */
86 using value_type = typename inherited::value_type;
87
88 public:
89 /**
90 */
91 using SignedDifferenceType = typename inherited::SignedDifferenceType;
92
93 public:
94 /**
95 */
96 using UnsignedDifferenceType = typename inherited::UnsignedDifferenceType;
97
98 private:
99 struct MyIteratorRep_;
100
101 public:
102 /**
103 * DiscreteRange () with no arguments produces an empty sequence.
104 *
105 * \pre begin <= end (after substitution of optional values)
106 * \pre src range must be eClosed on both sides
107 */
108 explicit constexpr DiscreteRange () = default;
109 explicit constexpr DiscreteRange (T begin, T end);
110 explicit constexpr DiscreteRange (const optional<T>& begin, const optional<T>& end);
111 explicit constexpr DiscreteRange (const Range<T, TRAITS>& r);
112
113 public:
114 /**
115 * Like Range<>::FullRange () but returning a DiscreteRange<> type.
116 */
117 static constexpr DiscreteRange FullRange ();
118
119 public:
120 /**
121 * Like Range<>::Intersection (), but returning a DiscreteRange<> type.
122 */
123 constexpr Range<T, TRAITS> Intersection (const Range<T, TRAITS>& rhs) const;
124 constexpr DiscreteRange Intersection (const DiscreteRange& rhs) const;
125
126 public:
127 /**
128 * Like Range<>::UnionBounds (), but returning a DiscreteRange<> type.
129 */
130 constexpr Range<T, TRAITS> UnionBounds (const Range<T, TRAITS>& rhs) const;
131 constexpr DiscreteRange UnionBounds (const DiscreteRange& rhs) const;
132
133 public:
134 /**
135 * This returns the number of points from lower bound to upper bound inclusive.
136 * This equals GetDistanceSpanned () + 1 (roughly).
137 * If (empty ()) .... this returns 0;
138 */
139 constexpr UnsignedDifferenceType GetNumberOfContainedPoints () const;
140
141 public:
142 /**
143 * \pre not empty
144 * \pre the DiscreteRange produced by applying the given offset to *this remains valid with respect to the constraints on this DiscreteRange.
145 */
146 constexpr DiscreteRange Offset (SignedDifferenceType o) const;
147
148 public:
149 /**
150 * \par Example Usage
151 * \code
152 * DisjointDiscreteRange<DiscreteRange<int>> t;
153 * for (T i : t.Elements ()) {
154 * }
155 * \endcode
156 *
157 * Elements () makes no guarantees about whether or not modifications to the underlying DisjointDiscreteRange<> will
158 * appear in the Elements() Iterable<T>.
159 *
160 * \note Elements produces a generator, not an actual list of each item (internally). This should not be visible externally,
161 * except in how much memory or time is required to create an Elements() iterable for a large range (should be cheap).
162 */
163 nonvirtual Iterable<T> Elements () const;
164
165 public:
166 /**
167 * @aliases Elements ()
168 */
169 nonvirtual operator Iterable<T> () const;
170
171 public:
172 /**
173 * \see Elements () - this produces a generator iterator, so should be quite cheap even for a large range.
174 */
175 nonvirtual Iterator<T> begin () const;
176
177 public:
178 /**
179 */
180 nonvirtual Iterator<T> end () const;
181
182 private:
183 struct MyIterable_;
184 };
185
186 /**
187 * Intersection ()
188 */
189 template <typename T, typename TRAITS>
191
192}
193
194/*
195 ********************************************************************************
196 ******************************* Implementation Details *************************
197 ********************************************************************************
198 */
199#include "DiscreteRange.inl"
200
201#endif /*_Stroika_Foundation_Traversal_DiscreteRange_h_ */
A DiscreteRange is a Range where the underlying endpoints are integral (discrete, not continuous); th...
constexpr Range< T, TRAITS > Intersection(const Range< T, TRAITS > &rhs) const
nonvirtual Iterator< T > begin() const
nonvirtual Iterable< T > Elements() const
constexpr Range< T, TRAITS > UnionBounds(const Range< T, TRAITS > &rhs) const
constexpr UnsignedDifferenceType GetNumberOfContainedPoints() const
static constexpr DiscreteRange FullRange()
constexpr DiscreteRange Offset(SignedDifferenceType o) const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
An Iterator<T> is a copyable object which allows traversing the contents of some container....
Definition Iterator.h:225
T value_type
Range::value_type is the type of the contained elements of the range (say range of integers,...
Definition Range.h:281