16 #include <type_traits>
19 #define FMT_VERSION 50300
22 # define FMT_HAS_FEATURE(x) __has_feature(x)
24 # define FMT_HAS_FEATURE(x) 0
27 #if defined(__has_include) && !defined(__INTELLISENSE__) && \
28 !(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600)
29 # define FMT_HAS_INCLUDE(x) __has_include(x)
31 # define FMT_HAS_INCLUDE(x) 0
34 #ifdef __has_cpp_attribute
35 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
37 # define FMT_HAS_CPP_ATTRIBUTE(x) 0
40 #if defined(__GNUC__) && !defined(__clang__)
41 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
43 # define FMT_GCC_VERSION 0
46 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
47 # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION
49 # define FMT_HAS_GXX_CXX11 0
53 # define FMT_MSC_VER _MSC_VER
55 # define FMT_MSC_VER 0
60 #ifndef FMT_USE_CONSTEXPR
61 # define FMT_USE_CONSTEXPR \
62 (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \
63 (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L))
66 # define FMT_CONSTEXPR constexpr
67 # define FMT_CONSTEXPR_DECL constexpr
69 # define FMT_CONSTEXPR inline
70 # define FMT_CONSTEXPR_DECL
73 #ifndef FMT_USE_CONSTEXPR11
74 # define FMT_USE_CONSTEXPR11 \
75 (FMT_USE_CONSTEXPR || FMT_GCC_VERSION >= 406 || FMT_MSC_VER >= 1900)
77 #if FMT_USE_CONSTEXPR11
78 # define FMT_CONSTEXPR11 constexpr
80 # define FMT_CONSTEXPR11
84 # if FMT_HAS_FEATURE(cxx_override) || \
85 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
86 # define FMT_OVERRIDE override
92 #if FMT_HAS_FEATURE(cxx_explicit_conversions) || \
93 FMT_GCC_VERSION >= 405 || FMT_MSC_VER >= 1800
94 # define FMT_USE_EXPLICIT 1
95 # define FMT_EXPLICIT explicit
97 # define FMT_USE_EXPLICIT 0
102 # if FMT_HAS_FEATURE(cxx_nullptr) || \
103 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1600
104 # define FMT_NULL nullptr
105 # define FMT_USE_NULLPTR 1
107 # define FMT_NULL NULL
110 #ifndef FMT_USE_NULLPTR
111 # define FMT_USE_NULLPTR 0
115 #ifndef FMT_EXCEPTIONS
116 # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
117 FMT_MSC_VER && !_HAS_EXCEPTIONS
118 # define FMT_EXCEPTIONS 0
120 # define FMT_EXCEPTIONS 1
125 #ifndef FMT_USE_NOEXCEPT
126 # define FMT_USE_NOEXCEPT 0
129 #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
130 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900
131 # define FMT_DETECTED_NOEXCEPT noexcept
132 # define FMT_HAS_CXX11_NOEXCEPT 1
134 # define FMT_DETECTED_NOEXCEPT throw()
135 # define FMT_HAS_CXX11_NOEXCEPT 0
139 # if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
140 # define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
142 # define FMT_NOEXCEPT
146 #ifndef FMT_BEGIN_NAMESPACE
147 # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \
149 # define FMT_INLINE_NAMESPACE inline namespace
150 # define FMT_END_NAMESPACE }}
152 # define FMT_INLINE_NAMESPACE namespace
153 # define FMT_END_NAMESPACE } using namespace v5; }
155 # define FMT_BEGIN_NAMESPACE namespace fmt { FMT_INLINE_NAMESPACE v5 {
158 #if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
160 # define FMT_API __declspec(dllexport)
161 # elif defined(FMT_SHARED)
162 # define FMT_API __declspec(dllimport)
170 # define FMT_ASSERT(condition, message) assert((condition) && message)
174 #if (FMT_HAS_INCLUDE(<string_view>) && \
175 (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
176 (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
177 # include <string_view>
178 # define FMT_STRING_VIEW std::basic_string_view
179 #elif FMT_HAS_INCLUDE(<experimental/string_view>) && __cplusplus >= 201402L
180 # include <experimental/string_view>
181 # define FMT_STRING_VIEW std::experimental::basic_string_view
185 #if FMT_GCC_VERSION && FMT_GCC_VERSION <= 404
186 # include <functional>
193 template <
typename T>
199 template <
typename F,
typename... Args>
202 typedef typename std::result_of<
207 template <
typename Int>
214 template <
typename T>
222 std::size_t capacity_;
234 capacity_ = buf_capacity;
238 virtual void grow(std::size_t capacity) = 0;
274 if (new_capacity > capacity_)
280 ptr_[size_++] =
value;
284 template <
typename U>
285 void append(
const U *
begin,
const U *
end);
288 const T &
operator[](std::size_t index)
const {
return ptr_[index]; }
295 template <
typename Container>
298 Container &container_;
302 container_.resize(capacity);
303 this->set(&container_[0], capacity);
312 template <
typename Container>
314 typedef std::back_insert_iterator<Container> bi_iterator;
315 struct accessor: bi_iterator {
316 accessor(bi_iterator iter) : bi_iterator(iter) {}
317 using bi_iterator::container;
319 return *accessor(it).container;
327 FMT_API void on_error(
const char *message);
330 template <
typename T>
334 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 405
335 template <
typename... T>
338 template <
typename... T>
349 template <
typename Char>
363 : data_(s), size_(count) {}
372 : data_(s), size_(
std::char_traits<Char>::length(s)) {}
375 template <
typename Alloc>
378 : data_(s.data()), size_(s.size()) {}
380 #ifdef FMT_STRING_VIEW
382 : data_(s.data()), size_(s.size()) {}
401 size_t str_size = size_ < other.size_ ? size_ : other.size_;
402 int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
404 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
453 template <
typename Char>
457 template <
typename Char>
461 template <
typename Char>
464 #ifdef FMT_STRING_VIEW
465 template <
typename Char>
474 template <
typename S>
479 typename Enable =
typename std::enable_if<is_compile_string<S>::value>
::type>
483 template <
typename Context>
486 template <
typename Context>
490 template <
typename T,
typename Char =
char,
typename Enable =
void>
493 "don't know how to format the type, include fmt/ostream.h if it provides "
494 "an operator<< that should be used");
497 template <
typename ParseContext>
498 typename ParseContext::iterator parse(ParseContext &);
499 template <
typename FormatContext>
500 auto format(
const T &val, FormatContext &ctx) -> decltype(ctx.out());
503 template <
typename T,
typename Char,
typename Enable =
void>
505 bool, !std::is_arithmetic<T>::value && std::is_convertible<T, int>::value> {};
514 template <
typename S>
515 struct is_string : std::integral_constant<bool, !std::is_same<
516 dummy_string_view, decltype(to_string_view(declval<S>()))>::value> {};
518 template <
typename S>
524 template <typename Char>
527 template <typename T, typename Char>
550 template <
typename Char>
556 template <
typename Context>
563 template <
typename Context>
583 value(
unsigned val) { uint_value = val; }
584 value(
long long val) { long_long_value = val; }
585 value(
unsigned long long val) { ulong_long_value = val; }
586 value(
double val) { double_value = val; }
587 value(
long double val) { long_double_value = val; }
590 static_assert(std::is_same<char, char_type>::value,
591 "incompatible string types");
595 static_assert(std::is_same<char, char_type>::value,
596 "incompatible string types");
600 string.value = val.
data();
601 string.size = val.
size();
603 value(
const void *val) { pointer = val; }
605 template <
typename T>
608 custom.format = &format_custom_arg<T>;
617 template <
typename T>
618 static void format_custom_arg(
const void *
arg, Context &ctx) {
623 auto &&parse_ctx = ctx.parse_context();
624 parse_ctx.advance_to(f.parse(parse_ctx));
625 ctx.advance_to(f.format(*static_cast<const T*>(
arg), ctx));
630 template <
typename Context,
typename T, type TYPE>
633 static const type type_tag = TYPE;
639 template <
typename Context,
typename T>
642 #define FMT_MAKE_VALUE(TAG, ArgType, ValueType) \
643 template <typename C> \
644 FMT_CONSTEXPR init<C, ValueType, TAG> make_value(ArgType val) { \
645 return static_cast<ValueType>(val); \
648 #define FMT_MAKE_VALUE_SAME(TAG, Type) \
649 template <typename C> \
650 FMT_CONSTEXPR init<C, Type, TAG> make_value(Type val) { return val; }
660 typedef
std::conditional<sizeof(
long) == sizeof(
int),
int,
long long>::
type
664 typedef
std::conditional<sizeof(
unsigned long) == sizeof(
unsigned),
676 template <typename C, typename Char>
681 template <
typename C>
683 !std::is_same<typename C::char_type, char>::value,
718 template <
typename C,
typename T>
719 typename std::enable_if<!std::is_same<T, typename C::char_type>::value>
::type
721 static_assert(!
sizeof(T),
"formatting of non-void pointers is disallowed");
724 template <
typename C,
typename T>
725 inline typename std::enable_if<
727 init<C, int, int_type>>
::type
730 template <
typename C,
typename T,
typename Char =
typename C::
char_type>
731 inline typename std::enable_if<
737 template <
typename C,
typename T,
typename Char =
typename C::
char_type>
738 inline typename std::enable_if<
740 !std::is_convertible<T, basic_string_view<Char>>::value &&
745 init<C, const T &, custom_type>>
::type
748 template <
typename C,
typename T>
749 init<C, const void*, named_arg_type>
753 return static_cast<const void*>(&val);
756 template <
typename C,
typename S>
762 static_assert(std::is_same<
764 "mismatch between char-types of context and argument");
772 template <
typename Context>
778 template <
typename Context>
784 template <
typename ContextType,
typename T>
788 template <
typename Visitor,
typename Ctx>
802 void format(Context &ctx)
const { custom_.format(custom_.value, ctx); }
829 template <
typename Visitor,
typename Context>
840 return vis(
arg.value_.int_value);
842 return vis(
arg.value_.uint_value);
844 return vis(
arg.value_.long_long_value);
846 return vis(
arg.value_.ulong_long_value);
848 return vis(
arg.value_.int_value != 0);
850 return vis(static_cast<char_type>(
arg.value_.int_value));
852 return vis(
arg.value_.double_value);
854 return vis(
arg.value_.long_double_value);
856 return vis(
arg.value_.string.value);
859 arg.value_.string.value,
arg.value_.string.size));
861 return vis(
arg.value_.pointer);
869 template <
typename Visitor,
typename Context>
877 template <
typename Char,
typename ErrorHandler =
internal::error_handler>
889 : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {}
894 return format_str_.
begin();
909 if (next_arg_id_ > 0) {
910 on_error(
"cannot switch from automatic to manual argument indexing");
919 ErrorHandler::on_error(message);
934 template <
typename Context>
937 arg_map(
const arg_map &) =
delete;
938 void operator=(
const arg_map &) =
delete;
950 void push_back(value<Context> val) {
952 map_[size_] = entry{named.
name, named.template deserialize<Context>()};
963 for (entry *it = map_, *
end = map_ + size_; it !=
end; ++it) {
964 if (it->name == name)
980 template <
typename Locale>
983 template <
typename Locale>
987 template <
typename OutputIt,
typename Context,
typename Char>
1005 : parse_context_(format_str), out_(out), args_(ctx_args), loc_(loc) {}
1011 parse_context_.
on_error(
"argument index out of range");
1043 template <
typename Context,
typename T>
1045 typedef decltype(make_value<Context>(
1050 template <typename Context>
1053 template <
typename Context,
typename Arg,
typename... Args>
1058 template <
typename Context,
typename T>
1062 arg.value_ = make_value<Context>(
value);
1066 template <
bool IS_PACKED,
typename Context,
typename T>
1067 inline typename std::enable_if<IS_PACKED, value<Context>>
::type
1069 return make_value<Context>(
value);
1072 template <
bool IS_PACKED,
typename Context,
typename T>
1073 inline typename std::enable_if<!IS_PACKED, basic_format_arg<Context>>
::type
1075 return make_arg<Context>(
value);
1080 template <
typename OutputIt,
typename Char>
1083 OutputIt, basic_format_context<OutputIt, Char>, Char> {
1089 template <
typename T>
1100 using base::get_arg;
1112 :
base(out, format_str, ctx_args, loc) {}
1115 return this->do_get_arg(this->
parse_context().next_arg_id());
1124 template <
typename Char>
1127 std::back_insert_iterator<internal::basic_buffer<Char>>, Char>
type;
1139 template <
typename Context,
typename ...Args>
1142 static const size_t NUM_ARGS =
sizeof...(Args);
1147 typedef typename std::conditional<IS_PACKED,
1151 static const size_t DATA_SIZE =
1152 NUM_ARGS + (IS_PACKED && NUM_ARGS != 0 ? 0 : 1);
1153 value_type data_[DATA_SIZE];
1164 #if FMT_USE_CONSTEXPR11
1170 #if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \
1171 (FMT_MSC_VER && FMT_MSC_VER <= 1800)
1174 value_type init[DATA_SIZE] =
1175 {internal::make_arg<IS_PACKED, Context>(args)...};
1176 std::memcpy(data_, init,
sizeof(init));
1180 : data_{internal::make_arg<IS_PACKED, Context>(args)...} {}
1184 #if !FMT_USE_CONSTEXPR11
1185 template <
typename Context,
typename ...Args>
1186 const unsigned long long format_arg_store<Context, Args...>::TYPES =
1198 inline format_arg_store<Context, Args...>
1202 template <
typename Context>
1211 unsigned long long types_;
1225 unsigned shift = index * 4;
1226 return static_cast<typename internal::type>(
1227 (types_ & (0xfull << shift)) >> shift);
1233 void set_data(
const format_arg *args) { args_ = args; }
1235 format_arg do_get(size_type index)
const {
1238 auto num_args = max_size();
1239 if (index < num_args)
1248 internal::value<Context> &val =
arg.value_;
1249 val = values_[index];
1261 template <
typename... Args>
1263 : types_(static_cast<unsigned long long>(store.TYPES)) {
1264 set_data(store.data_);
1281 arg =
arg.value_.as_named_arg().template deserialize<Context>();
1287 return static_cast<size_type>(
1295 template <
typename ...Args>
1300 template <
typename ...Args>
1305 #define FMT_ENABLE_IF_T(B, T) typename std::enable_if<B, T>::type
1307 #ifndef FMT_USE_ALIAS_TEMPLATES
1308 # define FMT_USE_ALIAS_TEMPLATES FMT_HAS_FEATURE(cxx_alias_templates)
1310 #if FMT_USE_ALIAS_TEMPLATES
1312 template <
typename S>
1315 #define FMT_CHAR(S) fmt::char_t<S>
1317 template <
typename S>
1319 internal::is_string<S>::value, typename internal::char_t<S>::type> {};
1320 #define FMT_CHAR(S) typename char_t<S>::type
1323 namespace internal {
1324 template <
typename Char>
1325 struct named_arg_base {
1334 template <
typename Context>
1342 template <
typename T,
typename Char>
1343 struct named_arg : named_arg_base<Char> {
1350 template <
typename... Args,
typename S>
1351 inline typename std::enable_if<!is_compile_string<S>::value>
::type
1353 template <
typename... Args,
typename S>
1354 typename std::enable_if<is_compile_string<S>::value>
::type
1357 template <
typename S,
typename... Args>
1359 typename buffer_context<FMT_CHAR(S)>::type, Args...> {
1370 template <
typename Char>
1371 std::basic_string<Char>
vformat(
1375 template <
typename Char>
1390 template <
typename T>
1395 template <
typename T>
1401 template <
typename S,
typename T,
typename Char>
1404 template <
typename Container>
1407 template <
typename Char>
1410 template <
typename Char>
1414 template <
typename Container,
typename S>
1415 typename std::enable_if<
1418 std::back_insert_iterator<Container> out,
1419 const S &format_str,
1426 template <
typename Container,
typename S,
typename... Args>
1427 inline typename std::enable_if<
1429 std::back_insert_iterator<Container>>
::type
1430 format_to(std::back_insert_iterator<Container> out,
const S &format_str,
1431 const Args &... args) {
1436 template <
typename S,
typename Char = FMT_CHAR(S)>
1438 const S &format_str,
1453 template <
typename S,
typename... Args>
1455 const S &format_str,
const Args &... args) {
1475 template <
typename S,
typename... Args>
1477 print(
std::FILE *f, const S &format_str, const Args &... args) {
1494 template <
typename S,
typename... Args>
1496 print(const S &format_str, const Args &... args) {
1502 #endif // FMT_CORE_H_