6#include "Containers/Array.h"
7#include "Misc/AssertionMacros.h"
8#include "Misc/DateTime.h"
9#include "Math/RangeBound.h"
10#include "Misc/FrameNumber.h"
11#include "Serialization/Archive.h"
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49template<
typename ElementType>
class TRange
62
63
64
65
66
67
69 : LowerBound(BoundsType::Inclusive(A))
70 , UpperBound(BoundsType::Inclusive(A))
74
75
76
77
78
79
80
82 : LowerBound(BoundsType::Inclusive(A))
83 , UpperBound(BoundsType::Exclusive(B))
87
88
89
90
91
93 : LowerBound(InLowerBound)
94 , UpperBound(InUpperBound)
100
101
102
103
104
107 if (IsEmpty() && Other.IsEmpty())
112 return ((LowerBound == Other.LowerBound) && (UpperBound == Other.UpperBound));
116
117
118
119
120
123 if (IsEmpty() && Other.IsEmpty())
128 return ((LowerBound != Other.LowerBound) || (UpperBound != Other.UpperBound));
134
135
136
137
138
139
140
141
142
145 if (IsEmpty() || Other.IsEmpty())
150 if (!UpperBound.IsOpen() && !Other.LowerBound.IsOpen() && UpperBound.GetValue() == Other.LowerBound.GetValue())
152 return ((UpperBound.IsInclusive() && Other.LowerBound.IsExclusive()) ||
153 (UpperBound.IsExclusive() && Other.LowerBound.IsInclusive()));
156 if (!Other.UpperBound.IsOpen() && !LowerBound.IsOpen() && Other.UpperBound.GetValue() == LowerBound.GetValue())
158 return ((Other.UpperBound.IsInclusive() && LowerBound.IsExclusive()) ||
159 (Other.UpperBound.IsExclusive() && LowerBound.IsInclusive()));
166
167
168
169
170
171
172
173
174
175 bool Conjoins(
const TRange& X,
const TRange& Y)
const
182 return (Adjoins(X) && Adjoins(Y));
186
187
188
189
190
193 return ((BoundsType::MinLower(LowerBound, Element) == LowerBound) &&
194 (BoundsType::MaxUpper(UpperBound, Element) == UpperBound));
198
199
200
201
202
205 return ((BoundsType::MinLower(LowerBound, Other.LowerBound) == LowerBound) &&
206 (BoundsType::MaxUpper(UpperBound, Other.UpperBound) == UpperBound));
210
211
212
213
214
215
216
219 return (Overlaps(Other) || Adjoins(Other));
223
224
225
226
227
234
235
236
237
238
241 LowerBound = NewLowerBound;
245
246
247
248
249
252 LowerBound.SetValue(NewLowerBoundValue);
256
257
258
259
260
261
262
265 return LowerBound.GetValue();
269
270
271
272
273
280
281
282
283
284
287 UpperBound = NewUpperBound;
291
292
293
294
295
298 UpperBound.SetValue(NewUpperBoundValue);
302
303
304
305
306
307
308
311 return UpperBound.GetValue();
315
316
317
318
319
322 return LowerBound.IsClosed();
326
327
328
329
330
333 return UpperBound.IsClosed();
337
338
339
340
341
342
343
344
347 return (LowerBound.IsInclusive() && (LowerBound == UpperBound));
351
352
353
354
355
356
357
358
359
360
363 if (LowerBound.IsClosed() && UpperBound.IsClosed())
365 if (LowerBound.GetValue() > UpperBound.GetValue())
370 return ((LowerBound.GetValue() == UpperBound.GetValue()) && (LowerBound.IsExclusive() || UpperBound.IsExclusive()));
377
378
379
380
381
384 if (IsEmpty() || Other.IsEmpty())
389 bool bUpperOpen = UpperBound.IsOpen() || Other.LowerBound.IsOpen();
390 bool bLowerOpen = LowerBound.IsOpen() || Other.UpperBound.IsOpen();
393 bool bUpperValid =
true;
394 bool bLowerValid =
true;
398 bool bUpperGreaterThan = UpperBound.GetValue() > Other.LowerBound.GetValue();
399 bool bUpperGreaterThanOrEqualTo = UpperBound.GetValue() >= Other.LowerBound.GetValue();
400 bool bUpperBothInclusive = UpperBound.IsInclusive() && Other.LowerBound.IsInclusive();
402 bUpperValid = bUpperBothInclusive ? bUpperGreaterThanOrEqualTo : bUpperGreaterThan;
407 bool bLowerLessThan = LowerBound.GetValue() < Other.UpperBound.GetValue();
408 bool bLowerLessThanOrEqualTo = LowerBound.GetValue() <= Other.UpperBound.GetValue();
409 bool bLowerBothInclusive = LowerBound.IsInclusive() && Other.UpperBound.IsInclusive();
411 bLowerValid = bLowerBothInclusive ? bLowerLessThanOrEqualTo : bLowerLessThan;
414 return bUpperValid && bLowerValid;
418
419
420
421
422
423
424
425
426 template<
typename DifferenceType> DifferenceType
Size()
const
428 check(LowerBound.IsClosed() && UpperBound.IsClosed());
430 return (UpperBound.GetValue() - LowerBound.GetValue());
434
435
436
437
438
439
440
443 TArray<TRange> Result;
445 if (Contains(Element))
447 Result.Add(TRange(LowerBound, BoundsType::Exclusive(Element)));
448 Result.Add(TRange(BoundsType::Inclusive(Element), UpperBound));
461
462
463
464
465
466
467
470 TArray<TRange> Result;
474 TRange LowerRange = TRange(X.LowerBound, BoundsType::FlipInclusion(Y.LowerBound));
475 TRange UpperRange = TRange(BoundsType::FlipInclusion(Y.UpperBound), X.UpperBound);
477 if (!LowerRange.IsEmpty())
479 Result.Add(LowerRange);
482 if (!UpperRange.IsEmpty())
484 Result.Add(UpperRange);
496
497
498
499
500
501
502
503
504
517 return TRange(BoundsType::MinLower(X.LowerBound, Y.LowerBound), BoundsType::MaxUpper(X.UpperBound, Y.UpperBound));
521
522
523
524
525
526
529 if (Ranges.Num() == 0)
531 return TRange::Empty();
534 TRange Bounds = Ranges[0];
536 for (int32 i = 1; i < Ranges.Num(); ++i)
538 Bounds = Hull(Bounds, Ranges[i]);
545
546
547
548
549
550
551
552
553
558 return TRange::Empty();
563 return TRange::Empty();
566 return TRange(BoundsType::MaxLower(X.LowerBound, Y.LowerBound), BoundsType::MinUpper(X.UpperBound, Y.UpperBound));
570
571
572
573
574
575
578 if (Ranges.Num() == 0)
580 return TRange::Empty();
583 TRange Bounds = Ranges[0];
585 for (int32 i = 1; i < Ranges.Num(); ++i)
587 Bounds = Intersection(Bounds, Ranges[i]);
594
595
596
597
598
599
600
601
602
605 TArray<TRange> OutRanges;
609 OutRanges.Add(TRange(BoundsType::MinLower(X.LowerBound, Y.LowerBound), BoundsType::MaxUpper(X.UpperBound, Y.UpperBound)));
630
631
632
633
634
637 return TRange(BoundsType::Open(), BoundsType::Open());
641
642
643
644
645
646
649 return TRange(BoundsType::Inclusive(Value), BoundsType::Open());
653
654
655
656
657
658
661 return TRange(BoundsType::Open(), BoundsType::Inclusive(Value));
665
666
667
668
669
672 return TRange(BoundsType::Exclusive(ElementType()), BoundsType::Exclusive(ElementType()));
676
677
678
679
680
681
682
685 return TRange(BoundsType::Exclusive(Min), BoundsType::Exclusive(Max));
689
690
691
692
693
694
697 return TRange(BoundsType::Exclusive(Value), BoundsType::Open());
701
702
703
704
705
706
707
710 return TRange(BoundsType::Inclusive(Min), BoundsType::Inclusive(Max));
714
715
716
717
718
719
722 return TRange(BoundsType::Open(), BoundsType::Exclusive(Value));
728
729
730
731
732
733
736 return Ar << Range.LowerBound << Range.UpperBound;
740
741
742
743
744
747 return (GetTypeHash(Range.LowerBound) + 23 * GetTypeHash(Range.UpperBound));
761
763#define DEFINE_RANGE_WRAPPER_STRUCT(Name, ElementType)
764 struct Name : TRange<ElementType>
767 typedef TRange<ElementType> Super;
775 Name(const Super& Rhs)
780 explicit Name(ElementValueOrConstRef A)
785 explicit Name(ElementValueOrConstRef A, ElementValueOrConstRef B)
790 explicit Name(const TRangeBound<ElementType>& InLowerBound, const TRangeBound<ElementType>& InUpperBound)
791 : Super(InLowerBound, InUpperBound)
795 TArray<Name> Split(ElementValueOrConstRef Element) const
797 return TArray<Name>(Super::Split(Element));
800 static FORCEINLINE TArray<Name> Difference(const Name& X, const Name& Y)
802 return TArray<Name>(Super::Difference(X, Y));
807 return Super::Empty();
810 static FORCEINLINE Name Hull(const Name& X, const Name& Y)
812 return Super::Hull(X, Y);
815 static FORCEINLINE Name Hull(const TArray<Name>& Ranges)
817 return Super::Hull(reinterpret_cast<const TArray<Super>&>(Ranges));
820 static FORCEINLINE Name Intersection(const Name& X, const Name& Y)
822 return Super::Intersection(X, Y);
825 static FORCEINLINE Name Intersection(const TArray<Name>& Ranges)
827 return Super::Intersection(reinterpret_cast<const TArray<Super>&>(Ranges));
830 static FORCEINLINE TArray<Name> Union(const Name& X, const Name& Y)
832 return TArray<Name>(Super::Union(X, Y));
840 static FORCEINLINE Name AtLeast(ElementValueOrConstRef Value)
842 return Super::AtLeast(Value);
845 static FORCEINLINE Name AtMost(ElementValueOrConstRef Value)
847 return Super::AtMost(Value);
850 static FORCEINLINE TRange GreaterThan(ElementValueOrConstRef Value)
852 return Super::GreaterThan(Value);
855 static FORCEINLINE TRange LessThan(ElementValueOrConstRef Value)
857 return Super::LessThan(Value);
862 struct TIsBitwiseConstructible<Name, TRange<ElementType>>
864 enum { Value = true };
868 struct TIsBitwiseConstructible<TRange<ElementType>, Name>
870 enum { Value = true };
#define DEFINE_RANGE_WRAPPER_STRUCT(Name, ElementType)
TCallTraits< ElementType >::ParamType ElementValueOrConstRef
static FORCEINLINE TRange Intersection(const TArray< TRange > &Ranges)
bool Contains(ElementValueOrConstRef Element) const
bool HasLowerBound() const
bool Overlaps(const TRange &Other) const
static FORCEINLINE TRange Hull(const TRange &X, const TRange &Y)
TRange(const BoundsType &InLowerBound, const BoundsType &InUpperBound)
static FORCEINLINE TRange LessThan(ElementValueOrConstRef Value)
static FORCEINLINE TRange AtLeast(ElementValueOrConstRef Value)
static FORCEINLINE TRange GreaterThan(ElementValueOrConstRef Value)
static FORCEINLINE TRange AtMost(ElementValueOrConstRef Value)
void SetUpperBoundValue(ElementValueOrConstRef NewUpperBoundValue)
void SetLowerBoundValue(ElementValueOrConstRef NewLowerBoundValue)
TRangeBound< ElementType > BoundsType
static FORCEINLINE TArray< TRange > Union(const TRange &X, const TRange &Y)
friend uint32 GetTypeHash(const TRange &Range)
static FORCEINLINE TRange All()
bool Contiguous(const TRange &Other) const
static FORCEINLINE TRange Hull(const TArray< TRange > &Ranges)
void SetLowerBound(const BoundsType &NewLowerBound)
TArray< TRange > Split(ElementValueOrConstRef Element) const
TRange(ElementValueOrConstRef A, ElementValueOrConstRef B)
bool operator!=(const TRange &Other) const
bool Adjoins(const TRange &Other) const
bool Contains(const TRange &Other) const
TRange(ElementValueOrConstRef A)
DifferenceType Size() const
static FORCEINLINE TRange Intersection(const TRange &X, const TRange &Y)
void SetUpperBound(const BoundsType &NewUpperBound)
bool HasUpperBound() const
BoundsType GetUpperBound() const
ElementValueOrConstRef GetLowerBoundValue() const
static FORCEINLINE TRange Exclusive(ElementValueOrConstRef Min, ElementValueOrConstRef Max)
ElementValueOrConstRef GetUpperBoundValue() const
bool operator==(const TRange &Other) const
static FORCEINLINE TRange Inclusive(ElementValueOrConstRef Min, ElementValueOrConstRef Max)
BoundsType GetLowerBound() const
bool Conjoins(const TRange &X, const TRange &Y) const
static FORCEINLINE TRange Empty()
bool IsDegenerate() const
static FORCEINLINE TArray< TRange > Difference(const TRange &X, const TRange &Y)