#include <Range.h>
Public Types | |
using | value_type = T |
Range::value_type is the type of the contained elements of the range (say range of integers, value_type=int) | |
Public Member Functions | |
constexpr | Range () |
constexpr Range | ReplaceStart (Common::ArgByValueType< T > start) const |
Construct a new Range from this, but with the given start. | |
constexpr Range | ReplaceEnd (Common::ArgByValueType< T > end) const |
Construct a new Range from this, but with the given end. | |
constexpr bool | empty () const |
constexpr | operator bool () const |
equivalent to not this->empty (); | |
constexpr UnsignedDifferenceType | GetDistanceSpanned () const |
constexpr T | GetMidpoint () const |
constexpr T | Pin (T v) const |
constexpr bool | Contains (Common::ArgByValueType< T > r) const |
nonvirtual constexpr Range | Closure () const |
constexpr bool | operator== (const Range &rhs) const |
constexpr optional< bool > | DefinitelyLessThan (const Range &rhs) const |
Compute a less-like notion for Range. | |
template<typename T2 , typename TRAITS2 > | |
constexpr bool | Intersects (const Range< T2, TRAITS2 > &rhs) const |
constexpr Range | Intersection (const Range &rhs) const |
nonvirtual DisjointRange< T, Range > | Union (const Range &rhs) const |
constexpr Range | UnionBounds (const Range &rhs) const |
constexpr Range | Extend (Common::ArgByValueType< T > value) const |
constexpr T | GetLowerBound () const |
constexpr T | GetUpperBound () const |
constexpr Range | Offset (SignedDifferenceType o) const |
constexpr Range | Times (T o) const |
nonvirtual Characters::String | ToString (const function< Characters::String(const T &)> &elt2String=[](const T &x) -> Characters::String { return Characters::ToString(x);}) const |
Static Public Member Functions | |
static constexpr Range | Ball (Common::ArgByValueType< T > center, Common::ArgByValueType< UnsignedDifferenceType > radius, Openness lhsOpen=TRAITS::kLowerBoundOpenness, Openness rhsOpen=TRAITS::kUpperBoundOpenness) |
returns a range centered around center, with the given radius (and optionally argument openness). | |
static constexpr Range | ContainedRange (Common::ArgByValueType< T > begin, Common::ArgByValueType< T > end) |
static constexpr Range | FullRange () |
A Range<> is analogous to a mathematical range. It's left and and its right sides can be optionally open or closed.
Range<> is an immutable type (once constructed, will never change), except for allowing operator=.
A range always has a lower and upper bound (if not specified in CTOR, its specified by the type traits) so no unbounded ranges).
For a range to contain a single point, min=max, and both sides must be closed (else its a require error)
This Range<> template is similar to Ruby range, and fairly DIFFERENT from the std::range<> template.
This notion of range is NOT THE SAME as std::range, though is similar (obviously from the name).
Somewhat inspired by, and at least influenced by, the definition in http://ruby-doc.org/core-2.0/Range.html However - where Ruby has one type "Range" - we have "Range" and DiscreteRange" - and some ruby Range methods/properties are expressed only in DiscreteRange<>. Also Stroika Range has openness as an optional/configurable feature of both endpoints, whereas in Ruby, the LHS is always closed and its RHS is optionally open. Note - you can do Range<float>, but cannot do DiscreteRange<float> - but can do DiscreteRange<int>. A note about an empty range. All empty ranges (of the same type) are equal to one another. It is illegal to ask for the start or end of an empty range. Empty ranges contain no points. It is illegal to call: Range<int>{1,1, Openness::eOpen, Openness::eOpen} since this would produce an empty range. Range<int>{1,1, Openness::eClosed, Openness::eClosed} != Range<int>{3,3, Openness::eClosed, Openness::eClosed} would be true, since neither is empty and they contain different points (1 vs 3). \note The default OPENNESS for Default varies by TYPE T. Integer and enums are both fully closed by default, and other arithmetic types (floats) are half open [) \note <a href="Design-Overview.md#Comparisons">Comparisons: o Standard Stroika Comparison support (operator==, operator<=>, etc); o Depends on operator==/operator<=> being defined on T
|
explicitconstexpr |
Range{} creates an empty range (note all empty () ranges of the same type are equal to each other).
optional values - if omitted - are replaced with the TRAITS::kLowerBound and TRAITS::kUpperBound values (as well as 'TRAITs' default openness). Constructors with actual numeric values (begin/end) MUST construct non-empty ranges (begin == end ==> both sides closed).
|
constexpr |
|
constexpr |
|
staticconstexpr |
|
staticconstexpr |
|
constexpr |
A Range is considered empty if it contains no points. If GetLowerBound () < GetUpperBound (), then clearly this is non-empty. If created with Range/0() - then the range this is empty.
But if GetLowerBound () == GetUpperBound () - this is a trickier case. With both ends CLOSED - that means the GetLowerBound () value is contained in the range, so that is not empty.
if GetLowerBound () == GetUpperBound (), and both ends open, then there are no points contained.
But if GetLowerBound () == GetUpperBound (), and one one side is open, and the other closed, the one closed point endpoint is in the range, so the range is non-empty.
|
constexpr |
GetUpperBound ()-GetLowerBound (), or distance from GetLowerBound () to end of the range. If this is empty (), then GetDistanceSpanned () will be zero but the GetDistanceSpanned CAN be zero without the range being empty (if both ends are closed).
|
constexpr |
|
constexpr |
Compare v with the upper and lower bounds of this range, and return a value as close as possible to v but in range.
If 'v' is not in range, and this Range is open, GetNext or GetPrevious maybe used to find a value in range.
|
constexpr |
|
constexpr |
|
constexpr |
|
constexpr |
Compute a less-like notion for Range.
There is no clear way to provide an ordering of two ranges (of the same type). The ordering of their left sides, may not agree with the ordering of their right sides, or their midpoints.
But - OFTEN - they CAN be ordered! And that's often a useful concept. So capture that case at least. Just return nullopt if not comparable. Then the caller can decide how to break the 'tie' - with midpoint compare, or left or right edge compares...
|
constexpr |
Returns true iff there are any points shared in common between this range and the rhs range.
|
constexpr |
DisjointRange< T, Range< T, TRAITS > > Stroika::Foundation::Traversal::Range< T, TRAITS >::Union | ( | const Range< T, TRAITS > & | rhs | ) | const |
|
constexpr |
|
constexpr |
|
constexpr |
|
constexpr |
|
constexpr |
|
constexpr |
Characters::String Stroika::Foundation::Traversal::Range< T, TRAITS >::ToString | ( | const function< Characters::String(const T &)> & | elt2String = [] (const T& x) -> Characters::String { return Characters::ToString (x); } | ) | const |
Print a displayable rendition of the given range, using the argument function to format the basic value_type.
if the 'UpperBound' == kUpperBound, its not shown
Similarly for (only) LowerBound == kLowerBound