Skip to content

Commit

Permalink
Merge pull request xbmc#18216 from Paxxi/fix_enum_backport
Browse files Browse the repository at this point in the history
Fix enum formatting for libfmt 6 [backport]
  • Loading branch information
DaveTBlake authored Jul 27, 2020
2 parents acbb816 + 1e4e926 commit 45686bd
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
27 changes: 23 additions & 4 deletions xbmc/utils/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ DEF_TO_STR_VALUE(foo) // outputs "4"
#define DEF_TO_STR_NAME(x) #x
#define DEF_TO_STR_VALUE(x) DEF_TO_STR_NAME(x)

template< bool B, class T = void >
using enable_if_t = typename std::enable_if<B,T>::type;

template< class T > struct remove_rvalue_reference {typedef T type;};
template< class T > struct remove_rvalue_reference<T&> {typedef T& type;};
template< class T > struct remove_rvalue_reference<T*> {typedef T* type;};
template< class T > struct remove_rvalue_reference<T&&> {typedef T type;};

template<typename T, enable_if_t<!std::is_enum<T>::value, int> = 0>
constexpr auto EnumToInt(T&& arg) noexcept -> typename remove_rvalue_reference<decltype(arg)>::type
{
return arg;
}
template<typename T, enable_if_t<std::is_enum<T>::value, int> = 0>
constexpr auto EnumToInt(T&& arg) noexcept -> int
{
return static_cast<int>(arg);
}

class StringUtils
{
public:
Expand All @@ -69,19 +88,19 @@ class StringUtils
static std::string Format(const std::string& fmt, Args&&... args)
{
// coverity[fun_call_w_exception : FALSE]
auto result = ::fmt::format(fmt, std::forward<Args>(args)...);
auto result = ::fmt::format(fmt, EnumToInt(std::forward<Args>(args))...);
if (result == fmt)
result = ::fmt::sprintf(fmt, std::forward<Args>(args)...);
result = ::fmt::sprintf(fmt, EnumToInt(std::forward<Args>(args))...);

return result;
}
template<typename... Args>
static std::wstring Format(const std::wstring& fmt, Args&&... args)
{
// coverity[fun_call_w_exception : FALSE]
auto result = ::fmt::format(fmt, std::forward<Args>(args)...);
auto result = ::fmt::format(fmt, EnumToInt(std::forward<Args>(args))...);
if (result == fmt)
result = ::fmt::sprintf(fmt, std::forward<Args>(args)...);
result = ::fmt::sprintf(fmt, EnumToInt(std::forward<Args>(args))...);

return result;
}
Expand Down
55 changes: 55 additions & 0 deletions xbmc/utils/test/TestStringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@

#include "gtest/gtest.h"

enum class ECG
{
A,
B
};

enum EG
{
C,
D
};

namespace test_enum
{
enum class ECN
{
A = 1,
B
};
enum EN
{
C = 1,
D
};
}

TEST(TestStringUtils, Format)
{
std::string refstr = "test 25 2.7 ff FF";
Expand All @@ -22,6 +48,35 @@ TEST(TestStringUtils, Format)
EXPECT_STREQ("", varstr.c_str());
}

TEST(TestStringUtils, FormatEnum)
{
const char* zero = "0";
const char* one = "1";

std::string varstr = StringUtils::Format("{}", ECG::A);
EXPECT_STREQ(zero, varstr.c_str());

varstr = StringUtils::Format("{}", EG::C);
EXPECT_STREQ(zero, varstr.c_str());

varstr = StringUtils::Format("{}", test_enum::ECN::A);
EXPECT_STREQ(one, varstr.c_str());

varstr = StringUtils::Format("{}", test_enum::EN::C);
EXPECT_STREQ(one, varstr.c_str());
}

TEST(TestStringUtils, FormatEnumWidth)
{
const char* one = "01";

std::string varstr = StringUtils::Format("{:02d}", ECG::B);
EXPECT_STREQ(one, varstr.c_str());

varstr = StringUtils::Format("%02d", EG::D);
EXPECT_STREQ(one, varstr.c_str());
}

TEST(TestStringUtils, ToUpper)
{
std::string refstr = "TEST";
Expand Down

0 comments on commit 45686bd

Please sign in to comment.