diff --git a/src/core/convertible_through_base.hpp b/src/core/convertible_through_base.hpp index cc27702547..8b9fec0152 100644 --- a/src/core/convertible_through_base.hpp +++ b/src/core/convertible_through_base.hpp @@ -36,11 +36,17 @@ concept ConvertibleThroughBaseOrTo = std::is_convertible_v || Convertibl template class ReferenceThroughBaseContainer : public Container { public: - Container::reference at(ConvertibleThroughBase auto pos) { return this->Container::at(pos.base()); } - Container::const_reference at(ConvertibleThroughBase auto pos) const { return this->Container::at(pos.base()); } + Container::reference at(size_t pos) { return this->Container::at(pos); } + Container::reference at(const ConvertibleThroughBase auto &pos) { return this->Container::at(pos.base()); } - Container::reference operator[](ConvertibleThroughBase auto pos) { return this->Container::operator[](pos.base()); } - Container::const_reference operator[](ConvertibleThroughBase auto pos) const { return this->Container::operator[](pos.base()); } + Container::const_reference at(size_t pos) const { return this->Container::at(pos); } + Container::const_reference at(const ConvertibleThroughBase auto &pos) const { return this->Container::at(pos.base()); } + + Container::reference operator[](size_t pos) { return this->Container::operator[](pos); } + Container::reference operator[](const ConvertibleThroughBase auto &pos) { return this->Container::operator[](pos.base()); } + + Container::const_reference operator[](size_t pos) const { return this->Container::operator[](pos); } + Container::const_reference operator[](const ConvertibleThroughBase auto &pos) const { return this->Container::operator[](pos.base()); } }; #endif /* CONVERTIBLE_THROUGH_BASE_HPP */ diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 6d4bd9fce9..dfe922fc74 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -61,6 +61,8 @@ struct EMPTY_BASES PoolID : PoolIDBase { constexpr auto operator++() { ++this->value; return this; } constexpr auto operator+(const std::integral auto &val) const { return this->value + val; } + constexpr auto operator-(const std::integral auto &val) const { return this->value - val; } + constexpr auto operator%(const std::integral auto &val) const { return this->value % val; } constexpr bool operator==(const PoolID &rhs) const { return this->value == rhs.value; } constexpr auto operator<=>(const PoolID &rhs) const { return this->value <=> rhs.value; } @@ -72,6 +74,11 @@ private: TBaseType value; }; +template requires std::is_base_of_v +constexpr auto operator+(const std::integral auto &val, const T &pool_id) { return pool_id + val; } +template requires std::is_enum_v && std::is_base_of_v +constexpr auto operator+(const Te &val, const Tp &pool_id) { return pool_id + to_underlying(val); } + /** Base class for base of all pools. */ struct PoolBase { const PoolType type; ///< Type of this pool. diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 839f8d4740..2105bf24a9 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -15,6 +15,7 @@ #include "os_abstraction.h" #include "config.h" #include "core.h" +#include "../../core/convertible_through_base.hpp" #include "../../string_type.h" typedef uint16_t PacketSize; ///< Size of the whole packet. @@ -63,6 +64,7 @@ public: bool CanWriteToPacket(size_t bytes_to_write); void Send_bool (bool data); void Send_uint8 (uint8_t data); + void Send_uint8 (const ConvertibleThroughBase auto &data) { this->Send_uint8(data.base()); } void Send_uint16(uint16_t data); void Send_uint32(uint32_t data); void Send_uint64(uint64_t data); diff --git a/src/newgrf_debug.h b/src/newgrf_debug.h index 989514db0e..0a9ce1a842 100644 --- a/src/newgrf_debug.h +++ b/src/newgrf_debug.h @@ -33,7 +33,9 @@ extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker; bool IsNewGRFInspectable(GrfSpecFeature feature, uint index); void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32_t grfid = 0); void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, uint index); +void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, ConvertibleThroughBase auto index) { InvalidateNewGRFInspectWindow(feature, index.base()); } void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index); +void DeleteNewGRFInspectWindow(GrfSpecFeature feature, ConvertibleThroughBase auto index) { DeleteNewGRFInspectWindow(feature, index.base()); } GrfSpecFeature GetGrfSpecFeature(TileIndex tile); GrfSpecFeature GetGrfSpecFeature(VehicleType type); diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 789c6a8224..9ccb0f4b54 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -73,6 +73,8 @@ static inline uint GetInspectWindowNumber(GrfSpecFeature feature, uint index) return (feature << 24) | index; } +static inline uint GetInspectWindowNumber(GrfSpecFeature feature, ConvertibleThroughBase auto index) { return GetInspectWindowNumber(feature, index.base()); } + /** * The type of a property to show. This is used to * provide an appropriate representation in the GUI. @@ -226,6 +228,11 @@ protected: SetDParam(2, index); SetDParam(3, tile); } + + void SetObjectAtStringParameters(StringID string, ConvertibleThroughBase auto index, TileIndex tile) const + { + this->SetObjectAtStringParameters(string, index.base(), tile); + } }; diff --git a/src/source_type.h b/src/source_type.h index 2906dc1857..f14b0fd4b3 100644 --- a/src/source_type.h +++ b/src/source_type.h @@ -34,12 +34,17 @@ public: SourceID id; ///< Index of industry/town/HQ, Source::Invalid if unknown/invalid. SourceType type; ///< Type of \c source_id. + Source() = default; + Source(ConvertibleThroughBase auto id, SourceType type) : id(id.base()), type(type) {} + Source(SourceID id, SourceType type) : id(id), type(type) {} + constexpr CompanyID ToCompanyID() const { assert(this->type == SourceType::Headquarters); return static_cast(this->id); } constexpr IndustryID ToIndustryID() const { assert(this->type == SourceType::Industry); return static_cast(this->id); } constexpr TownID ToTownID() const { assert(this->type == SourceType::Town); return static_cast(this->id); } constexpr void MakeInvalid() { this->id = Source::Invalid; } constexpr void SetIndex(SourceID index) { this->id = index; } + constexpr void SetIndex(ConvertibleThroughBase auto index) { this->id = index.base(); } constexpr bool IsValid() const noexcept { return this->id != Source::Invalid; } auto operator<=>(const Source &source) const = default; diff --git a/src/window_func.h b/src/window_func.h index 2d51cc04c4..2b4fbfe0ff 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -35,6 +35,7 @@ void SetupColoursAndInitialWindow(); void InputLoop(); void InvalidateWindowData(WindowClass cls, WindowNumber number, int data = 0, bool gui_scope = false); +void InvalidateWindowData(WindowClass cls, WindowNumber number, ConvertibleThroughBase auto data, bool gui_scope = false) { InvalidateWindowData(cls, number, data.base(), gui_scope); } void InvalidateWindowClassesData(WindowClass cls, int data = 0, bool gui_scope = false); void InvalidateWindowClassesData(WindowClass cls, ConvertibleThroughBase auto data, bool gui_scope = false) { InvalidateWindowClassesData(cls, data.base(), gui_scope); } diff --git a/src/window_type.h b/src/window_type.h index 0c441689e4..62de2281cf 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -763,6 +763,9 @@ public: /* Automatically convert to any other type that might be requested. */ template requires (std::is_enum_v || std::is_class_v) operator T() const { return static_cast(value); }; + + constexpr bool operator==(const std::integral auto &rhs) const { return this->value == static_cast(rhs); } + constexpr bool operator==(const ConvertibleThroughBase auto &rhs) const { return this->value == static_cast(rhs.base()); } }; /** State of handling an event. */