From 90219a772bb6b58c1fb9f14e57c2fa7e663a3be6 Mon Sep 17 00:00:00 2001 From: vsol Date: Fri, 13 Mar 2020 10:00:23 +0300 Subject: [PATCH] Build fixes --- include/fmt/dyn-args.h | 20 +++++++++----------- test/format-dyn-args-test.cc | 13 +++++++++---- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/fmt/dyn-args.h b/include/fmt/dyn-args.h index 2fd1cd68..e9ac5378 100644 --- a/include/fmt/dyn-args.h +++ b/include/fmt/dyn-args.h @@ -11,13 +11,6 @@ #include "core.h" -#if (defined(FMT_HAS_VARIANT) || __cplusplus >= 201703L) -# include -# ifndef FMT_HAS_VARIANT -# define FMT_HAS_VARIANT -# endif -#endif - FMT_BEGIN_NAMESPACE namespace internal { @@ -61,18 +54,23 @@ template using need_dyn_copy_t = typename need_dyn_copy::type; class dyn_arg_storage { + // Workaround clang's -Wweak-vtables. For templates (unlike regular classes + // doesn't complain about inability to deduce translation unit to place vtable + // So dyn_arg_node_base is made a fake template + + template struct dyn_arg_node_base { virtual ~dyn_arg_node_base() = default; std::unique_ptr next_; }; template - struct dyn_arg_node : dyn_arg_node_base { + struct dyn_arg_node : dyn_arg_node_base<> { T value_; FMT_CONSTEXPR explicit dyn_arg_node(T&& arg) : value_{arg}{} }; - std::unique_ptr head_{nullptr}; + std::unique_ptr> head_{nullptr}; public: dyn_arg_storage() = default; @@ -84,8 +82,8 @@ public: template const T& emplace_front(T&& val) { - auto node{new dyn_arg_node{std::forward(val)}}; - std::unique_ptr ptr{node}; + auto node = new dyn_arg_node{std::forward(val)}; + std::unique_ptr> ptr{node}; swap(ptr, head_); head_->next_ = std::move(ptr); return node->value_; diff --git a/test/format-dyn-args-test.cc b/test/format-dyn-args-test.cc index ad7d60ad..21478865 100644 --- a/test/format-dyn-args-test.cc +++ b/test/format-dyn-args-test.cc @@ -31,18 +31,18 @@ TEST(FormatDynArgsTest, StringsAndRefs) { EXPECT_EQ("1234567890 and X234567890 and X234567890", result); } -struct Custom { +struct custom_type { int i{0}; }; FMT_BEGIN_NAMESPACE -template <> struct formatter { +template <> struct formatter { auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { return ctx.begin(); } template - auto format(const Custom& p, FormatContext& ctx) -> decltype(format_to( + auto format(const custom_type& p, FormatContext& ctx) -> decltype(format_to( ctx.out(), std::declval())) { return format_to(ctx.out(), "cust={}", p.i); } @@ -50,8 +50,13 @@ template <> struct formatter { FMT_END_NAMESPACE TEST(FormatDynArgsTest, CustomFormat) { + using context = fmt::format_context; fmt::dynamic_format_arg_store store; - Custom c{}; + static_assert(fmt::internal::need_dyn_copy_t::value, ""); + static_assert( + fmt::internal::mapped_type_constant::value == + fmt::internal::type::custom_type, ""); + custom_type c{}; store.push_back(c); ++c.i; store.push_back(c);