84 #include <string_view>
85 #include <type_traits>
100 template <
typename TypeT>
101 using RemoveCvref =
typename std::remove_cv_t<std::remove_reference_t<TypeT>>;
103 template <
typename TypeT,
typename =
void>
106 template <
typename TypeT>
107 struct IsOutputIteratorImpl<TypeT, std::enable_if_t<std::is_assignable_v<decltype(*std::declval<TypeT&>()++), char>>>
113 template <
typename TypeT,
size_t NumT>
116 template <
typename TypeT>
135 template <
typename T>
139 struct TypeConstant<signed char> : std::integral_constant<Type, Type::kInt> {};
142 struct TypeConstant<unsigned char> : std::integral_constant<Type, Type::kUint> {};
145 struct TypeConstant<short> : std::integral_constant<Type, Type::kInt> {};
148 struct TypeConstant<unsigned short> : std::integral_constant<Type, Type::kUint> {};
151 struct TypeConstant<int> : std::integral_constant<Type, Type::kInt> {};
154 struct TypeConstant<unsigned> : std::integral_constant<Type, Type::kUint> {};
157 struct TypeConstant<long> : std::integral_constant<Type, Type::kLongLong> {};
160 struct TypeConstant<unsigned long> : std::integral_constant<Type, Type::kUlongLong> {};
163 struct TypeConstant<long long> : std::integral_constant<Type, Type::kLongLong> {};
166 struct TypeConstant<unsigned long long> : std::integral_constant<Type, Type::kUlongLong> {};
169 struct TypeConstant<bool> : std::integral_constant<Type, Type::kBool> {};
172 struct TypeConstant<char> : std::integral_constant<Type, Type::kChar> {};
175 struct TypeConstant<float> : std::integral_constant<Type, Type::kFloat> {};
178 struct TypeConstant<double> : std::integral_constant<Type, Type::kDouble> {};
181 struct TypeConstant<const char*> : std::integral_constant<Type, Type::kCstring> {};
184 struct TypeConstant<char*> : std::integral_constant<Type, Type::kCstring> {};
187 struct TypeConstant<std::string_view> : std::integral_constant<Type, Type::kString> {};
190 struct TypeConstant<std::string> : std::integral_constant<Type, Type::kString> {};
192 template <
size_t NumT>
193 struct TypeConstant<char[NumT]> : std::integral_constant<Type, Type::kCstring> {};
195 template <
size_t NumT>
196 struct TypeConstant<const char[NumT]> : std::integral_constant<Type, Type::kCstring> {};
198 template <
typename T>
199 struct TypeConstant<T*> : std::integral_constant<Type, Type::kPointer> {};
207 unsigned long long value) noexcept;
210 long long value) noexcept;
222 char*
out() const noexcept;
224 size_t written() const noexcept;
226 size_t total_size() const noexcept;
230 void write(const
char* s,
size_t count);
232 void write(std::string_view sv);
235 char* begin_{
nullptr};
238 size_t total_size_{0};
241 template <
typename OutputItT>
246 inline OutputItT
out() const noexcept {
return out_; }
248 inline size_t size() const noexcept {
return count_; }
255 inline void write(
const char* s,
size_t count) {
256 for (
size_t i = 0; i < count; ++i) {
263 inline void write(std::string_view sv) {
write(sv.data(), sv.size()); }
270 template <
typename CharT>
292 constexpr
explicit Value(
unsigned char val) :
uint_value(static_cast<unsigned>(val)) {}
296 constexpr
explicit Value(
unsigned short val) :
uint_value(static_cast<unsigned>(val)) {}
326 template <
size_t NumT>
329 template <
size_t NumT>
332 template <
typename TypeT>
337 template <
typename CharT>
342 template <
typename TypeT>
344 if constexpr (std::is_enum_v<TypeT>) {
345 using UnderlyingT = std::underlying_type_t<TypeT>;
352 static_assert(!
sizeof(TypeT),
353 "[vlink::format] unsupported type for format_to/MLOG, "
354 "convert to string first");
366 template <
typename CharT,
typename... ArgsT>
368 static constexpr
size_t kNumArgs =
sizeof...(ArgsT);
371 template <
typename... ValuesT>
375 template <
typename CharT>
380 template <
typename... ArgsT>
382 : args_(store.args), size_(sizeof...(ArgsT)) {}
385 return id < size_ ? args_[id] : FormatArg<CharT>();
388 constexpr
size_t size()
const {
return size_; }
397 template <
typename CharT,
typename WriterT>
404 const char* p = fmt.data();
405 const char* end = p + fmt.size();
411 if (p != end && *p ==
'}') {
439 write_arg(args.
get(arg_id++));
447 size_t index = arg_id;
448 bool has_explicit_index =
false;
450 if (*p >=
'0' && *p <=
'9') {
452 has_explicit_index =
true;
454 while (p != end && *p >=
'0' && *p <=
'9') {
455 index = index * 10 +
static_cast<size_t>(*p++ -
'0');
459 while (p != end && *p !=
'}') {
465 write_arg(args.
get(index));
468 if VLIKELY (!has_explicit_index) {
477 inline auto out()
const {
return writer_.out(); }
479 template <
typename WriterImplT = WriterT>
481 return writer_.total_size();
484 inline size_t size()
const {
return writer_.size(); }
488 void write_int(
int value) {
491 writer_.write(buf, n);
494 void write_uint(
unsigned value) {
497 writer_.write(buf, n);
500 void write_long_long(
long long value) {
503 writer_.write(buf, n);
506 void write_ulong_long(
unsigned long long value) {
509 writer_.write(buf, n);
512 void write_bool(
bool value) {
514 writer_.write(
"true", 4);
516 writer_.write(
"false", 5);
520 void write_char(
char value) { writer_.write(value); }
522 void write_string(
const char* str) {
524 writer_.write(str, std::strlen(str));
526 writer_.write(
"(null)", 6);
530 void write_string_view(std::string_view sv) { writer_.write(sv); }
532 void write_pointer(
const void* ptr) {
535 writer_.write(buf, n);
538 void write_float(
float value) {
541 writer_.write(buf, n);
544 void write_double(
double value) {
547 writer_.write(buf, n);
550 void write_arg(
const FormatArg<CharT>& arg) {
551 switch (arg.type()) {
553 write_int(arg.value().int_value);
556 write_uint(arg.value().uint_value);
559 write_long_long(arg.value().long_long_value);
562 write_ulong_long(arg.value().ulong_long_value);
565 write_bool(arg.value().bool_value);
568 write_char(arg.value().char_value);
571 write_float(arg.value().float_value);
574 write_double(arg.value().double_value);
577 write_string(arg.value().string_value);
580 write_string_view(arg.value().string_view_value);
583 write_pointer(arg.value().pointer_value);
607 template <
typename... ArgsT>
614 template <
size_t NumT>
616 constexpr
FString(
const char (&s)[NumT]) :
str(s, NumT - 1) {}
619 template <
typename StrT, std::enable_if_t<std::is_convertible_v<const StrT&, std::
string_view>,
int> = 0>
624 inline operator std::string_view()
const {
return str; }
626 std::string_view
get()
const {
return str; }
634 template <
typename... ArgsT>
643 template <
typename OutputItT>
671 template <
typename... ArgsT>
689 template <
typename... ArgsT>
702 template <
size_t NumT,
typename... ArgsT>
719 template <
typename OutputItT,
typename... ArgsT,
721 std::enable_if_t<detail::kIsOutputIterator<detail::RemoveCvref<OutputItT>> &&
722 !std::is_array_v<std::remove_reference_t<OutputItT>>,
734 template <
typename... ArgsT>
736 const ArgsT&... args) {
740 template <
typename... ArgsT>
741 inline format::FormatToNResult<char*>
format::format_to_n(
char* out,
size_t n, format_string<ArgsT...> fmt,
742 const ArgsT&... args) {
743 format::detail::FormatArgStore<char, format::detail::RemoveCvref<ArgsT>...> arg_store{args...};
746 format::detail::StringWriter sw(out, n);
747 format::detail::FormatWriter<char, format::detail::StringWriter> writer(sw);
748 writer.format(fmt.get(), fargs);
750 size_t total = writer.total_size();
752 return {writer.out(), total, total > n};
755 template <
size_t NumT,
typename... ArgsT>
756 inline format::FormatToResult
format::format_to(
char (&out)[NumT], format_string<ArgsT...> fmt,
const ArgsT&... args) {
759 return {result.out, result.size, result.truncated};
762 template <
typename OutputItT,
typename... ArgsT,
763 std::enable_if_t<format::detail::kIsOutputIterator<format::detail::RemoveCvref<OutputItT>> &&
764 !std::is_array_v<std::remove_reference_t<OutputItT>>,
766 inline format::detail::RemoveCvref<OutputItT>
format::format_to(OutputItT&& out, format_string<ArgsT...> fmt,
767 const ArgsT&... args) {
768 using ItT = format::detail::RemoveCvref<OutputItT>;
773 format::detail::IteratorWriter<ItT> iter_writer(out);
774 format::detail::FormatWriter<char, format::detail::IteratorWriter<ItT>> writer(iter_writer);
776 writer.format(fmt.get(), fargs);
Cross-platform macros for visibility, branch hints, copy prevention, singletons and string helpers.
#define VUNLIKELY(...)
Short alias for VLINK_UNLIKELY.
Definition: macros.h:289
#define VLINK_EXPORT
Definition: macros.h:81
#define VLIKELY(...)
Short alias for VLINK_LIKELY.
Definition: macros.h:284
constexpr auto values() noexcept
Definition: name_detector.h:511