52 static_assert(
is_normal_v,
"[QRange::QRange] Typename T is partially or completely non-numeric!");
64 explicit QRange(std::pair<T, T> start_end)
65 :
QRange{ start_end.first, start_end.second } {}
79 explicit QRange(QString
start, QString
end, uint8_t first_base, uint8_t second_base = 0)
80 :
QRange{ normalizeValue(
start, first_base), normalizeValue(
end, second_base < 2 ? first_base : second_base) } {}
91 :
QRange{ normalizeValue(
start, base), normalizeValue(
start, base) + offset } {}
143 return { QString::number(
m_start, base), QString::number(
m_end, base) };
170 qWarning() <<
"[QRange::setDirection] There is no way to change direction in zero length range!";
175 qWarning() <<
"[QRange::setDirection] Invalid direction!";
180 qWarning() <<
"[QRange::setDirection] There is no way to set direction to Zero in non-zero length range!";
208 qWarning() <<
"[QRange::setDirection] Invalid direction!";
260 qWarning() <<
"[QRange::reverse] Invalid direction!";
277 qFatal(
"[QRange::isPositive] An unexpected error!");
292 qFatal(
"[QRange::isNegative] An unexpected error!");
318 return lower() <= number && number <=
upper();
319 qFatal(
"[QRange::contains] An unexpected error!");
335 qFatal(
"[QRange::contains] An unexpected error!");
351 qFatal(
"[QRange::in] An unexpected error!");
373 template <
typename... Args>
376 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
377 return r1.length() < r2.length();
388 template <
typename... Args>
391 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
392 return r1.length() > r2.length();
403 template <
typename... Args>
406 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
407 return r1.lower() < r2.lower();
418 template <
typename... Args>
421 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
422 return r1.upper() > r2.upper();
438 template <
typename... Args>
441 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
442 return r1.middleAccurate() < r2.middleAccurate();
458 template <
typename... Args>
461 return compareRanges(unpackRanges(ranges...), [](
const QRange& r1,
const QRange& r2) {
462 return r1.middleAccurate() > r2.middleAccurate();
472 static QList<T>
brake(
const QList<QRange>& ranges)
475 for (
const auto& range : ranges)
477 result.append(range.m_start);
478 result.append(range.m_end);
491 static QList<QRange>
merge(
const QList<T>& numbers)
493 QList<QRange> result;
494 auto editableNumbers = numbers;
495 while (!editableNumbers.isEmpty())
497 auto first = editableNumbers.takeFirst();
498 if (editableNumbers.isEmpty()) {
499 result.append(
QRange{ first, first });
503 auto second = editableNumbers.takeFirst();
504 result.append(
QRange{ first, second });
516 static QList<QRange>
cut(
const QRange& range,
int number)
518 QList<QRange> result;
524 qFatal(
"[QRange::cut] Incorrect number!");
526 if (number > range.
length())
527 qWarning() <<
"[QRange::cut] number > range.length(), so method can work strange";
529 T step = range.
length() / number;
531 T currentStart = range.
start();
532 for (
int i = 0; i < number; ++i)
534 T currentEnd = (i == number - 1) ? range.
end() : currentStart + step;
535 result.emplace_back(
QRange{ currentStart, currentEnd });
536 currentStart = currentEnd;
564 auto sortedRanges = ranges;
568 std::sort(sortedRanges.begin(), sortedRanges.end());
569 result = sortedRanges.first();
571 for (
const auto& range : sortedRanges) {
578 qFatal(
"[QRange::combine] Ranges have different directions!");
581 qFatal(
"[QRange::combine] There is a gap between ranges!");
583 result.
setEnd(sortedRanges[sortedRanges.count() - 1].m_end);
586 result = sortedRanges.first();
589 const auto [
min,
max] = std::minmax_element(numbers.begin(), numbers.end());
593 int countDirectionNegative = 0;
594 int countDirectionPositive = 0;
596 for (
const QRange& range : sortedRanges) {
598 countDirectionNegative++;
600 countDirectionPositive++;
603 if (countDirectionNegative > countDirectionPositive)
634 return { *
this, range };
636 return { *
this, *
this };
638 return { range, range };
658 return { *
this, *
this };
661 qWarning() <<
"[QRange::operator-] The subtracted is greater than the reduced";
662 return range - *
this;
670 return { resFirst, resSecond };
689 qFatal(
"[QRange::operator-] An unexpected error!");
701 qFatal(
"[QRange::operator*] The result is ∅!");
709 auto [
min,
max] = std::minmax_element(list.begin(), list.end());
710 list.removeOne(*
min);
711 list.removeOne(*
max);
712 auto res =
QRange{ list.front(), list.back() };
713 if (res.length() != 0) {
720 qFatal(
"[QRange::operator*] An unexpected error!");
736 return *
this - range;
744 return { resFirst, resSecond };
750 return { resFirst, resSecond };
753 qFatal(
"[QRange::operator/] An unexpected error!");
791 return os << range.getRangeInfo().toStdString();
796 return dbg << range.getRangeInfo();
822 || std::is_same<T, long>::value
823 || std::is_same<T, long long>::value
824 || std::is_same<T, unsigned int>::value
825 || std::is_same<T, unsigned long>::value
826 || std::is_same<T, unsigned long long>::value
827 || std::is_same<T, float>::value
828 || std::is_same<T, double>::value
829 || std::is_same<T, long double>::value;
840 std::pair<QRange, QRange>,
843 std::vector<QRange>>;
846 T normalizeValue(
const QString& value, uint8_t base)
850 if constexpr (std::is_integral<T>::value)
852 if (std::is_same_v<T, int>)
853 return value.toInt(&ok, base);
854 else if (std::is_same_v<T, long>)
855 return value.toLong(&ok, base);
856 else if (std::is_same_v<T, long long>)
857 return value.toLongLong(&ok, base);
858 else if (std::is_same_v<T, unsigned int>)
859 return value.toUInt(&ok, base);
860 else if (std::is_same_v<T, unsigned long>)
861 return value.toULong(&ok, base);
862 else if (std::is_same_v<T, unsigned long long>)
863 return value.toULongLong(&ok, base);
865 qWarning() <<
"[QRange::normalizeValue] Unsupported integer type.";
868 }
else if constexpr (std::is_floating_point_v<T>) {
869 if (std::is_same_v<T, float>)
870 return value.toFloat(&ok);
871 else if (std::is_same_v<T, double>)
872 return value.toDouble(&ok);
873 else if (std::is_same_v<T, long double>)
874 return static_cast<long double>(value.toDouble(&ok));
876 qWarning() <<
"[QRange::normalizeValue] Unsupported floating-point type.";
882 qCritical() << QString{
"[QRange::normalizeValue] Failed to convert string: %1!" }.arg(value);
887 template <
typename... Args>
888 static QList<QRange> unpackRanges(
const Args&... args)
890 auto ranges = QList<QRange>{};
891 std::initializer_list<ArgsType> initArgs{ args... };
892 for (
const auto& arg : initArgs)
893 unpackRange(ranges, arg);
897 static void unpackRange(QList<QRange>& allRanges,
const ArgsType& arg)
899 std::visit([&](
const auto& v) {
900 using VT = std::decay_t<
decltype(v)>;
901 if constexpr (std::is_same_v<VT, QRange>)
903 else if constexpr (std::is_same_v<VT, std::pair<QRange, QRange>>)
904 allRanges.append({ v.first, v.second });
905 else if constexpr (std::is_same_v<VT, QList<QRange>>
906 || std::is_same_v<VT, std::list<QRange>>
907 || std::is_same_v<VT, std::vector<QRange>>)
908 allRanges.append(QList<QRange>{ v.begin(), v.end() });
910 qWarning() <<
"[QRange::unpackRanges] Unexpected variant type";
914 template <
typename Comparator>
915 static QRange compareRanges(
const QList<QRange>& ranges, Comparator cmp)
917 if (ranges.empty()) {
918 qWarning() <<
"[QRange::compareRanges] There is nothing to compare";
922 auto result = ranges.first();
924 for (
const auto& currentRange : ranges)
925 if (cmp(currentRange, result))
926 result = currentRange;
931 QString getRangeInfo()
const
940 QString
property{
"error"};
946 property =
m_start < 0 ?
"-+" :
"+-";
949 return QString{
"[%1, %2]: {length: %3, direction: %4, property: %5}" }
void setEnd(const T end)
Sets the end of the range.
Definition qrange.h:159
double middleAccurate() const
Gets the exact center of the range, regardless of its generic type.
Definition qrange.h:122
bool operator>(const QRange &range) const
Operators >, <.
Definition qrange.h:762
static QRange combine(const QList< QRange > &ranges, QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive)
Method connects ranges from a QList to a single range.
Definition qrange.h:562
void reverse(const QRangeDirection &direction=QRangeDirection::Zero)
This method changes the values of the start and end of the range relative to the x-axis.
Definition qrange.h:224
std::pair< QRange, QRange > operator/(const QRange &range) const
Operator / works the same way as the set complement operator.
Definition qrange.h:729
bool operator<(const QRange &range) const
Definition qrange.h:763
static QList< T > brake(const QList< QRange > &ranges)
Method converts all ranges in the list to a number list.
Definition qrange.h:472
QRange(std::pair< T, T > start_end)
QRange(std::pair<T, T> start_end) - A constructor that creates a range based on a pair of set values,...
Definition qrange.h:64
friend std::ostream & operator<<(std::ostream &os, const QRange &range)
Definition qrange.h:789
T middle() const
Gets the midpoint of the range.
Definition qrange.h:117
void setDirection(int direction)
Definition qrange.h:194
bool operator>=(const QRange &range) const
Operators >=, <=.
Definition qrange.h:786
QRange operator-(T number) const
Definition qrange.h:620
static QRange min(const Args &... ranges)
This method finds the minimum length range from a set of ranges.
Definition qrange.h:374
bool contains(T number, QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
This method checks whether a number is contained within the range.
Definition qrange.h:313
T m_start
Definition qrange.h:800
QRange operator*(const QRange &range) const
Operator * works the same way as the set intersection operator.
Definition qrange.h:698
QRange()=default
Constructs a null range. Null ranges are also considered zero.
QRange(QString start, T offset, uint8_t base)
QRange - A constructor that takes the beginning of the range in a defined calculus systems,...
Definition qrange.h:90
T m_end
Definition qrange.h:801
bool in(const QRange &range, QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
This method checks whether the source range is contained within the external range.
Definition qrange.h:345
QRange(T start, T end)
QRange(T start, T end) - the constructor with 2 parameters.
Definition qrange.h:50
friend QDebug operator<<(QDebug dbg, const QRange &range)
Definition qrange.h:794
T length() const
Gets the length of the range.
Definition qrange.h:127
QRange(QString start, QString end, uint8_t first_base, uint8_t second_base=0)
QRange(QString start, QString end, uint8_t first_base, uint8_t second_base = 0) - A constructor that ...
Definition qrange.h:79
T start() const
Gets the start of the range.
Definition qrange.h:97
T lower() const
Gets the lower bound of the range.
Definition qrange.h:107
QRange operator+(T number) const
Operators +, -, *, /, % perform the appropriate mathematical operations with the start and the end of...
Definition qrange.h:619
bool isPositive(QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
isPositive property. Checks the beginning and end of the range relative to the x-axis.
Definition qrange.h:271
bool isMixed() const
isMixed property. Checks the beginning and end of the range relative to the x-axis.
Definition qrange.h:299
QRangeDirection direction() const
Gets the direction of the range.
Definition qrange.h:133
static QList< QRange > cut(const QRange &range, int number)
Method cuts the range into equal parts, the number of which is determined by.
Definition qrange.h:516
bool overlays(const QRange &range, QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
This method checks whether one range overlaps with another.
Definition qrange.h:361
QRange operator/(T number) const
Definition qrange.h:622
QRangeDirection m_direction
Definition qrange.h:802
bool contains(const QRange &range, QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
This method checks whether an external range is contained within the source range.
Definition qrange.h:329
std::pair< QRange, QRange > operator-(const QRange &range) const
Operator - works the same way as the set difference operator.
Definition qrange.h:655
static const bool is_normal_v
The library works with certain types of numeric data described below:
Definition qrange.h:821
static QRange maxMidX(const Args &... ranges)
This method finds the range that is closest to plus infinity on the x-axis.
Definition qrange.h:459
bool operator!=(const QRange &range) const
Definition qrange.h:775
static QRange minX(const Args &... ranges)
This method finds the minimum range on the x-axis from a set of ranges.
Definition qrange.h:404
T end() const
Gets the end of the range.
Definition qrange.h:102
void setStart(const T start)
Sets the start of the range.
Definition qrange.h:152
static QRange maxX(const Args &... ranges)
This method finds the maximum range on the x-axis from a set of ranges.
Definition qrange.h:419
std::pair< QString, QString > toAnotherBase(uint8_t base) const
Gets the range in another base.
Definition qrange.h:141
bool operator<=(const QRange &range) const
Definition qrange.h:787
std::variant< QRange, std::pair< QRange, QRange >, QList< QRange >, std::list< QRange >, std::vector< QRange > > ArgsType
QRange also has several functions with a variable number of parameters. These functions use the alias...
Definition qrange.h:839
static QRange max(const Args &... ranges)
This method finds the maximum length range from a set of ranges.
Definition qrange.h:389
void setDirection(const QRangeDirection &direction)
Sets the direction of the range by swapping the start and end.
Definition qrange.h:167
QRange operator%(T number) const
Definition qrange.h:623
void reverse(int direction)
Definition qrange.h:246
QRange operator*(T number) const
Definition qrange.h:621
bool isNegative(QRangeSensitivity sensitivity=QRangeSensitivity::Sensitive) const
isNegative property. Checks the beginning and end of the range relative to the x-axis.
Definition qrange.h:286
bool isZero() const
isZero property.
Definition qrange.h:304
static QRange minMidX(const Args &... ranges)
This method finds the range that is closest to minus infinity on the x-axis.
Definition qrange.h:439
static QList< QRange > merge(const QList< T > &numbers)
Method converts a list of numbers to the list of ranges. If there is an even number of elements,...
Definition qrange.h:491
bool operator==(const QRange &range) const
Operators ==, !=.
Definition qrange.h:771
std::pair< QRange, QRange > operator+(const QRange &range) const
Operator + works the same way as the set union operator.
Definition qrange.h:631
T upper() const
Gets the upper bound of the range.
Definition qrange.h:112
QRangeSensitivity
Enum that determines the sensitivity of certain methods, such as contains().
Definition qrange.h:21
@ Insensitive
Definition qrange.h:23
@ Sensitive
Definition qrange.h:22
QRangeDirection
Enum defining the direction of the range.
Definition qrange.h:10
@ Plus
Definition qrange.h:13
@ Minus
Definition qrange.h:11
@ Zero
Definition qrange.h:12