4#ifndef _Stroika_Foundation_Traversal_Range_h_
5#define _Stroika_Foundation_Traversal_Range_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
15#include "Stroika/Foundation/Common/Common.h"
38namespace Stroika::Foundation::Traversal {
44 namespace RangeTraits {
49 template <
typename DIFFERENCE_TYPE,
typename UNSIGNED_DIFFERENCE_TYPE = Common::Un
signedOfIf<DIFFERENCE_TYPE>>
51 using SignedDifferenceType = DIFFERENCE_TYPE;
52 using UnsignedDifferenceType = UNSIGNED_DIFFERENCE_TYPE;
64 template <Openness LOWER_BOUND, Openness UPPER_BOUND>
66 static constexpr Openness kLowerBound{LOWER_BOUND};
67 static constexpr Openness kUpperBound{UPPER_BOUND};
81 : conditional_t<is_floating_point_v<T>, ExplicitOpenness<Openness::eClosed, Openness::eOpen>, ExplicitOpenness<Openness::eClosed, Openness::eClosed>> {
95 template <
typename T, T MIN, T MAX>
97 static constexpr T kLowerBound{MIN};
98 static constexpr T kUpperBound{MAX};
106 template <
typename T>
108 static constexpr T kLowerBound{numeric_limits<T>::lowest ()};
109 static constexpr T kUpperBound{numeric_limits<T>::max ()};
116 template <
typename T,
typename OPENNESS = DefaultOpenness<T>,
typename DIFF_TYPE = DefaultDifferenceTypes<T>>
118 using value_type = T;
119 using SignedDifferenceType =
typename DIFF_TYPE::SignedDifferenceType;
120 using UnsignedDifferenceType =
typename DIFF_TYPE::UnsignedDifferenceType;
122 static constexpr Openness kLowerBoundOpenness{OPENNESS::kLowerBound};
123 static constexpr Openness kUpperBoundOpenness{OPENNESS::kUpperBound};
131 static size_t DifferenceToSizeT (UnsignedDifferenceType s)
135 static size_t DifferenceToSizeT (SignedDifferenceType s)
136 requires (not same_as<UnsignedDifferenceType, SignedDifferenceType>)
148 template <
typename T,
typename OPENNESS = DefaultOpenness<T>,
typename BOUNDS = DefaultBounds<T>,
typename DIFF_TYPE = DefaultDifferenceTypes<T>>
151 using value_type = T;
153 using SignedDifferenceType =
typename inherited::SignedDifferenceType;
154 using UnsignedDifferenceType =
typename inherited::UnsignedDifferenceType;
156 static constexpr T kLowerBound{BOUNDS::kLowerBound};
157 static constexpr T kUpperBound{BOUNDS::kUpperBound};
166 static constexpr value_type
GetNext (value_type i)
167 requires (is_integral_v<T> or is_enum_v<T>);
168 static value_type
GetNext (value_type i)
169 requires (is_floating_point_v<T>);
178 static constexpr value_type
GetPrevious (value_type i)
179 requires (is_integral_v<T> or is_enum_v<T>);
181 requires (is_floating_point_v<T>);
187 template <
typename T>
196 template <
typename T>
197 struct Default_Enum :
Explicit<T, ExplicitOpenness<Openness::eClosed, Openness::eClosed>, ExplicitBounds<T, T::eSTART, T::eLAST>> {};
205 template <
typename T>
220 template <
typename T>
222 : conditional_t<is_enum_v<T>, typename Common::LazyType<Default_Enum, T>::type,
223 conditional_t<is_integral_v<T>, typename Common::LazyType<Default_Integral, T>::type,
224 conditional_t<is_arithmetic_v<T> or true, typename Common::LazyType<Default_Arithmetic, T>::type, void>>> {
229 template <
typename T,
typename RANGE_TYPE>
275 template <
typename T,
typename TRAITS = RangeTraits::Default<T>>
286 using TraitsType = TRAITS;
291 using SignedDifferenceType =
typename TraitsType::SignedDifferenceType;
296 using UnsignedDifferenceType =
typename TraitsType::UnsignedDifferenceType;
316 constexpr explicit Range ();
317 template <
typename T2,
typename TRAITS2>
320 constexpr explicit Range (
const optional<T>& begin,
const optional<T>& end);
322 constexpr explicit Range (
const optional<T>& begin,
const optional<T>& end,
Openness lhsOpen,
Openness rhsOpen);
343 Openness lhsOpen = TRAITS::kLowerBoundOpenness,
Openness rhsOpen = TRAITS::kUpperBoundOpenness);
375 constexpr bool empty ()
const;
381 constexpr explicit operator bool ()
const;
413 constexpr T
Pin (T v)
const;
440 constexpr partial_ordering operator<=> (
const Range& rhs)
const;
453 [[deprecated (
"USE operator<==> - check <=> produces less (vs unordered) ")]]
constexpr optional<bool>
DefinitelyLessThan (
const Range& rhs)
const
455 return (*this <=> rhs) == partial_ordering::less;
475 template <
typename T2,
typename TRAITS2>
519 constexpr Openness GetLowerBoundOpenness ()
const;
530 constexpr Openness GetUpperBoundOpenness ()
const;
537 constexpr Range Offset (SignedDifferenceType o)
const;
580 Openness fBeginOpenness_;
581 Openness fEndOpenness_;
586 template <
typename RANGE_TYPE>
587 concept IRange = derived_from<RANGE_TYPE, Range<typename RANGE_TYPE::value_type, typename RANGE_TYPE::TraitsType>>;
593 template <
typename T,
typename TRAITS>
594 constexpr Range<T, TRAITS> operator+ (
const T& lhs,
const Range<T, TRAITS>& rhs);
595 template <
typename T,
typename TRAITS>
596 constexpr Range<T, TRAITS> operator+ (
const Range<T, TRAITS>& lhs,
const T& rhs);
597 template <
typename T,
typename TRAITS>
598 DisjointRange<T, Range<T, TRAITS>> operator+ (
const Range<T, TRAITS>& lhs,
const Range<T, TRAITS>& rhs);
604 template <
typename T,
typename TRAITS>
605 constexpr Range<T, TRAITS> operator* (
const T& lhs,
const Range<T, TRAITS>& rhs);
606 template <
typename T,
typename TRAITS>
607 constexpr Range<T, TRAITS> operator* (
const Range<T, TRAITS>& lhs,
const T& rhs);
621 template <
typename T,
typename TRAITS>
622 constexpr Range<T, TRAITS> operator^ (
const Range<T, TRAITS>& lhs,
const Range<T, TRAITS>& rhs);
String is like std::u32string, except it is much easier to use, often much more space efficient,...
A DisjointRange is NOT a range, but a collection of non-overlapping (except at the edges) Ranges....
constexpr optional< bool > DefinitelyLessThan(const Range &rhs) const
Compute a less-like notion for Range.
constexpr bool Contains(Common::ArgByValueType< T > r) const
static constexpr Range FullRange()
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).
constexpr Range Extend(Common::ArgByValueType< T > value) const
constexpr bool empty() const
constexpr Range Offset(SignedDifferenceType o) const
T value_type
Range::value_type is the type of the contained elements of the range (say range of integers,...
constexpr T GetUpperBound() const
constexpr Range Intersection(const Range &rhs) const
nonvirtual Characters::String ToString(const function< Characters::String(const T &)> &elt2String=[](const T &x) -> Characters::String { return Characters::ToString(x);}) const
constexpr bool Intersects(const Range< T2, TRAITS2 > &rhs) const
constexpr bool operator==(const Range &rhs) const
constexpr Range Times(T o) const
constexpr T GetLowerBound() const
constexpr Range ReplaceStart(Common::ArgByValueType< T > start) const
Construct a new Range from this, but with the given start.
constexpr Range UnionBounds(const Range &rhs) const
constexpr Range ReplaceEnd(Common::ArgByValueType< T > end) const
Construct a new Range from this, but with the given end.
nonvirtual DisjointRange< T, Range > Union(const Range &rhs) const
constexpr T GetMidpoint() const
constexpr T Pin(T v) const
nonvirtual constexpr Range Closure() const
static constexpr Range ContainedRange(Common::ArgByValueType< T > begin, Common::ArgByValueType< T > end)
constexpr UnsignedDifferenceType GetDistanceSpanned() const
String ToString(T &&t, ARGS... args)
Return a debug-friendly, display version of the argument: not guaranteed parsable or usable except fo...
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
This defines the default openness for a given type T, except for specializaitons. This is used by Exp...
static constexpr value_type GetPrevious(value_type i)
static constexpr value_type GetNext(value_type i)
static constexpr SignedDifferenceType Difference(Common::ArgByValueType< value_type > lhs, Common::ArgByValueType< value_type > rhs)