Comments (8)
Or is it unrelated?
This is a different to #3800
from fmt.
Changing the signature of formatter<join_view>::format
to
template <typename FormatContext>
auto format(join_view<It, Sentinel, Char>& value,
FormatContext& ctx) const -> decltype(ctx.out())
(that is, removing the const
from the join_view
argument) generates the following from Clang:
/Users/tristan/Coding/fmt/include/fmt/base.h:1522:63: error: implicit instantiation of undefined template 'fmt::detail::type_is_unformattable_for<const fmt::join_view<unsigned char *, unsigned char *>, char>'
1522 | type_is_unformattable_for<T, typename Context::char_type> _;
| ^
/Users/tristan/Coding/fmt/include/fmt/base.h:1908:20: note: in instantiation of function template specialization 'fmt::detail::make_arg<true, fmt::generic_context<std::back_insert_iterator<std::string>, char>, const fmt::join_view<unsigned char *, unsigned char *>, 0>' requested here
1908 | return {{detail::make_arg<NUM_ARGS <= detail::max_packed_args, Context>(
| ^
/Users/tristan/Coding/fmt/include/fmt/compile.h:201:14: note: in instantiation of function template specialization 'fmt::make_format_args<fmt::generic_context<std::back_insert_iterator<std::string>, char>, const fmt::join_view<unsigned char *, unsigned char *>, 1UL, 0UL, 15ULL, 0>' requested here
201 | fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
| ^
/Users/tristan/Coding/fmt/include/fmt/compile.h:438:6: note: in instantiation of function template specialization 'fmt::detail::spec_field<char, fmt::join_view<unsigned char *, unsigned char *>, 0>::format<std::back_insert_iterator<std::string>, fmt::join_view<unsigned char *, unsigned char *>>' requested here
438 | cf.format(std::back_inserter(s), args...);
| ^
/Users/tristan/Coding/fmt/include/fmt/compile.h:472:17: note: in instantiation of function template specialization 'fmt::format<fmt::detail::spec_field<char, fmt::join_view<unsigned char *, unsigned char *>, 0>, fmt::join_view<unsigned char *, unsigned char *>, char, 0>' requested here
472 | return fmt::format(compiled, std::forward<Args>(args)...);
| ^
/Users/tristan/Coding/fmt/test/compile-test.cc:185:28: note: in instantiation of function template specialization 'fmt::format<FMT_COMPILE_STRING, fmt::join_view<unsigned char *, unsigned char *>, 0>' requested here
185 | EXPECT_EQ("0102af", fmt::format(FMT_COMPILE("{:02x}"), fmt::join(data, "")));
| ^
/Users/tristan/Coding/fmt/include/fmt/base.h:1497:8: note: template is declared here
1497 | struct type_is_unformattable_for;
| ^
/Users/tristan/Coding/fmt/include/fmt/base.h:1525:7: error: static assertion failed due to requirement 'formattable': Cannot format an argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#udt
1525 | formattable,
| ^~~~~~~~~~~
In file included from /Users/tristan/Coding/fmt/test/compile-test.cc:8:
/Users/tristan/Coding/fmt/include/fmt/compile.h:203:16: error: no matching member function for call to 'format'
203 | return fmt.format(get_arg_checked<T, N>(args...), ctx);
| ~~~~^~~~~~
/Users/tristan/Coding/fmt/include/fmt/compile.h:438:6: note: in instantiation of function template specialization 'fmt::detail::spec_field<char, fmt::join_view<unsigned char *, unsigned char *>, 0>::format<std::back_insert_iterator<std::string>, fmt::join_view<unsigned char *, unsigned char *>>' requested here
438 | cf.format(std::back_inserter(s), args...);
| ^
/Users/tristan/Coding/fmt/include/fmt/compile.h:472:17: note: in instantiation of function template specialization 'fmt::format<fmt::detail::spec_field<char, fmt::join_view<unsigned char *, unsigned char *>, 0>, fmt::join_view<unsigned char *, unsigned char *>, char, 0>' requested here
472 | return fmt::format(compiled, std::forward<Args>(args)...);
| ^
/Users/tristan/Coding/fmt/test/compile-test.cc:185:28: note: in instantiation of function template specialization 'fmt::format<FMT_COMPILE_STRING, fmt::join_view<unsigned char *, unsigned char *>, 0>' requested here
185 | EXPECT_EQ("0102af", fmt::format(FMT_COMPILE("{:02x}"), fmt::join(data, "")));
| ^
/Users/tristan/Coding/fmt/include/fmt/ranges.h:588:8: note: candidate function template not viable: 1st argument ('const fmt::join_view<unsigned char *, unsigned char *>') would lose const qualifier
588 | auto format(join_view<It, Sentinel, Char>& value,
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 errors generated.
From the last line, it seems that something is trying to pass a const join_view
to the format function, but I'm not sure where that call is coming from
from fmt.
Fixed by #3800 (thanks).
from fmt.
Or is it unrelated?
from fmt.
There are a couple of places in the join_view
constructor where iterators are copied, but these are easily solved with std::move
. The difficulty is with formatter<join_view>::format()
:
Lines 587 to 603 in 810d175
Line 590 takes a copy of the iterator, which it then modifies. Because the join_view
is passed to this function as a const reference, there's no way we can move the iterator out of it -- and we also can't directly operate on the stored iterator, as it's const.
It seems like we need to take the join_view
argument to format()
by mutable &
rather than const&
, but making this change results in fmt considering join_view
to be non-formattable. Unfortunately I don't know enough about the library to understand why that happens. I also tried using a forwarding reference, but this always deduces to const&
and so doesn't help.
The generic range support without join
(i.e. fmt::format("{}", my_range)
) handles move-only iterators just fine, so this definitely seems like it should be solvable, but I don't understand enough about the fmt internals to follow what's going on.
from fmt.
It seems like we need to take the join_view argument to format() by mutable & rather than const&, but making this change results in fmt considering join_view to be non-formattable.
This should work. What error do you get?
from fmt.
GCC gives a little more context: an error occurs in the return value of spec_field::format
:
Lines 197 to 204 in 3c96084
Here, get_arg_checked<T, N>(args...)
returns const join_view&
, which causes the error as it cannot be passed to the join_view
's modified format
function. get_checked_arg
says
Lines 128 to 130 in 3c96084
so I guess adding the const&
is intentional, but I don't get why this triggers an error when using join
and not with plain fmt::format("{}", my_range)
?
from fmt.
Looks like we need to propagate (lack of) constness during format string compilation. Currently it passes everything by const&
.
from fmt.
Related Issues (20)
- `nested_formatter` compilation errors HOT 1
- chrono glibc '-' ext applies to following components within a spec HOT 3
- join does not use ADL on begin/end of its ranges HOT 1
- Invalid (local) %Z and %z with std::chrono::time_point<system_clock> but correct UTC Timestamp (%T) on MSVC HOT 4
- macOS compile issue on b2cde48de5253cc0c8e866b06edfbdd295ba1b45 HOT 2
- The vformat & vprint functions produce incorrect output when mixing named and positional arguments. HOT 2
- Documentation: API example for user-defined formatter doesn't compile HOT 1
- Undefined POSIX macro on MacOS HOT 5
- Gibberish error messages: What am I doing wrong? HOT 2
- Broken `fmt::has_formatter<std::string_view>` on 10.2.1 HOT 1
- Define a "namespace" for user-defined format specifiers HOT 4
- Error lnk2001 unresolved external symbol after upgrade from 8.1.1 to 10.0.0 on Window 10 VS 2019 HOT 2
- no `flockfile` and `funlockfile` on esp32 HOT 5
- g++-14 warning on self-comparison HOT 1
- For footprint optimization: Add define FMT_SUPPORTS_LOCALE HOT 2
- FMT_STATIC_THOUSANDS_SEPARATOR broken in 10.0.0 HOT 2
- Warning stringop-overflow with gcc-10.3.0 HOT 2
- fmt/ranges.h incompatible with Eigen 3.4 HOT 6
- Custom thousand separator HOT 1
- Formatting nested custom types with indentation HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fmt.