From 0340e19e042330d766e03e83b6438ced28b55377 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 22 Sep 2024 18:07:42 +0100 Subject: [PATCH] Codechange: Add to_underlying() to convert enum to underlying type. (#12958) This simplifies and replaces static_cast and C-style casts doing the same. `std::to_underlying()` exists in C++23 but not C++20. --- src/core/enum_type.hpp | 24 ++++++++++++++---------- src/misc/endian_buffer.hpp | 2 +- src/newgrf_engine.cpp | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/core/enum_type.hpp b/src/core/enum_type.hpp index e7405e3703..cabefee043 100644 --- a/src/core/enum_type.hpp +++ b/src/core/enum_type.hpp @@ -10,18 +10,22 @@ #ifndef ENUM_TYPE_HPP #define ENUM_TYPE_HPP +/** Implementation of std::to_underlying (from C++23) */ +template +constexpr std::underlying_type_t to_underlying(enum_type e) { return static_cast>(e); } + /** Some enums need to have allowed incrementing (i.e. StationClassID) */ #define DECLARE_POSTFIX_INCREMENT(enum_type) \ inline constexpr enum_type operator ++(enum_type& e, int) \ { \ enum_type e_org = e; \ - e = (enum_type)((std::underlying_type::type)e + 1); \ + e = static_cast(to_underlying(e) + 1); \ return e_org; \ } \ inline constexpr enum_type operator --(enum_type& e, int) \ { \ enum_type e_org = e; \ - e = (enum_type)((std::underlying_type::type)e - 1); \ + e = static_cast(to_underlying(e) - 1); \ return e_org; \ } @@ -29,19 +33,19 @@ /** Operators to allow to work with enum as with type safe bit set in C++ */ #define DECLARE_ENUM_AS_BIT_SET(enum_type) \ - inline constexpr enum_type operator | (enum_type m1, enum_type m2) {return (enum_type)((std::underlying_type::type)m1 | (std::underlying_type::type)m2);} \ - inline constexpr enum_type operator & (enum_type m1, enum_type m2) {return (enum_type)((std::underlying_type::type)m1 & (std::underlying_type::type)m2);} \ - inline constexpr enum_type operator ^ (enum_type m1, enum_type m2) {return (enum_type)((std::underlying_type::type)m1 ^ (std::underlying_type::type)m2);} \ - inline constexpr enum_type& operator |= (enum_type& m1, enum_type m2) {m1 = m1 | m2; return m1;} \ - inline constexpr enum_type& operator &= (enum_type& m1, enum_type m2) {m1 = m1 & m2; return m1;} \ - inline constexpr enum_type& operator ^= (enum_type& m1, enum_type m2) {m1 = m1 ^ m2; return m1;} \ - inline constexpr enum_type operator ~(enum_type m) {return (enum_type)(~(std::underlying_type::type)m);} + inline constexpr enum_type operator | (enum_type m1, enum_type m2) { return static_cast(to_underlying(m1) | to_underlying(m2)); } \ + inline constexpr enum_type operator & (enum_type m1, enum_type m2) { return static_cast(to_underlying(m1) & to_underlying(m2)); } \ + inline constexpr enum_type operator ^ (enum_type m1, enum_type m2) { return static_cast(to_underlying(m1) ^ to_underlying(m2)); } \ + inline constexpr enum_type& operator |= (enum_type& m1, enum_type m2) { m1 = m1 | m2; return m1; } \ + inline constexpr enum_type& operator &= (enum_type& m1, enum_type m2) { m1 = m1 & m2; return m1; } \ + inline constexpr enum_type& operator ^= (enum_type& m1, enum_type m2) { m1 = m1 ^ m2; return m1; } \ + inline constexpr enum_type operator ~(enum_type m) { return static_cast(~to_underlying(m)); } /** Operator that allows this enumeration to be added to any other enumeration. */ #define DECLARE_ENUM_AS_ADDABLE(EnumType) \ template , OtherEnumType>::type> \ constexpr OtherEnumType operator + (OtherEnumType m1, EnumType m2) { \ - return static_cast(static_cast::type>(m1) + static_cast::type>(m2)); \ + return static_cast(to_underlying(m1) + to_underlying(m2)); \ } /** diff --git a/src/misc/endian_buffer.hpp b/src/misc/endian_buffer.hpp index 29e810fa2b..7ff52ff930 100644 --- a/src/misc/endian_buffer.hpp +++ b/src/misc/endian_buffer.hpp @@ -50,7 +50,7 @@ public: EndianBufferWriter &operator <<(const T data) { if constexpr (std::is_enum_v) { - this->Write(static_cast>(data)); + this->Write(to_underlying(data)); } else if constexpr (std::is_base_of_v) { this->Write(data.base()); } else { diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index b5659581bd..6a37ce0bcf 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1200,7 +1200,7 @@ int GetEngineProperty(EngineID engine, PropertyID property, int orig_value, cons */ bool TestVehicleBuildProbability(Vehicle *v, EngineID engine, BuildProbabilityType type) { - uint16_t p = GetVehicleCallback(CBID_VEHICLE_BUILD_PROBABILITY, std::underlying_type::type(type), 0, engine, v); + uint16_t p = GetVehicleCallback(CBID_VEHICLE_BUILD_PROBABILITY, to_underlying(type), 0, engine, v); if (p == CALLBACK_FAILED) return false; const uint16_t PROBABILITY_RANGE = 100;