Fixed a lifetime issue in test and minor build fixes.

This commit is contained in:
vsol 2020-03-10 11:17:44 +03:00
parent 833bfe3749
commit c3c6d0c2d2
2 changed files with 25 additions and 10 deletions

View File

@ -159,8 +159,8 @@ class dynamic_format_arg_store
}
public:
dynamic_format_arg_store() FMT_NOEXCEPT = default;
~dynamic_format_arg_store() FMT_NOEXCEPT = default;
dynamic_format_arg_store() = default;
~dynamic_format_arg_store() = default;
dynamic_format_arg_store(const dynamic_format_arg_store&) = delete;
dynamic_format_arg_store& operator=(const dynamic_format_arg_store&) = delete;

View File

@ -37,20 +37,25 @@ TEST(FormatDynArgsTest, StringsAndRefs) {
}
struct Custom{ int i{0}; };
FMT_BEGIN_NAMESPACE
template <>
struct fmt::formatter<Custom> {
constexpr auto parse(format_parse_context& ctx) {
struct formatter<Custom> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin())
{
return ctx.begin();
}
template <typename FormatContext>
auto format(const Custom& p, FormatContext& ctx) {
// ctx.out() is an output iterator to write to.
return format_to(
auto format(const Custom& p, FormatContext& ctx) ->
decltype(format_to(ctx.out(),
std::declval<typename FormatContext::char_type const*>())) {
return format_to(
ctx.out(),
"cust={}", p.i);
}
};
FMT_END_NAMESPACE
#ifdef FMT_HAS_VARIANT
@ -75,9 +80,19 @@ TEST(FormatDynArgsTest, CustomFormat) {
TEST(FormatDynArgsTest, NamedArgByRef) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
auto a1 = fmt::arg("a1_", 42);
auto ref = std::cref(a1);
store.push_back(ref);
// Note: fmt::arg() constructs an object which holds a reference
// to its value. It's not an aggregate, so it doesn't extend the
// reference lifetime. As a result, it's a very bad idea passing temporary
// as a named argument value. Only GCC with optimization level >0
// complains about this.
//
// A real life usecase is when you have both name and value alive
// guarantee their lifetime and thus don't want them to be copied into
// storages.
int a1_val{42};
auto a1 = fmt::arg("a1_", a1_val);
store.push_back(std::cref(a1));
std::string result = fmt::vformat(
"{a1_}", // and {} and {}",