by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Matthias Moulin
    @matt77hias
    Unfortunately, this is the reality on Windows :( (if std::filesystem::path would use UTF8 instead of UTF16, I wouldn't need the multi-byte strings at all).
    And all other Windows APIs requiring wchar_t* filenames as well.
    Matthias Moulin
    @matt77hias
    No idea what that PR is talking about. Why can't the formatter not handle the type directly (the formatters that I provided, seem to handle all cases)? Furthermore, between char and wchar_t there are basically four combinations of format and format arguments, why does only one of them not work anymore as intended?
    Victor Zverovich
    @vitaut
    I'm not sure why only one specialization is not working. If you are willing to debug and submit a PR I'll be happy to merge it in even though as I wrote before the recommended solution is to introduce types to do transconding explicitly. A common practice is to use UTF-8 internally and only transcode at WinAPI boundaries.
    Matthias Moulin
    @matt77hias
    Unfortunately, std::filesystem already crosses the WinAPI boundary (character type is OS dependent). I understand that explicitizing the conversions results in a neater design, but on the other hand the formatter specializations are somewhat explicit as well. Though, they target all (common) conversions indirectly vs one particular conversion directly. In that sense, it seems imho better to introduce a separate intermediary class for explicit non-common conversions as opposed to all conversions (e.g., why is the type std::string treated different from std::vector for formatting wchar_t streams? Both are just types for which the user needs to handle the formatting).
    Victor Zverovich
    @vitaut
    Not sure I understand your suggestion about intermediary class for non-common conversions. std::string is different from std::vector because the former have an well-established output format while the latter doesn't. There are some facilities to format containers in fmt/ranges.h though.
    Matthias Moulin
    @matt77hias
    But std::string does not have a well-established output form for an UTF16 output iterator, and a std::wstring does not have a well-established output form for an UTF8 output iterator. So I do not see the differences with an arbitrary user-defined type Widget (e.g., container).
    With non-common, I just refer to the same thing you proposed above (i.e. utf8): format("{}", NonCommonType(L"...")) + formatter specialization for NonCommonType.
    Victor Zverovich
    @vitaut
    Sure, that's why I'm open to a PR to make specialization of formatter for non-native string types possible although I'd recommend the non-common approach.
    Matthias Moulin
    @matt77hias
    I recommend the non-common approach as well if and only if the common case cannot be handled properly while still using the common case for the majority. The elegancy of fmt is the possibility to pass whatever arguments you want compared to printf's fixed number of types, but somehow using a wrapper for some arguments feels like going back to printf (irrespective of whether an automatic conversion could be error-prone in some non-common cases).
    Germán Méndez Bravo
    @Kronuz
    I'm using fmt 5.2.1, but simply including it and doing some simple print takes vary long to compile... what makes the compilation so slow?
    Victor Zverovich
    @vitaut
    Make sure to use the core API that is optimized for compile time: http://fmtlib.net/latest/api.html#core-api
    Mateusz Janek
    @stryku
    Hello, which clang-format version does fmt use?
    Victor Zverovich
    @vitaut
    {fmt} doesn't use clang-format, but the coding conventions are described in https://github.com/fmtlib/fmt/blob/master/CONTRIBUTING.rst
    Mateusz Janek
    @stryku
    Yes, I saw that. Well, that explains a lot, thanks (:
    devhandle
    @devhandle
    Hi -I've just started using fmt in spdlog. Is there are a way to set a width of a string which will truncate the contents if it's > width. I'm using "{:<30}" but the string is not being truncated. thanks
    Mateusz Janek
    @stryku

    Hi, have you tried with precision?

    For non-number types the field indicates the maximum field size - in other words, how many characters will be used from the field content.

    Try {:.30}

    devhandle
    @devhandle
    Thanks @stryku, that works great.
    Mateusz Janek
    @stryku
    Np, glad to hear
    Dirk Van Haerenborgh
    @vhdirk
    Hi guys
    is it possible to specify the 'precision/width' of a string field but overflow on the left part?
    Using {:.30s} will always trim the tail. adding the alignment operator just aligns the field after it's been trimmed {:>.30s}
    Victor Zverovich
    @vitaut
    No, but it's possible to do by removing a prefix from a string view, something like:
    std::string_view s = ...
    if (s.size() > 30) s.remove_prefix(s.size() - 30);
    and formatting the resulting string view if needed.
    Dirk Van Haerenborgh
    @vhdirk
    @vitaut thanks, but that would mean that I'd have to do that in code, rather than in the formatter string
    Victor Zverovich
    @vitaut
    Yes. alternatively you could write a custom formatter, but that's probably an overkill.
    Patrick Bos
    @egpbos
    hey, i'm working on a multi-process code from which i want to print diagnostic stuff to stdout, and it's quite a lot, so output from different processes is getting mixed up
    i was naively hoping that i could control std::cout's buffer size, but apparently this is an implementation detail and in any case not part of the standard
    so i'm wondering: can fmt help me here?
    do you have / know of examples of using fmt in a multi-process environment?
    note: not multi-threaded, so no shared memory, though I am able to communicate between processes, but would rather not, as I'm doing performance critical stuff
    Patrick Bos
    @egpbos
    the simplest thing i could think of is to just have an adjustable size buffer which i could then tune to only output stuff from each process after some specified criterium to make sure that no output gets scattered across buffer flushes as is happening now
    i guess the easiest would be to just flush after every line, but i'm afraid that would impact my performance too much
    and also, i'm just looking for a good excuse to try out fmt :D
    Victor Zverovich
    @vitaut
    Unfortunately, I don't have any examples how to prevent mixing of output from multiple processes. fmt::print writes the whole message atomically (using one call to the underlying system function), which prevents mixing parts of messages within the process, but I'm not sure if it helps with multiple processes.
    Patrick Bos
    @egpbos
    ok, thx for your response!
    genuine_
    @blaquee
    you might need to implement some internal lock mechanism
    but it would probably throttle output
    Patrick Bos
    @egpbos
    yeah, that's not good
    i think ideally i'd have a separate process that handles output, to which other processes send their output, via a block of shared memory to prevent copies
    but this is a bit outside of the scope of my project ;)
    Vladyslav
    @vtronko

    Hello, people. How is your day?
    Can I get an aid with my problem? I want compile-time checks of parameters correctness (number of param mismatch etc.) with syntax like fmt::format("The answer is {:d}", "forty-two");. Is that possible? From website I only see alternative format(fmt kind of syntax that switches to compile time checks instead of throwing exceptions.
    I tried DCMAKE_FMT_PEDANTIC=ONdidn't seem to help on both gcc and clang, probably it's doing not what I thought it would.

    Reason to do this is to have compile-time checks for another library that uses fmt (named spdlog) while not changing anything on spdlog side...
    I promise I did research myself prior to asking here, sorry for any trouble. I hope someone else had solution for this, spdlog seems to be quite popular and is mentioned in readme as a fellow library.

    Victor Zverovich
    @vitaut
    You need to wrap the format string in the fmt (or FMT_STRING) macro as described in http://fmtlib.net/latest/api.html#compile-time-format-string-checks
    Vladyslav
    @vtronko
    Thank you. I assumed that's for calming down MSVC, that's what I read in a particular paragraph on your old blog post.
    std branch being only branch with this feature enabled is no more actual?
    I didn't know fmt and FMT_STRING effect is in fact equal when it comes to aiming for compile time checks.
    Now it is all clear to me. Thank you again, Victor.
    Victor Zverovich
    @vitaut
    Compile-time checks are in {fmt} since version 5.0, not only in the std branch. Macros are unfortunately the only portable way to have compile-time strings.
    jbeach
    @jasonbeach
    I'm trying to implement a formatter for a couple of user defined types (namely a Point type (struct with 3 doubles)and a Polygon type which is a std::vector<Point>). I have them both working, but am not sure the one for polygon is implemented as efficiently as it could be:
    template <>
    struct formatter<Polygon> {
      template <typename ParseContext>
      constexpr auto parse(ParseContext &ctx) { return ctx.begin(); }
    
      template <typename FormatContext>
      auto format(const Polygon &p,
        FormatContext &ctx)
      {
        fmt::memory_buffer out;
        bool is_first = true;
        for (auto& vertice : p.vertices)
        {
          if(is_first)
          {
            format_to(out, "{}", vertice);
            is_first = false;
          }
          else
          {
            format_to(out, ", {}", vertice);
          }
        }
        return format_to(ctx.begin(), "{}", to_string(out));
      }
    };
    }
    Is there a better way?
    Victor Zverovich
    @vitaut
    You could make it more efficient by writing directly to the output iterator ctx.out() instead of intermediate buffer.
    jbeach
    @jasonbeach

    So something like:

      template <typename FormatContext>
      auto format(const Polygon &p,
        FormatContext &ctx)
      {
        //fmt::memory_buffer out;
        bool is_first = true;
        for (auto& vertice : p.vertices)
        {
          if(is_first)
          {
            format_to(ctx.begin(), "{}", vertice);
            is_first = false;
          }
          else
          {
            format_to(ctx.begin(), ", {}", vertice);
          }
        }
        return ctx.begin();
      }

    Seems much better. Thanks!