9 #include "quill/core/Attributes.h" 10 #include "quill/core/Codec.h" 11 #include "quill/core/DynamicFormatArgStore.h" 12 #include "quill/core/InlinedVector.h" 18 #include <type_traits> 23 #if defined(_WIN32) && defined(_MSC_VER) 26 #pragma warning(disable : 4702) 95 static constexpr
bool use_memcpy =
96 std::conjunction_v<std::is_trivially_copyable<T>, std::is_default_constructible<T>>;
100 if constexpr (use_memcpy)
107 return sizeof(T) +
alignof(T) - 1;
111 template <
typename Arg>
114 if constexpr (use_memcpy)
116 std::memcpy(buffer, &arg,
sizeof(arg));
117 buffer +=
sizeof(arg);
121 auto aligned_ptr = align_pointer(buffer,
alignof(T));
123 if constexpr (std::is_rvalue_reference_v<Arg&&> && is_move_constructible<T>::value)
125 new (
static_cast<void*
>(aligned_ptr)) T(std::move(arg));
129 static_assert(is_copy_constructible<T>::value,
"T is not copy-constructible!");
130 new (
static_cast<void*
>(aligned_ptr)) T(arg);
133 buffer +=
sizeof(T) +
alignof(T) - 1;
137 static T decode_arg(std::byte*& buffer)
139 if constexpr (use_memcpy)
144 std::memcpy(static_cast<void*>(&arg), buffer,
sizeof(arg));
146 buffer +=
sizeof(arg);
151 static_assert(std::is_move_constructible_v<T> || std::is_copy_constructible_v<T>,
152 "T must be move or copy constructible");
154 auto* aligned_ptr = align_pointer(buffer,
alignof(T));
155 auto* tmp = std::launder(reinterpret_cast<T*>(aligned_ptr));
156 buffer +=
sizeof(T) +
alignof(T) - 1;
165 if constexpr (!std::is_trivially_destructible_v<T>)
170 } destroy_guard{tmp};
172 if constexpr (std::is_move_constructible_v<T>)
175 return T{std::move(*tmp)};
188 QUILL_TRY { args_store->
push_back(decode_arg(buffer)); }
189 #if !defined(QUILL_NO_EXCEPTIONS) 194 static constexpr
char fallback[] =
"[Quill deferred decode failed]";
195 args_store->
push_back(fmtquill::string_view{fallback,
sizeof(fallback) - 1u});
204 template <
typename U,
typename =
void>
205 struct is_default_constructible : std::false_type
209 template <
typename U>
210 struct is_default_constructible<U, std::void_t<decltype(U())>> : std::true_type
215 template <
typename U,
typename =
void>
216 struct is_copy_constructible : std::false_type
220 template <
typename U>
221 struct is_copy_constructible<U, std::void_t<decltype(U(std::declval<U const&>()))>> : std::true_type
226 template <
typename U,
typename =
void>
227 struct is_move_constructible : std::false_type
231 template <
typename U>
232 struct is_move_constructible<U, std::void_t<decltype(U(std::declval<U&&>()))>> : std::true_type
236 static std::byte* align_pointer(
void* pointer,
size_t alignment) noexcept
238 return reinterpret_cast<std::byte*
>((
reinterpret_cast<uintptr_t
>(pointer) + (alignment - 1ul)) &
245 #if defined(_WIN32) && defined(_MSC_VER)