UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Range.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "Containers/Array.h"
8#include "Misc/DateTime.h"
9#include "Math/RangeBound.h"
10#include "Misc/FrameNumber.h"
12
13
49template<typename ElementType> class TRange
50{
51public:
52
54
55 /*~ Typedef used to pass/return small element types by value rather than const& */
57
59 [[nodiscard]] TRange() { }
60
69 : LowerBound(BoundsType::Inclusive(A))
70 , UpperBound(BoundsType::Inclusive(A))
71 { }
72
82 : LowerBound(BoundsType::Inclusive(A))
83 , UpperBound(BoundsType::Exclusive(B))
84 { }
85
93 : LowerBound(InLowerBound)
94 , UpperBound(InUpperBound)
95 { }
96
97public:
98
105 [[nodiscard]] bool operator==(const TRange& Other) const
106 {
107 if (IsEmpty() && Other.IsEmpty())
108 {
109 return true;
110 }
111
112 return ((LowerBound == Other.LowerBound) && (UpperBound == Other.UpperBound));
113 }
114
121 [[nodiscard]] bool operator!=(const TRange& Other) const
122 {
123 if (IsEmpty() && Other.IsEmpty())
124 {
125 return false;
126 }
127
128 return ((LowerBound != Other.LowerBound) || (UpperBound != Other.UpperBound));
129 }
130
131public:
132
143 [[nodiscard]] bool Adjoins(const TRange& Other) const
144 {
145 if (IsEmpty() || Other.IsEmpty())
146 {
147 return false;
148 }
149
150 if (!UpperBound.IsOpen() && !Other.LowerBound.IsOpen() && UpperBound.GetValue() == Other.LowerBound.GetValue())
151 {
152 return ((UpperBound.IsInclusive() && Other.LowerBound.IsExclusive()) ||
153 (UpperBound.IsExclusive() && Other.LowerBound.IsInclusive()));
154 }
155
156 if (!Other.UpperBound.IsOpen() && !LowerBound.IsOpen() && Other.UpperBound.GetValue() == LowerBound.GetValue())
157 {
158 return ((Other.UpperBound.IsInclusive() && LowerBound.IsExclusive()) ||
159 (Other.UpperBound.IsExclusive() && LowerBound.IsInclusive()));
160 }
161
162 return false;
163 }
164
175 [[nodiscard]] bool Conjoins(const TRange& X, const TRange& Y) const
176 {
177 if (X.Overlaps(Y))
178 {
179 return false;
180 }
181
182 return (Adjoins(X) && Adjoins(Y));
183 }
184
192 {
193 return ((BoundsType::MinLower(LowerBound, Element) == LowerBound) &&
194 (BoundsType::MaxUpper(UpperBound, Element) == UpperBound));
195 }
196
203 [[nodiscard]] bool Contains(const TRange& Other) const
204 {
205 return ((BoundsType::MinLower(LowerBound, Other.LowerBound) == LowerBound) &&
206 (BoundsType::MaxUpper(UpperBound, Other.UpperBound) == UpperBound));
207 }
208
217 [[nodiscard]] bool Contiguous(const TRange& Other) const
218 {
219 return (Overlaps(Other) || Adjoins(Other));
220 }
221
229 {
230 return LowerBound;
231 }
232
240 {
241 LowerBound = NewLowerBound;
242 }
243
254
264 {
265 return LowerBound.GetValue();
266 }
267
275 {
276 return UpperBound;
277 }
278
286 {
287 UpperBound = NewUpperBound;
288 }
289
300
310 {
311 return UpperBound.GetValue();
312 }
313
320 [[nodiscard]] bool HasLowerBound() const
321 {
322 return LowerBound.IsClosed();
323 }
324
331 [[nodiscard]] bool HasUpperBound() const
332 {
333 return UpperBound.IsClosed();
334 }
335
345 [[nodiscard]] bool IsDegenerate() const
346 {
347 return (LowerBound.IsInclusive() && (LowerBound == UpperBound));
348 }
349
361 [[nodiscard]] bool IsEmpty() const
362 {
363 if (LowerBound.IsClosed() && UpperBound.IsClosed())
364 {
365 if (LowerBound.GetValue() > UpperBound.GetValue())
366 {
367 return true;
368 }
369
370 return ((LowerBound.GetValue() == UpperBound.GetValue()) && (LowerBound.IsExclusive() || UpperBound.IsExclusive()));
371 }
372
373 return false;
374 }
375
382 [[nodiscard]] bool Overlaps(const TRange& Other) const
383 {
384 if (IsEmpty() || Other.IsEmpty())
385 {
386 return false;
387 }
388
389 bool bUpperOpen = UpperBound.IsOpen() || Other.LowerBound.IsOpen();
390 bool bLowerOpen = LowerBound.IsOpen() || Other.UpperBound.IsOpen();
391
392 // true in the case that the bounds are open (default)
393 bool bUpperValid = true;
394 bool bLowerValid = true;
395
396 if (!bUpperOpen)
397 {
398 bool bUpperGreaterThan = UpperBound.GetValue() > Other.LowerBound.GetValue();
399 bool bUpperGreaterThanOrEqualTo = UpperBound.GetValue() >= Other.LowerBound.GetValue();
400 bool bUpperBothInclusive = UpperBound.IsInclusive() && Other.LowerBound.IsInclusive();
401
403 }
404
405 if (!bLowerOpen)
406 {
407 bool bLowerLessThan = LowerBound.GetValue() < Other.UpperBound.GetValue();
408 bool bLowerLessThanOrEqualTo = LowerBound.GetValue() <= Other.UpperBound.GetValue();
409 bool bLowerBothInclusive = LowerBound.IsInclusive() && Other.UpperBound.IsInclusive();
410
412 }
413
414 return bUpperValid && bLowerValid;
415 }
416
426 template<typename DifferenceType>
428 {
429 check(LowerBound.IsClosed() && UpperBound.IsClosed());
430
431 return (UpperBound.GetValue() - LowerBound.GetValue());
432 }
433
443 {
444 TArray<TRange> Result;
445
446 if (Contains(Element))
447 {
448 Result.Add(TRange(LowerBound, BoundsType::Exclusive(Element)));
449 Result.Add(TRange(BoundsType::Inclusive(Element), UpperBound));
450 }
451 else
452 {
453 Result.Add(*this);
454 }
455
456 return Result;
457 }
458
459public:
460
469 [[nodiscard]] static inline TArray<TRange> Difference(const TRange& X, const TRange& Y)
470 {
471 TArray<TRange> Result;
472
473 if (X.Overlaps(Y))
474 {
475 TRange LowerRange = TRange(X.LowerBound, BoundsType::FlipInclusion(Y.LowerBound));
476 TRange UpperRange = TRange(BoundsType::FlipInclusion(Y.UpperBound), X.UpperBound);
477
478 if (!LowerRange.IsEmpty())
479 {
480 Result.Add(LowerRange);
481 }
482
483 if (!UpperRange.IsEmpty())
484 {
485 Result.Add(UpperRange);
486 }
487 }
488 else
489 {
490 Result.Add(X);
491 }
492
493 return Result;
494 }
495
506 [[nodiscard]] static inline TRange Hull(const TRange& X, const TRange& Y)
507 {
508 if (X.IsEmpty())
509 {
510 return Y;
511 }
512
513 if (Y.IsEmpty())
514 {
515 return X;
516 }
517
518 return TRange(BoundsType::MinLower(X.LowerBound, Y.LowerBound), BoundsType::MaxUpper(X.UpperBound, Y.UpperBound));
519 }
520
528 [[nodiscard]] static inline TRange Hull(const TArray<TRange>& Ranges)
529 {
530 if (Ranges.Num() == 0)
531 {
532 return TRange::Empty();
533 }
534
535 TRange Bounds = Ranges[0];
536
537 for (int32 i = 1; i < Ranges.Num(); ++i)
538 {
539 Bounds = Hull(Bounds, Ranges[i]);
540 }
541
542 return Bounds;
543 }
544
555 [[nodiscard]] static inline TRange Intersection(const TRange& X, const TRange& Y)
556 {
557 if (X.IsEmpty())
558 {
559 return TRange::Empty();
560 }
561
562 if (Y.IsEmpty())
563 {
564 return TRange::Empty();
565 }
566
567 return TRange(BoundsType::MaxLower(X.LowerBound, Y.LowerBound), BoundsType::MinUpper(X.UpperBound, Y.UpperBound));
568 }
569
577 [[nodiscard]] static inline TRange Intersection(const TArray<TRange>& Ranges)
578 {
579 if (Ranges.Num() == 0)
580 {
581 return TRange::Empty();
582 }
583
584 TRange Bounds = Ranges[0];
585
586 for (int32 i = 1; i < Ranges.Num(); ++i)
587 {
588 Bounds = Intersection(Bounds, Ranges[i]);
589 }
590
591 return Bounds;
592 }
593
604 [[nodiscard]] static inline TArray<TRange> Union(const TRange& X, const TRange& Y)
605 {
607
608 if (X.Contiguous(Y))
609 {
610 OutRanges.Add(TRange(BoundsType::MinLower(X.LowerBound, Y.LowerBound), BoundsType::MaxUpper(X.UpperBound, Y.UpperBound)));
611 }
612 else
613 {
614 if (!X.IsEmpty())
615 {
616 OutRanges.Add(X);
617 }
618
619 if (!Y.IsEmpty())
620 {
621 OutRanges.Add(Y);
622 }
623 }
624
625 return OutRanges;
626 }
627
628public:
629
640
652
664
672 {
673 return TRange(BoundsType::Exclusive(ElementType()), BoundsType::Exclusive(ElementType()));
674 }
675
688
700
713
725
726public:
727
735 friend class FArchive& operator<<(class FArchive& Ar, TRange& Range)
736 {
737 return Ar << Range.LowerBound << Range.UpperBound;
738 }
739
746 friend uint32 GetTypeHash(const TRange& Range)
747 {
748 return (GetTypeHash(Range.LowerBound) + 23 * GetTypeHash(Range.UpperBound));
749 }
750
751private:
752
754 BoundsType LowerBound;
755
757 BoundsType UpperBound;
758};
759
760
761/* Default ranges for built-in types
762 *****************************************************************************/
763
764#define DEFINE_RANGE_WRAPPER_STRUCT(Name, ElementType) \
765 struct Name : TRange<ElementType> \
766 { \
767 private: \
768 typedef TRange<ElementType> Super; \
769 \
770 public: \
771 Name() \
772 : Super() \
773 { \
774 } \
775 \
776 Name(const Super& Rhs) \
777 : Super(Rhs) \
778 { \
779 } \
780 \
781 explicit Name(ElementValueOrConstRef A) \
782 : Super(A) \
783 { \
784 } \
785 \
786 explicit Name(ElementValueOrConstRef A, ElementValueOrConstRef B) \
787 : Super(A, B) \
788 { \
789 } \
790 \
791 explicit Name(const TRangeBound<ElementType>& InLowerBound, const TRangeBound<ElementType>& InUpperBound) \
792 : Super(InLowerBound, InUpperBound) \
793 { \
794 } \
795 \
796 TArray<Name> Split(ElementValueOrConstRef Element) const \
797 { \
798 return TArray<Name>(Super::Split(Element)); \
799 } \
800 \
801 static UE_FORCEINLINE_HINT TArray<Name> Difference(const Name& X, const Name& Y) \
802 { \
803 return TArray<Name>(Super::Difference(X, Y)); \
804 } \
805 \
806 static UE_FORCEINLINE_HINT Name Empty() \
807 { \
808 return Super::Empty(); \
809 } \
810 \
811 static UE_FORCEINLINE_HINT Name Hull(const Name& X, const Name& Y) \
812 { \
813 return Super::Hull(X, Y); \
814 } \
815 \
816 static UE_FORCEINLINE_HINT Name Hull(const TArray<Name>& Ranges) \
817 { \
818 return Super::Hull(reinterpret_cast<const TArray<Super>&>(Ranges)); \
819 } \
820 \
821 static UE_FORCEINLINE_HINT Name Intersection(const Name& X, const Name& Y) \
822 { \
823 return Super::Intersection(X, Y); \
824 } \
825 \
826 static UE_FORCEINLINE_HINT Name Intersection(const TArray<Name>& Ranges) \
827 { \
828 return Super::Intersection(reinterpret_cast<const TArray<Super>&>(Ranges)); \
829 } \
830 \
831 static UE_FORCEINLINE_HINT TArray<Name> Union(const Name& X, const Name& Y) \
832 { \
833 return TArray<Name>(Super::Union(X, Y)); \
834 } \
835 \
836 static UE_FORCEINLINE_HINT Name All() \
837 { \
838 return Super::All(); \
839 } \
840 \
841 static UE_FORCEINLINE_HINT Name AtLeast(ElementValueOrConstRef Value) \
842 { \
843 return Super::AtLeast(Value); \
844 } \
845 \
846 static UE_FORCEINLINE_HINT Name AtMost(ElementValueOrConstRef Value) \
847 { \
848 return Super::AtMost(Value); \
849 } \
850 \
851 static UE_FORCEINLINE_HINT TRange GreaterThan(ElementValueOrConstRef Value) \
852 { \
853 return Super::GreaterThan(Value); \
854 } \
855 \
856 static UE_FORCEINLINE_HINT TRange LessThan(ElementValueOrConstRef Value) \
857 { \
858 return Super::LessThan(Value); \
859 } \
860 }; \
861 \
862 template <> \
863 struct TIsBitwiseConstructible<Name, TRange<ElementType>> \
864 { \
865 enum { Value = true }; \
866 }; \
867 \
868 template <> \
869 struct TIsBitwiseConstructible<TRange<ElementType>, Name> \
870 { \
871 enum { Value = true }; \
872 };
873
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int16 int16
A 16-bit signed integer.
Definition Platform.h:1123
FPlatformTypes::int8 int8
An 8-bit signed integer.
Definition Platform.h:1121
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
#define DEFINE_RANGE_WRAPPER_STRUCT(Name, ElementType)
Definition Range.h:764
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
Definition RangeBound.h:36
ElementValueOrConstRef GetValue() const
Definition RangeBound.h:97
UE_FORCEINLINE_HINT bool IsClosed() const
Definition RangeBound.h:125
static const TRangeBound & MinLower(const TRangeBound &A, const TRangeBound &B)
Definition RangeBound.h:300
UE_FORCEINLINE_HINT bool IsExclusive() const
Definition RangeBound.h:135
static const TRangeBound & MaxUpper(const TRangeBound &A, const TRangeBound &B)
Definition RangeBound.h:282
static TRangeBound Inclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:209
UE_FORCEINLINE_HINT bool IsInclusive() const
Definition RangeBound.h:145
UE_FORCEINLINE_HINT bool IsOpen() const
Definition RangeBound.h:155
static const TRangeBound & MaxLower(const TRangeBound &A, const TRangeBound &B)
Definition RangeBound.h:264
static const TRangeBound & MinUpper(const TRangeBound &A, const TRangeBound &B)
Definition RangeBound.h:318
static TRangeBound FlipInclusion(const TRangeBound &Bound)
Definition RangeBound.h:242
static TRangeBound Open()
Definition RangeBound.h:224
static TRangeBound Exclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:193
void SetValue(ElementValueOrConstRef NewValue)
Definition RangeBound.h:113
Definition Range.h:50
TCallTraits< ElementType >::ParamType ElementValueOrConstRef
Definition Range.h:56
bool Contains(ElementValueOrConstRef Element) const
Definition Range.h:191
TRange()
Definition Range.h:59
bool HasLowerBound() const
Definition Range.h:320
static UE_FORCEINLINE_HINT TRange Inclusive(ElementValueOrConstRef Min, ElementValueOrConstRef Max)
Definition Range.h:709
bool Overlaps(const TRange &Other) const
Definition Range.h:382
TRange(const BoundsType &InLowerBound, const BoundsType &InUpperBound)
Definition Range.h:92
static TArray< TRange > Union(const TRange &X, const TRange &Y)
Definition Range.h:604
static UE_FORCEINLINE_HINT TRange Exclusive(ElementValueOrConstRef Min, ElementValueOrConstRef Max)
Definition Range.h:684
static UE_FORCEINLINE_HINT TRange AtMost(ElementValueOrConstRef Value)
Definition Range.h:660
void SetUpperBoundValue(ElementValueOrConstRef NewUpperBoundValue)
Definition Range.h:296
void SetLowerBoundValue(ElementValueOrConstRef NewLowerBoundValue)
Definition Range.h:250
static TRange Intersection(const TRange &X, const TRange &Y)
Definition Range.h:555
TRangeBound< ElementType > BoundsType
Definition Range.h:53
friend uint32 GetTypeHash(const TRange &Range)
Definition Range.h:746
static TArray< TRange > Difference(const TRange &X, const TRange &Y)
Definition Range.h:469
bool IsEmpty() const
Definition Range.h:361
friend class FArchive & operator<<(class FArchive &Ar, TRange &Range)
Definition Range.h:735
static TRange Intersection(const TArray< TRange > &Ranges)
Definition Range.h:577
bool Contiguous(const TRange &Other) const
Definition Range.h:217
void SetLowerBound(const BoundsType &NewLowerBound)
Definition Range.h:239
TArray< TRange > Split(ElementValueOrConstRef Element) const
Definition Range.h:442
TRange(ElementValueOrConstRef A, ElementValueOrConstRef B)
Definition Range.h:81
bool operator!=(const TRange &Other) const
Definition Range.h:121
bool Adjoins(const TRange &Other) const
Definition Range.h:143
static TRange Hull(const TArray< TRange > &Ranges)
Definition Range.h:528
bool Contains(const TRange &Other) const
Definition Range.h:203
TRange(ElementValueOrConstRef A)
Definition Range.h:68
DifferenceType Size() const
Definition Range.h:427
void SetUpperBound(const BoundsType &NewUpperBound)
Definition Range.h:285
bool HasUpperBound() const
Definition Range.h:331
BoundsType GetUpperBound() const
Definition Range.h:274
ElementValueOrConstRef GetLowerBoundValue() const
Definition Range.h:263
ElementValueOrConstRef GetUpperBoundValue() const
Definition Range.h:309
bool operator==(const TRange &Other) const
Definition Range.h:105
BoundsType GetLowerBound() const
Definition Range.h:228
static UE_FORCEINLINE_HINT TRange GreaterThan(ElementValueOrConstRef Value)
Definition Range.h:696
bool Conjoins(const TRange &X, const TRange &Y) const
Definition Range.h:175
static UE_FORCEINLINE_HINT TRange Empty()
Definition Range.h:671
static UE_FORCEINLINE_HINT TRange LessThan(ElementValueOrConstRef Value)
Definition Range.h:721
bool IsDegenerate() const
Definition Range.h:345
static UE_FORCEINLINE_HINT TRange AtLeast(ElementValueOrConstRef Value)
Definition Range.h:648
static TRange Hull(const TRange &X, const TRange &Y)
Definition Range.h:506
static UE_FORCEINLINE_HINT TRange All()
Definition Range.h:636
Definition DateTime.h:76
Definition FrameNumber.h:18
TCallTraitsParamTypeHelper< T, PassByValue >::ParamType ParamType
Definition UnrealTypeTraits.h:275