ACF $AcfVersion:0$
TRange.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// STL includes
6#include <algorithm>
7#include <cmath>
8
9// Qt includes
10#include <QtCore/QtGlobal>
11
12
13namespace istd
14{
15
16
20template <typename ValueType>
21class TRange
22{
23public:
31 TRange(const TRange& range);
32
36 TRange(ValueType minValue, ValueType maxValue);
37
41 bool IsValid() const;
42
46 bool IsEmpty() const;
47
51 bool IsValidNonEmpty() const;
52
56 ValueType GetMinValue() const;
57
61 ValueType& GetMinValueRef();
62
66 void SetMinValue(ValueType minValue);
67
71 ValueType GetAbsMinValue() const;
72
76 ValueType GetAbsMaxValue() const;
77
81 ValueType GetMaxValue() const;
82
86 ValueType& GetMaxValueRef();
87
91 void SetMaxValue(ValueType maxValue);
92
96 void Reset();
97
102 ValueType GetLength() const;
103
110
116 void GetValidated(TRange& result) const;
117
123 void Validate();
124
129 bool Contains(ValueType value) const;
130
134 bool Contains(const TRange& range) const;
135
140 bool IsIntersectedBy(const TRange& range) const;
141
145 bool IsOutsideOf(const TRange& range) const;
146
151 TRange GetTranslated(ValueType offset) const;
152
157 void Translate(ValueType offset);
158
162 TRange GetIntersection(const TRange& range) const;
163
167 void Intersection(const TRange& range);
168
172 TRange GetUnion(const TRange& range) const;
173
177 TRange GetUnion(double value) const;
178
182 void Unite(const TRange& range);
183
187 void Unite(double value);
188
193 TRange GetExpanded(const TRange& range) const;
194
199 void Expand(const TRange& range);
200
205 ValueType GetDistance(ValueType value) const;
209 ValueType GetNearestInside(ValueType value) const;
210
214 ValueType GetClipped(ValueType value) const;
215
219 TRange GetClipped(const TRange& range) const;
220
227 ValueType GetValueFromAlpha(double alpha) const;
228
235 double GetAlphaFromValue(ValueType value) const;
236
248 ValueType GetMappedTo(ValueType value, const TRange& range) const;
249
254 TRange GetApply(const TRange& range) const;
255
256 TRange GetInvertApply(const TRange& range) const;
257
259
263 void SetInterpolated(const TRange& first, const TRange& second, double alpha);
264
265 TRange& operator=(const TRange& range);
266 bool operator==(const TRange& range) const;
267 bool operator!=(const TRange& range) const;
268 TRange operator*(double value) const;
269 TRange operator/(double value) const;
270 TRange& operator*=(double value);
271 TRange& operator/=(double value);
272
273 // static methods
277 static const TRange& GetNull();
281 static const TRange& GetInvalid();
285 static TRange GetValid(ValueType value1, ValueType value2);
286
287private:
288 ValueType m_minValue;
289 ValueType m_maxValue;
290};
291
292
293// public methods
294
295template <typename ValueType>
297 :m_minValue(0),
298 m_maxValue(0)
299{
300}
301
302
303template <typename ValueType>
305 :m_minValue(range.m_minValue),
306 m_maxValue(range.m_maxValue)
307{
308}
309
310
311template <typename ValueType>
312TRange<ValueType>::TRange(ValueType minValue, ValueType maxValue)
313 :m_minValue(minValue),
314 m_maxValue(maxValue)
315{
316}
317
318
319template <typename ValueType>
320inline bool TRange<ValueType>::IsValid() const
321{
322 return (m_minValue <= m_maxValue);
323}
324
325
326template <typename ValueType>
327inline bool TRange<ValueType>::IsEmpty() const
328{
329 return (m_minValue == m_maxValue);
330}
331
332
333template <typename ValueType>
335{
336 return (m_minValue < m_maxValue);
337}
338
339
340template <typename ValueType>
341inline ValueType TRange<ValueType>::GetMinValue() const
342{
343 return m_minValue;
344}
345
346
347template <typename ValueType>
349{
350 return m_minValue;
351}
352
353
354template <typename ValueType>
355inline void TRange<ValueType>::SetMinValue(ValueType minValue)
356{
357 m_minValue = minValue;
358}
359
360
361template <typename ValueType>
363{
364 ValueType absMin = std::abs(m_minValue);
365 ValueType absMax = std::abs(m_maxValue);
366
367 return std::min<ValueType>(absMin , absMax);
368}
369
370
371template <typename ValueType>
373{
374 ValueType absMin = std::abs(m_minValue);
375 ValueType absMax = std::abs(m_maxValue);
376
377 return std::max<ValueType>(absMin, absMax);
378}
379
380
381template <typename ValueType>
382inline ValueType TRange<ValueType>::GetMaxValue() const
383{
384 return m_maxValue;
385}
386
387
388template <typename ValueType>
390{
391 return m_maxValue;
392}
393
394
395template <typename ValueType>
396inline void TRange<ValueType>::SetMaxValue(ValueType maxValue)
397{
398 m_maxValue = maxValue;
399}
400
401
402template <typename ValueType>
404{
405 m_minValue = ValueType(0);
406 m_maxValue = ValueType(0);
407}
408
409
410template <typename ValueType>
411inline ValueType TRange<ValueType>::GetLength() const
412{
413 return IsValid() ? m_maxValue - m_minValue: 0;
414}
415
416
417template <typename ValueType>
419{
420 return TRange(
421 std::min<ValueType>(m_minValue, m_maxValue),
422 std::max<ValueType>(m_minValue, m_maxValue));
423}
424
425
426template <typename ValueType>
427inline void TRange<ValueType>::GetValidated(TRange& result) const
428{
429 result.SetMinValue(std::min<ValueType>(m_minValue, m_maxValue));
430 result.SetMaxValue(std::max<ValueType>(m_minValue, m_maxValue));
431}
432
433
434template <typename ValueType>
436{
437 *this = TRange(std::min<ValueType>(m_minValue, m_maxValue), std::max<ValueType>(m_minValue, m_maxValue));
438}
439
440
441template <typename ValueType>
442inline bool TRange<ValueType>::Contains(ValueType value) const
443{
444 Q_ASSERT(IsValid());
445
446 return (value >= m_minValue) && (value <= m_maxValue);
447}
448
449
450template <typename ValueType>
451inline bool TRange<ValueType>::Contains(const TRange& range) const
452{
453 Q_ASSERT(IsValid());
454 Q_ASSERT(range.IsValid());
455
456 return (range.m_minValue >= m_minValue) && (range.m_maxValue <= m_maxValue);
457}
458
459
460template <typename ValueType>
461inline bool TRange<ValueType>::IsIntersectedBy(const TRange& range) const
462{
463 return (range.m_maxValue > m_minValue) && (range.m_minValue < m_maxValue);
464}
465
466
467template <typename ValueType>
468inline bool TRange<ValueType>::IsOutsideOf(const TRange& range) const
469{
470 return (range.m_maxValue <= m_minValue) || (range.m_minValue >= m_maxValue);
471}
472
473
474template <typename ValueType>
476{
477 return TRange(m_minValue + offset, m_maxValue + offset);
478}
479
480
481template <typename ValueType>
482inline void TRange<ValueType>::Translate(ValueType offset)
483{
484 m_minValue += offset;
485 m_maxValue += offset;
486}
487
488
489template <typename ValueType>
491{
492 if (IsEmpty()){
493 return *this;
494 }
495 else{
496 return TRange(std::max<ValueType>(m_minValue, range.m_minValue), std::min<ValueType>(m_maxValue, range.m_maxValue));
497 }
498}
499
500
501template <typename ValueType>
503{
504 if (!IsEmpty()){
505 if (range.m_minValue > m_minValue){
506 m_minValue = range.m_minValue;
507 }
508
509 if (range.m_maxValue < m_maxValue){
510 m_maxValue = range.m_maxValue;
511 }
512 }
513}
514
515
516template <typename ValueType>
518{
519 if (range.IsValid()){
520 if (IsValid()){
521 return TRange(std::min<ValueType>(m_minValue, range.m_minValue), std::max<ValueType>(m_maxValue, range.m_maxValue));
522 }
523 else{
524 return range;
525 }
526 }
527 else{
528 return *this;
529 }
530}
531
532
533template <typename ValueType>
535{
536 if (IsValid()){
537 return TRange(std::min<ValueType>(m_minValue, value), std::max<ValueType>(m_maxValue, value));
538 }
539 else{
540 return TRange(value, value);
541 }
542}
543
544
545template <typename ValueType>
547{
548 if (range.IsValid()){
549 if (IsValid()){
550 if (range.m_minValue < m_minValue){
551 m_minValue = range.m_minValue;
552 }
553
554 if (range.m_maxValue > m_maxValue){
555 m_maxValue = range.m_maxValue;
556 }
557 }
558 else{
559 *this = range;
560 }
561 }
562}
563
564
565template <typename ValueType>
566void TRange<ValueType>::Unite(double value)
567{
568 if (IsValid()){
569 if (value < m_minValue){
570 m_minValue = value;
571 }
572
573 if (value > m_maxValue){
574 m_maxValue = value;
575 }
576 }
577 else{
578 m_minValue = value;
579 m_maxValue = value;
580 }
581}
582
583
584template <typename ValueType>
586{
587 return TRange(m_minValue + range.m_minValue, m_maxValue + range.m_maxValue);
588}
589
590
591template <typename ValueType>
592inline void TRange<ValueType>::Expand(const TRange& range)
593{
594 m_minValue += range.m_minValue;
595 m_maxValue += range.m_maxValue;
596}
597
598
599template <typename ValueType>
600inline ValueType TRange<ValueType>::GetDistance(ValueType value) const
601{
602 if (value > m_maxValue){
603 return value - m_maxValue;
604 }
605
606 if (value < m_minValue){
607 return m_minValue - value;
608 }
609
610 return 0;
611}
612
613
614template <typename ValueType>
615inline ValueType TRange<ValueType>::GetNearestInside(ValueType value) const
616{
617 if (value > m_maxValue){
618 value = m_maxValue;
619 }
620
621 if (value < m_minValue){
622 value = m_minValue;
623 }
624
625 return value;
626}
627
628
629template <typename ValueType>
630ValueType TRange<ValueType>::GetClipped(ValueType value) const
631{
632 if (!Contains(value)){
633 ValueType distanceMin = (ValueType)qAbs(value - m_minValue);
634 ValueType distanceMax = (ValueType)qAbs(value - m_maxValue);
635
636 return distanceMin < distanceMax ? m_minValue : m_maxValue;
637 }
638
639 return value;
640}
641
642
643template <typename ValueType>
645{
646 istd::TRange<ValueType> clippedRange = range;
647
648 if (!Contains(range.GetMinValue())){
649 clippedRange.SetMinValue(m_minValue);
650 }
651
652 if (!Contains(range.GetMaxValue())){
653 clippedRange.SetMaxValue(m_maxValue);
654 }
655
656 return clippedRange;
657}
658
659
660template <typename ValueType>
661inline ValueType TRange<ValueType>::GetValueFromAlpha(double alpha) const
662{
663 return GetMinValue() + alpha * GetLength();
664}
665
666
667template <typename ValueType>
668inline double TRange<ValueType>::GetAlphaFromValue(ValueType value) const
669{
670 auto length = static_cast<double>(GetLength());
671 if (length)
672 return static_cast<double>(value - GetMinValue()) / length;
673 else
674 return 0.0;
675}
676
677
678template <typename ValueType>
679inline ValueType TRange<ValueType>::GetMappedTo(ValueType value, const TRange& range) const
680{
681 ValueType length = GetLength();
682 if (length)
683 return ValueType(range.GetMinValue() + (value - GetMinValue()) * (range.GetLength() / length));
684 else
685 return (ValueType) 0.0;
686}
687
688
689template <typename ValueType>
691{
692 TRange result;
693 result.m_minValue = GetValueFromAlpha(range.m_minValue);
694 result.m_maxValue = GetValueFromAlpha(range.m_maxValue);
695
696 return result;
697}
698
699
700template <typename ValueType>
702{
703 TRange result;
704
705 double length = GetLength();
706 if (length)
707 {
708 result.m_minValue = ValueType((range.m_minValue - m_minValue) / length);
709 result.m_maxValue = ValueType((range.m_maxValue - m_minValue) / length);
710 }
711 else
712 {
713 result.m_minValue = result.m_maxValue = 0.0;
714 }
715
716 return result;
717}
718
719
720template <typename ValueType>
722{
723 TRange result;
724
725 ValueType minusWidth = m_minValue - m_maxValue;
726 if (minusWidth)
727 {
728 result.m_minValue = ValueType(m_minValue / (double)minusWidth);
729 result.m_maxValue = ValueType((m_minValue - 1) / (double)minusWidth);
730 }
731 else
732 {
733 result.m_minValue = result.m_maxValue = 0.0;
734 }
735
736 return result;
737}
738
739
740template <typename ValueType>
741void TRange<ValueType>::SetInterpolated(const TRange& first, const TRange& second, double alpha)
742{
743 double beta = 1 - alpha;
744
745 m_minValue = ValueType(first.m_minValue * beta + second.m_minValue * alpha);
746 m_maxValue = ValueType(first.m_maxValue * beta + second.m_maxValue * alpha);
747}
748
749
750template <typename ValueType>
751inline bool TRange<ValueType>::operator==(const TRange& range) const
752{
753 return (m_maxValue == range.m_maxValue) && (m_minValue == range.m_minValue);
754}
755
756
757template <typename ValueType>
758inline bool TRange<ValueType>::operator!=(const TRange& range) const
759{
760 return (m_maxValue != range.m_maxValue) || (m_minValue != range.m_minValue);
761}
762
763
764
765template <typename ValueType>
767{
768 m_maxValue = range.m_maxValue;
769 m_minValue = range.m_minValue;
770
771 return *this;
772}
773
774
775template <typename ValueType>
777{
778 TRange result = *this;
779
780 result.m_minValue *= value;
781 result.m_maxValue *= value;
782
783 return result;
784}
785
786
787template <typename ValueType>
789{
790 TRange result = *this;
791
792 if (value)
793 {
794 result.m_minValue /= value;
795 result.m_maxValue /= value;
796 }
797 else
798 {
799 result.m_minValue = result.m_maxValue = 0.0;
800 }
801
802 return result;
803}
804
805
806template <typename ValueType>
808{
809 m_minValue *= value;
810 m_maxValue *= value;
811
812 return *this;
813}
814
815
816template <typename ValueType>
818{
819 if (value)
820 {
821 m_minValue /= value;
822 m_maxValue /= value;
823 }
824 else
825 {
826 m_minValue = m_maxValue = 0.0;
827 }
828
829 return *this;
830}
831
832
833// static methods
834
835template <typename ValueType>
836inline TRange<ValueType> TRange<ValueType>::GetValid(ValueType value1, ValueType value2)
837{
838 return TRange(std::min<ValueType>(value1, value2), std::max<ValueType>(value1, value2));
839}
840
841
842// static methods
843
844template <typename ValueType>
846{
847 static const TRange<ValueType> s_null(0, 0);
848 return s_null;
849}
850
851
852template <typename ValueType>
854{
855 static const TRange<ValueType> s_invalid(0, -1);
856 return s_invalid;
857}
858
859
860// typedefs
861
864
865
866} // namespace istd
867
868
Implementation of a abstract range defined by two values - minimum and maximum.
Definition TRange.h:22
TRange & operator*=(double value)
Definition TRange.h:807
bool operator==(const TRange &range) const
Definition TRange.h:751
bool Contains(const TRange &range) const
Returns true, if this range is inside of the range.
Definition TRange.h:451
void GetValidated(TRange &result) const
Get validated range, if it was invalid.
Definition TRange.h:427
ValueType GetClipped(ValueType value) const
Get value clipped to the range.
Definition TRange.h:630
TRange(const TRange &range)
Copy constructor.
Definition TRange.h:304
TRange GetClipped(const TRange &range) const
Get range clipped to the current range.
Definition TRange.h:644
TRange & operator/=(double value)
Definition TRange.h:817
void Validate()
Force this range to be valid.
Definition TRange.h:435
ValueType GetAbsMinValue() const
Get the minimum by the absolute value.
Definition TRange.h:362
ValueType GetNearestInside(ValueType value) const
Get nearest value belonging to range.
Definition TRange.h:615
TRange GetInverted() const
Definition TRange.h:721
bool IsOutsideOf(const TRange &range) const
Check if this range is outside of the given range.
Definition TRange.h:468
TRange operator/(double value) const
Definition TRange.h:788
ValueType GetLength() const
Get length of this range.
Definition TRange.h:411
void Unite(const TRange &range)
Set this range to be union of two ranges.
Definition TRange.h:546
void Reset()
Set this range to be empty.
Definition TRange.h:403
TRange(ValueType minValue, ValueType maxValue)
Constructs a range object from two numbers.
Definition TRange.h:312
void Unite(double value)
Set this range to be union of two ranges.
Definition TRange.h:566
static const TRange & GetInvalid()
Return invalid range.
Definition TRange.h:853
void SetMinValue(ValueType minValue)
Set the bottom value.
Definition TRange.h:355
TRange operator*(double value) const
Definition TRange.h:776
TRange GetUnion(double value) const
Get union with the second range.
Definition TRange.h:534
double GetAlphaFromValue(ValueType value) const
Get value based on 'alpha' factor.
Definition TRange.h:668
TRange GetExpanded(const TRange &range) const
Get expanded range using the second range.
Definition TRange.h:585
TRange()
Constructs an empty range object.
Definition TRange.h:296
ValueType GetMaxValue() const
Get the top value.
Definition TRange.h:382
ValueType GetValueFromAlpha(double alpha) const
Get value based on 'alpha' factor.
Definition TRange.h:661
bool Contains(ValueType value) const
Returns true, if value is in range between top and bottom.
Definition TRange.h:442
void Expand(const TRange &range)
Set this range to be expanded.
Definition TRange.h:592
void Intersection(const TRange &range)
Set this range to be intersection of two ranges.
Definition TRange.h:502
void SetInterpolated(const TRange &first, const TRange &second, double alpha)
Set this range to be linear interpolated using two other ranges and adjast alpha value.
Definition TRange.h:741
static TRange GetValid(ValueType value1, ValueType value2)
Return always valid range.
Definition TRange.h:836
TRange GetUnion(const TRange &range) const
Get union with the second range.
Definition TRange.h:517
TRange GetTranslated(ValueType offset) const
Get translated position range.
Definition TRange.h:475
ValueType GetMinValue() const
Get the bottom value.
Definition TRange.h:341
bool IsEmpty() const
Return true if the bottom value is equal to the top value.
Definition TRange.h:327
static const TRange & GetNull()
Return null range.
Definition TRange.h:845
bool IsIntersectedBy(const TRange &range) const
Check if this range is intersected by other range.
Definition TRange.h:461
bool IsValidNonEmpty() const
Return true if the range is valid and it is not empty.
Definition TRange.h:334
void Translate(ValueType offset)
Translated position of this range.
Definition TRange.h:482
ValueType & GetMinValueRef()
Get reference to the bottom value.
Definition TRange.h:348
bool IsValid() const
Return true if the bottom value is smaller or equal then the top value.
Definition TRange.h:320
TRange GetApply(const TRange &range) const
Get a combined range.
Definition TRange.h:690
ValueType GetMappedTo(ValueType value, const TRange &range) const
Returns the value, that corresponds the input value inputValue in the other range range.
Definition TRange.h:679
ValueType & GetMaxValueRef()
Get reference to the top value.
Definition TRange.h:389
TRange GetIntersection(const TRange &range) const
Get intersection with the second range.
Definition TRange.h:490
TRange GetInvertApply(const TRange &range) const
Definition TRange.h:701
TRange & operator=(const TRange &range)
Definition TRange.h:766
ValueType GetAbsMaxValue() const
Get the maximum by the absolute value.
Definition TRange.h:372
bool operator!=(const TRange &range) const
Definition TRange.h:758
ValueType GetDistance(ValueType value) const
Get distance from value to range.
Definition TRange.h:600
void SetMaxValue(ValueType maxValue)
Set the top value.
Definition TRange.h:396
TRange GetValidated() const
Get validated range, if it was invalid.
Definition TRange.h:418
Standard library.
Definition IComponent.h:17
istd::TRange< int > CIntRange
Definition TRange.h:863
istd::TRange< double > CRange
Definition TRange.h:862