tpecholt / imrad

ImRAD is a GUI builder for the ImGui library
GNU General Public License v3.0
915 stars 29 forks source link

ImRad::Format causing trouble at compilation! #31

Closed GetRektBoy724 closed 4 months ago

GetRektBoy724 commented 4 months ago

The Format function on the ImRad class inside the ImRad header is causing problem at compilation. Exactly at line 339, at the std::to_string call, the error is 'std::to_string': no overloaded function could convert all the argument types and I have no idea how to fix it, could someone help me on this? I just added this to a fresh VS C++ project, with SDL disabled C++17, and including the ImGui lib. Thanks!

std::string Format(std::string_view fmt, A1&& arg, A&&... args)
{
#ifdef IMRAD_WITH_FMT
    return fmt::format(fmt, std::forward<A1>(arg), std::forward<A>(args)...);
#else
    //todo
    std::string s;
    for (size_t i = 0; i < fmt.size(); ++i)
    {
        if (fmt[i] == '{') {
            if (i + 1 == fmt.size())
                break;
            if (fmt[i + 1] == '{')
                s += '{';
            else {
                auto j = fmt.find('}', i + 1);
                if (j == std::string::npos)
                    break;
                if constexpr (std::is_same_v<std::decay_t<A1>, std::string>)
                    s += arg;
                else if constexpr (std::is_same_v<std::decay_t<A1>, const char*>)
                    s += arg;
                else if constexpr (std::is_same_v<std::decay_t<A1>, char>)
                    s += arg;
                else
                    s += std::to_string(arg);
                return s + Format(fmt.substr(j + 1), args...);
            }
        }
        else
            s += fmt[i];
    }
    return s;
#endif
}
websecnl commented 4 months ago

Same issue here please fix

tpecholt commented 4 months ago

Are you trying to build ImRAD itself or some app with ImRAD-generated code? What VS version do you use?

The ImRad::Format function in question is a template so the error depends on the types of the parameters used at a call site. Can you post the exact source location and/or types of the parameters of the Format call so I can see what is causing the issue?

(I am not sure what "SDL disabled C++17" means. Probably you are not referring to SDL library which is not currently supported by ImRAD)

GetRektBoy724 commented 4 months ago

I'm trying to build an app from ImRAD-generated code, I use VS 2022, and I use PCHAR type for the ImRad::Format function parameter. SDL that I refer to is the Software Development Lifecycle check in the project settings. These are the calls to the Format function looks like. ImGui::Button(ImRad::Format("{}", ETWTI_SwitchValue).c_str(), { 0, 0 }); ImGui::TextUnformatted(ImRad::Format("{}", HVCI_Status).c_str());

tpecholt commented 4 months ago

Okay and what is the type of ETWTI_SwitchValue and HVCI_Status? Is it possibly signed/unsigned char or other type not currently handled by the Format?

GetRektBoy724 commented 4 months ago

Okay and what is the type of ETWTI_SwitchValue and HVCI_Status? Is it possibly signed/unsigned char or other type not currently handled by the Format?

It is both PCHAR, or char pointer essentially. Why don't we just use sprintf or something like that for the Format routine?

tpecholt commented 4 months ago

So that is rather simple. I pushed the fix for PCHAR. I assume it is null terminated string not a pointer to char-sized variable.

Why don't we just use sprintf or something like that for the Format routine?

printf family functions have long standing issues. For example if a sprintf call refers to a variable whose type changes during refactoring it may go unnoticed and lead to a crash because the incorrect type specifier remains in the formatting string. Printf format is also not easily extensible to named parameters which are used in ImRAD.

For these and other reasons c++20 comes with std::format which is a replacement of sprintf. ImRAD follows it except it currently doesn't call std::format directly as it is still not universally implemented by all standard libraries currently in use. I should add conditional include for it. Even today you can however compile with IMRAD_WITH_FMT and Format will forward to the popular fmt library which is the same thing.

GetRektBoy724 commented 4 months ago

I see, well, thanks for the help, I'll update the code with the latest ImRAD header, thanks for the help!