diff --git a/CHANGELOG.md b/CHANGELOG.md index 066786e09..9be1267e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,7 +61,8 @@ - Added `BusToSignalAdapter` component for communicating bus voltages and injection currents. - Added cmake-format hooks, including in pre-commit. - Added off-nominal tap ratio and phase shift support to the PhasorDynamics `Branch` model. -- Added portable Vector class to GridKit +- Added portable Vector class to GridKit. +- Added Windows compatibility. ## v0.1 diff --git a/GridKit/CommonMath.hpp b/GridKit/CommonMath.hpp index e4a7ec87f..db6cab1cb 100644 --- a/GridKit/CommonMath.hpp +++ b/GridKit/CommonMath.hpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace GridKit @@ -34,7 +35,7 @@ namespace GridKit * @return value of the sigmoid function */ template - __attribute__((always_inline)) inline ScalarT sigmoid(const ScalarT x) + FORCE_INLINE ScalarT sigmoid(const ScalarT x) { using RealT = typename GridKit::ScalarTraits::RealT; return HALF * (ONE + std::tanh(HALF * MU * x)); @@ -52,7 +53,7 @@ namespace GridKit * @return value of the smooth ramp function */ template - __attribute__((always_inline)) inline ScalarT ramp(const ScalarT x) + FORCE_INLINE ScalarT ramp(const ScalarT x) { using RealT = typename GridKit::ScalarTraits::RealT; @@ -76,7 +77,7 @@ namespace GridKit * @return value of the quadratic ramp */ template - __attribute__((always_inline)) inline ScalarT qramp(const ScalarT x) + FORCE_INLINE ScalarT qramp(const ScalarT x) { return x * x * sigmoid(x); } @@ -101,7 +102,7 @@ namespace GridKit * forcing callers to cast every parameter. */ template - __attribute__((always_inline)) inline auto max( + FORCE_INLINE auto max( const LeftT x, const RightT y) { @@ -128,7 +129,7 @@ namespace GridKit * forcing callers to cast every parameter. */ template - __attribute__((always_inline)) inline auto min( + FORCE_INLINE auto min( const LeftT x, const RightT y) { @@ -152,7 +153,7 @@ namespace GridKit * @return value of the smooth clamp function */ template - __attribute__((always_inline)) inline auto clamp( + FORCE_INLINE auto clamp( const ScalarT x, const LowerT lower, const UpperT upper) @@ -176,7 +177,7 @@ namespace GridKit * @return Smooth deadbanded value */ template - __attribute__((always_inline)) inline ScalarT deadband( + FORCE_INLINE ScalarT deadband( const ScalarT x, const RealT lower, const RealT upper) @@ -198,7 +199,7 @@ namespace GridKit * @return Slew-rate-limited value of f */ template - __attribute__((always_inline)) inline ScalarT slew( + FORCE_INLINE ScalarT slew( const ScalarT f, const RealT rate) { @@ -223,7 +224,7 @@ namespace GridKit * @return Smooth linear segment contribution */ template - __attribute__((always_inline)) inline ScalarT linseg( + FORCE_INLINE ScalarT linseg( const ScalarT x, const RealT lower, const RealT upper, @@ -244,7 +245,7 @@ namespace GridKit * @return Smooth indicator that x is above limit_min */ template - __attribute__((always_inline)) inline ScalarT above( + FORCE_INLINE ScalarT above( const ScalarT x, const RealT limit_min) { @@ -262,7 +263,7 @@ namespace GridKit * @return Smooth indicator that x is below limit_max */ template - __attribute__((always_inline)) inline ScalarT below( + FORCE_INLINE ScalarT below( const ScalarT x, const RealT limit_max) { @@ -281,7 +282,7 @@ namespace GridKit * @return Smooth indicator that x is inside [limit_min, limit_max] */ template - __attribute__((always_inline)) inline ScalarT inside( + FORCE_INLINE ScalarT inside( const ScalarT x, const RealT limit_min, const RealT limit_max) @@ -302,7 +303,7 @@ namespace GridKit * @return Smooth indicator that x is outside [limit_min, limit_max] */ template - __attribute__((always_inline)) inline ScalarT outside( + FORCE_INLINE ScalarT outside( const ScalarT x, const RealT limit_min, const RealT limit_max) @@ -325,7 +326,7 @@ namespace GridKit * 0 when integration should be blocked. */ template - __attribute__((always_inline)) inline ScalarT indicator( + FORCE_INLINE ScalarT indicator( const ScalarT x, const ScalarT f, const RealT limit_min, @@ -359,7 +360,7 @@ namespace GridKit * @return Smooth anti-windup limited derivative */ template - __attribute__((always_inline)) inline ScalarT antiwindup( + FORCE_INLINE ScalarT antiwindup( const ScalarT x, const ScalarT f, const RealT limit_min, diff --git a/GridKit/Definitions.hpp.in b/GridKit/Definitions.hpp.in index 10215709d..2c979ecb7 100644 --- a/GridKit/Definitions.hpp.in +++ b/GridKit/Definitions.hpp.in @@ -10,3 +10,11 @@ #define GRIDKIT_VERSION_MAJOR "@GridKit_VERSION_MAJOR@" #define GRIDKIT_VERSION_MINOR "@GridKit_VERSION_MINOR@" #define GRIDKIT_VERSION_PATCH "@GridKit_VERSION_PATCH@" + +#if defined(__MINGW32__) || defined(__clang__) || defined(__GNUC__) + #define FORCE_INLINE __attribute__((always_inline)) inline +#elif defined(_MSC_VER) + #define FORCE_INLINE [[msvc::forceinline]] inline +#else + #define FORCE_INLINE __attribute__((always_inline)) inline +#endif diff --git a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp index 84149f8a4..02a1817a0 100644 --- a/GridKit/Model/PhasorDynamics/Branch/Branch.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/Branch.hpp @@ -134,17 +134,17 @@ namespace GridKit typename ModelDataT::Parameters parameter, RealT& target); - static __attribute__((always_inline)) inline void addAdmittanceContribution(RealT G, - RealT B, - const ScalarT& Vr, - const ScalarT& Vi, - ScalarT& Ir, - ScalarT& Ii); - - static __attribute__((always_inline)) inline void evaluateAdmittanceBlock(RealT G, - RealT B, - const ScalarT* wb, - ScalarT* h); + static FORCE_INLINE void addAdmittanceContribution(RealT G, + RealT B, + const ScalarT& Vr, + const ScalarT& Vi, + ScalarT& Ir, + ScalarT& Ii); + + static FORCE_INLINE void evaluateAdmittanceBlock(RealT G, + RealT B, + const ScalarT* wb, + ScalarT* h); ScalarT& Vr1() { @@ -187,10 +187,10 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateBusResidual11(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual12(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual21(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual22(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual11(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual12(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual21(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual22(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: BusT* bus1_; diff --git a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp index 1fe3977f0..05d750e4d 100644 --- a/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Branch/BranchImpl.hpp @@ -174,7 +174,7 @@ namespace GridKit } template - __attribute__((always_inline)) inline void Branch::addAdmittanceContribution( + FORCE_INLINE void Branch::addAdmittanceContribution( RealT G, RealT B, const ScalarT& Vr, @@ -187,7 +187,7 @@ namespace GridKit } template - __attribute__((always_inline)) inline void Branch::evaluateAdmittanceBlock( + FORCE_INLINE void Branch::evaluateAdmittanceBlock( RealT G, RealT B, const ScalarT* wb, @@ -205,7 +205,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Branch::evaluateBusResidual11( + FORCE_INLINE int Branch::evaluateBusResidual11( [[maybe_unused]] ScalarT* y, [[maybe_unused]] ScalarT* yp, ScalarT* wb, @@ -221,7 +221,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Branch::evaluateBusResidual12( + FORCE_INLINE int Branch::evaluateBusResidual12( [[maybe_unused]] ScalarT* y, [[maybe_unused]] ScalarT* yp, ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp b/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp index 3b559fd1b..63d408877 100644 --- a/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp +++ b/GridKit/Model/PhasorDynamics/BusFault/BusFault.hpp @@ -110,7 +110,7 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: BusT* bus_; diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp index add41ad66..4bcc81302 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1.hpp @@ -122,7 +122,7 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: // Signal pointers diff --git a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp index c055ad6b4..f844257bd 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/IEEET1/Ieeet1Impl.hpp @@ -279,7 +279,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Ieeet1::evaluateInternalResidual( + FORCE_INLINE int Ieeet1::evaluateInternalResidual( ScalarT* y, ScalarT* yp, ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp index 56f5667d0..832109da8 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPti.hpp @@ -103,7 +103,7 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual( + FORCE_INLINE int evaluateInternalResidual( ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: diff --git a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp index e0de70fea..b3fc1787f 100644 --- a/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Exciter/SEXS-PTI/SexsPtiImpl.hpp @@ -181,7 +181,7 @@ namespace GridKit } template - __attribute__((always_inline)) inline int SexsPti::evaluateInternalResidual( + FORCE_INLINE int SexsPti::evaluateInternalResidual( ScalarT* y, ScalarT* yp, ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp index f8ceb7207..9c67561df 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1.hpp @@ -109,7 +109,7 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: // Input parameters diff --git a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp index 29c4b07bd..cad6312f9 100644 --- a/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp +++ b/GridKit/Model/PhasorDynamics/Governor/Tgov1/Tgov1Impl.hpp @@ -237,7 +237,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Tgov1::evaluateInternalResidual( + FORCE_INLINE int Tgov1::evaluateInternalResidual( ScalarT* y, ScalarT* yp, [[maybe_unused]] ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/Load/Load.hpp b/GridKit/Model/PhasorDynamics/Load/Load.hpp index 33ce3cc1e..93803ef87 100644 --- a/GridKit/Model/PhasorDynamics/Load/Load.hpp +++ b/GridKit/Model/PhasorDynamics/Load/Load.hpp @@ -110,8 +110,8 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; public: - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/LoadZIP/LoadZIP.hpp b/GridKit/Model/PhasorDynamics/LoadZIP/LoadZIP.hpp index ebe3a9be2..da7018f48 100644 --- a/GridKit/Model/PhasorDynamics/LoadZIP/LoadZIP.hpp +++ b/GridKit/Model/PhasorDynamics/LoadZIP/LoadZIP.hpp @@ -124,8 +124,8 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; public: - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: BusT* bus_{nullptr}; diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp index 486f1820b..c6adac551 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/Ieeest.hpp @@ -110,7 +110,7 @@ namespace GridKit const Model::VariableMonitorBase* getMonitor() const override; - __attribute__((always_inline)) inline int evaluateInternalResidual( + FORCE_INLINE int evaluateInternalResidual( ScalarT*, ScalarT*, [[maybe_unused]] ScalarT*, diff --git a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp index 70b49977d..66d23d245 100644 --- a/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp +++ b/GridKit/Model/PhasorDynamics/Stabilizer/IEEEST/IeeestImpl.hpp @@ -244,7 +244,7 @@ namespace GridKit } template - __attribute__((always_inline)) inline int Ieeest::evaluateInternalResidual( + FORCE_INLINE int Ieeest::evaluateInternalResidual( ScalarT* y, ScalarT* yp, [[maybe_unused]] ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp index 73b6f764d..88464ee50 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/Genrou.hpp @@ -205,8 +205,8 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp index 9cbb0b587..4fd46a2a8 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENROUwS/GenrouImpl.hpp @@ -528,7 +528,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Genrou::evaluateInternalResidual( + FORCE_INLINE int Genrou::evaluateInternalResidual( ScalarT* y, ScalarT* yp, ScalarT* wb, @@ -606,7 +606,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Genrou::evaluateBusResidual( + FORCE_INLINE int Genrou::evaluateBusResidual( ScalarT* y, [[maybe_unused]] ScalarT* yp, ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/Gensal.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/Gensal.hpp index 8e00fc2e8..3ef0626d9 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/Gensal.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/Gensal.hpp @@ -169,8 +169,8 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: /* Identification */ diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/GensalImpl.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/GensalImpl.hpp index 9b779ded5..1e511a70d 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/GensalImpl.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GENSALwS/GensalImpl.hpp @@ -351,7 +351,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Gensal::evaluateInternalResidual( + FORCE_INLINE int Gensal::evaluateInternalResidual( ScalarT* y, ScalarT* yp, ScalarT* wb, @@ -422,7 +422,7 @@ namespace GridKit * */ template - __attribute__((always_inline)) inline int Gensal::evaluateBusResidual( + FORCE_INLINE int Gensal::evaluateBusResidual( ScalarT* y, [[maybe_unused]] ScalarT* yp, ScalarT* wb, diff --git a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp index a2696fc0d..87c4615fc 100644 --- a/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp +++ b/GridKit/Model/PhasorDynamics/SynchronousMachine/GenClassical/GenClassical.hpp @@ -144,8 +144,8 @@ namespace GridKit } public: - __attribute__((always_inline)) inline int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); - __attribute__((always_inline)) inline int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateInternalResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); + FORCE_INLINE int evaluateBusResidual(ScalarT*, ScalarT*, ScalarT*, ScalarT*); private: /* Identification */ diff --git a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp index 000238b20..017c1f0f1 100644 --- a/GridKit/Utilities/CliArgs/CliArgsImpl.hpp +++ b/GridKit/Utilities/CliArgs/CliArgsImpl.hpp @@ -241,7 +241,11 @@ namespace GridKit void CliArgsImpl::parseArgs(int argc, const char* argv[]) { - app_name_ = std::filesystem::path(argv[0]).filename(); +#if defined(_WIN32) + app_name_ = std::filesystem::path(argv[0]).filename().string(); +#else + app_name_ = std::filesystem::path(argv[0]).filename(); +#endif bool status = true; // Current argument (may involve multiple tokens) diff --git a/GridKit/Utilities/String.hpp b/GridKit/Utilities/String.hpp index 26e0d39e0..13c4ecfb4 100644 --- a/GridKit/Utilities/String.hpp +++ b/GridKit/Utilities/String.hpp @@ -12,7 +12,7 @@ namespace GridKit /** * @brief Convert a string to all uppercase */ - std::string toUpper(std::string str) + inline std::string toUpper(std::string str) { std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::toupper(c); });