Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Victor Zverovich
    @vitaut
    So I'm open to pull requests if this can be done in the form args{{"name", "World"}, {"number", 42"} or similar rather than just a single list.
    lyngklip
    @lyngklip
    First: good job on this library. I'm learning a lot.
    Now for a "thing" I found: I tried to combine format_to_n with a back_insert_iterator and got the compilation error "invalid use of 'std::__iterator_traits ... yadayada.. ::value_type {aka void}'.
    I think the issue is that (quote from cppreference): "Pure output-only iterator is allowed to declare its iterator_traits<X>::value_type [and others] to be void (and iterators such as std::back_insert_iterator do just that)."
    I didn't check trunk, I'm on 5.2.0.
    valuetype is used for declaring blackhole in the truncating iterator. (Underscore does things with the text, sorry)
    lyngklip
    @lyngklip
    value_type is used for declaring blackhole_ in the truncating iterator...
    there you go
    Victor Zverovich
    @vitaut
    Good catch! It should be easy to fix by passing the character type as an extra parameter to truncating_iterator. PRs are welcome =)
    lyngklip
    @lyngklip
    I had it working by rewriting the ++, --, * operators and adding a = operator so the truncating_iterator works more like a back_inserting_iterator, but I didn't test with plain pointers, and I I'm not quite sure what I'm doing, so...
    lyngklip
    @lyngklip
    ++(), --(), and *() for back_inserting_iterator do nothing and =() calls push_back, so the assignment actually advances the underlying iterator. I did similarly for the truncating_iterator so that --(), ++(), and *() do nothing but return *this, and assignment assigns to - and increments - the underlying iterator - if count hasn't reached limit yet. Something like if (count++ < limit) *out_++ = value;. As a template function, to avoid the issue of value_type. I'll see if I can figure out how to make a PR.
    lyngklip
    @lyngklip
    I realize that what I just wrote doesn't make sense, because back_insert_iterator doesn't have an underlying iterator. Also, if fmtlib assigns twice without advancing the iterator, my solution will fail because it will advance the iterator implicitly.
    lyngklip
    @lyngklip
    fmtlib mistakenly assumes std::strlen is constexpr for an ARM toolchain. I just removed the constexpr for the length() function.
    Victor Zverovich
    @vitaut
    What gcc version do you use?
    lyngklip
    @lyngklip
    It's a 6.3.1 that I got from https://developer.arm.com/open-source/gnu-toolchain/gnu-rm over a year back.
    Victor Zverovich
    @vitaut
    Hmm, this is relatively new version, so it looks like an ARM toolchain thing. Is __arm__ a good macro to check?
    lyngklip
    @lyngklip
    I guess, but your guess is better than mine.
    Victor Zverovich
    @vitaut
    Should be fixed in fmtlib/fmt#889
    Rodelle Ladia
    @rLadia
    Awesome library! I was wondering if there's a way to override the on_error behavior so that I can replace the invalid format code with an empty string instead of throwing an exception.
    Victor Zverovich
    @vitaut
    Thanks! The error handling is not yet customizable via the public API but you can wrap a formatting function (such as vformat), intercept an exception and return an empty string instead.
    Marius Elvert
    @ltjax
    Hello. Is there a way to feed a dynamic number of args to fmt::format ?
    I have a format string and a std::vector of strings that I like to use for my args
    Alex Dalshov
    @myrgy
    you may write you own formatter for std::vector with some special delimiters and pass it to the fmt
    Marius Elvert
    @ltjax
    Thanks, but I am not sure how that helps - isn't that more for when I want my vector of strings to replace a single placeholder in my format string?
    Victor Zverovich
    @vitaut
    Yes, fmt/ranges.h is useful when you want to format a vector. For dynamic arguments take a look at fmtlib/fmt#819.
    Andrew
    @randrewy
    Hello! I have kinda a similar question to Rodel's one. Have you ever considered a non-aborting mode for library when you neither throw nor abort. Because when code compiles without exception support there is no way to intercept an assert.
    The idea is to swallow errors (and may be report them via some custom channel) and never chash
    Andrew
    @randrewy
    btw, can tests be run with disabled exceptions?
    Victor Zverovich
    @vitaut
    In theory you can define FMT_THROW to something other than abort or throw, but it might require more work to get rid of noreturn assumptions in a few places. PRs are welcome =).
    Tests do require exceptions I believe.
    Andrew
    @randrewy
    Good, thanks, I'll try it and make a PR if the result will be functional :)
    Matthias Moulin
    @matt77hias
    Hey, the latest release is from Sep 21. I updated my {fmt}/master from September 22 (should be pretty similar to latest release) to November 16, but my code base no longer compiles. Are there any major possibly breaking design decisions in between?
    An apparent change is the replacement of the FMT_MAKE_VALUE macro with the make_value.
    Victor Zverovich
    @vitaut
    What code doesn't compile and what is the error message?
    Matthias Moulin
    @matt77hias
    Basically, the static_assert's condition of make_value
    is false. Probably, due to some wchar_t to char conversion that I need to look further into (but msvc++ is not that helpful in case of lots of template chains). So it would be helpful to know if fmt changed the API in some way, especially with regard to the formatter specializations?
    Matthias Moulin
    @matt77hias
    Or if you advise to not use the master branch, I'll just revert to the latest release?
    Matthias Moulin
    @matt77hias
    I created a separate Godbolt example (https://godbolt.org/z/dfxuOL) that does not compile with the current trunk, but compiles with the latest release. Without digging deeper into my code base^^, I am quite certain I have the same problem.
    And to support minimal reading: https://godbolt.org/z/CEit-x
    Victor Zverovich
    @vitaut
    I wouldn't recommend such implicit mixing of multi-byte and wide strings. If you want the conversion it's better to introduce a new type that does it and specialize formatter for this type. Something along the lines of format("{}", utf8(L"...")).
    Victor Zverovich
    @vitaut
    That said, here's the PR that changed likely affected the behavior: fmtlib/fmt#907
    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?