-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add vformat_to_n function #769
Comments
It is not possible to provide |
I have a class which looks similar to this: template <size_t N>
class FixedSizeString {
public:
// ...
void setFromFormatV(const char format[], fmt::format_args args) noexcept {
fmt::vformat_to_n(&mData[0], N, format, args);
}
template <typename... Args>
void setFromFormat(const char format[], const Args&... args) noexcept {
setFromFormatV(format, fmt::make_format_args(args...));
}
private:
char mData[N];
}; It allows me to format a string into a fixed size buffer. Based on the It's not a major issue, but I was just wondering, why |
The template <typename... Args>
void setFromFormat(const char format[], const Args&... args) noexcept {
fmt::format_to_n(&mData[0], N, format, args...);
} |
But this means, that I have to use variadic template functions all over the place. If I want to use an abstract interface class such as the following, then this even isn't possible without implementing my own type erasure solution: class FixedSizeStringBase {
public:
virtual ~FixedSizeStringBase() = default;
virtual void setFromFormat(const char format[], fmt::format_args args) noexcept = 0;
};
template <size_t N>
class FixedSizeString : public FixedSizeStringBase {
public:
virtual ~FixedSizeString() = default;
void setFromFormat(const char format[], fmt::format_args args) noexcept override {
fmt::vformat_to_n(&mData[0], N, format, args);
}
private:
char mData[N];
}; (contrived example) My previous solution used |
Right now this can only be done using the internal API, but I can make the relevant parts of the API public if this works for you: #include "fmt/format.h"
using format_to_n_context = typename fmt::format_context_t<
fmt::internal::truncating_iterator<char*>>::type;
using format_to_n_args = fmt::basic_format_args<format_to_n_context>;
class FixedSizeStringBase {
public:
virtual void vsetFromFormat(const char *format, format_to_n_args args) = 0;
template <typename... Args>
void setFromFormat(const char *format, const Args&... args) {
vsetFromFormat(format, fmt::make_format_args<format_to_n_context>(args...));
}
};
template <size_t N>
class FixedSizeString : public FixedSizeStringBase {
public:
void vsetFromFormat(const char *format, format_to_n_args args) override {
vformat_to(fmt::internal::truncating_iterator<char*>(&mData[0], N),
format, args);
}
private:
char mData[N];
};
int main() {
FixedSizeString<10> s;
s.setFromFormat("{}", 42);
} |
Thanks, that already would help me. So a template <typename OutputIt>
using format_to_n_context = typename fmt::format_context_t<
fmt::internal::truncating_iterator<OutputIt>>::type;
template <typename OutputIt>
using format_to_n_args = fmt::basic_format_args<format_to_n_context<OutputIt> >;
template <typename OutputIt, typename ...Args>
inline format_arg_store<format_to_n_contex<OutputIt>, Args...>
make_format_to_n_args(const Args & ... args) {
return format_arg_store<format_to_n_contex<OutputIt>, Args...>(args...);
}
template <typename OutputIt, typename... Args>
inline format_to_n_result<OutputIt> vformat_to_n(
OutputIt out, std::size_t n, string_view format_str, format_to_n_args<OutputIt> args) {
typedef internal::truncating_iterator<OutputIt> It;
auto it = vformat_to(It(out, n), format_str, args);
return {it.base(), it.count()};
}
char buffer[128];
fmt::vformat_to_n(&buffer[0], 128, "{}, {}", make_format_to_n_args<char*>(42, 43)); It's kind of ugly, that the iterator type has to be specified for the |
Added |
Thank you very much!
|
Never mind. The problem was caused by my broken build configuration. I had two copies of fmt and for some reason it was using the header from one version, but the library from the other.
|
Just like there is a function called
fmt::vformat_to
, which takes afmt::format_args
as parameter, there should also be afmt::vformat_to_n
function, which takes afmt::format_args
as parameter.Or is there any reason, why this function does not exist?
The text was updated successfully, but these errors were encountered: