1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-31 02:35:46 +01:00
Files
OpenRCT2/src/openrct2/core/Range.hpp
2024-12-31 20:30:04 +01:00

111 lines
2.1 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2025 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include <cmath>
#include <type_traits>
template<typename T>
struct Range
{
static_assert(std::is_integral<T>(), "type must be integral");
class Iterator
{
friend Range;
private:
T Lower{};
T Upper{};
T Value{};
T Change{};
private:
Iterator(const Range& range, T initialValue)
: Lower(range.Lower)
, Upper(range.Upper)
, Value(initialValue)
, Change(range.Upper >= range.Lower ? 1 : -1)
{
}
public:
Iterator& operator++()
{
Value += Change;
return *this;
}
Iterator operator++(int)
{
auto result = *this;
++(*this);
return result;
}
bool operator==(Iterator other) const
{
return Value == other.Value;
}
bool operator!=(Iterator other) const
{
return !(*this == other);
}
const T& operator*()
{
return Value;
}
};
T Lower{};
T Upper{};
Range() = default;
Range(T single)
: Lower(single)
, Upper(single)
{
}
Range(T lower, T upper)
: Lower(lower)
, Upper(upper)
{
}
size_t size() const
{
return std::abs(Upper - Lower);
}
Iterator begin()
{
return Iterator(*this, Lower);
}
Iterator end()
{
return Iterator(*this, Upper + 1);
}
Iterator begin() const
{
return Iterator(*this, Lower);
}
Iterator end() const
{
return Iterator(*this, Upper + 1);
}
};