39 #include <initializer_list>
43 #include <system_error>
45 #ifdef __cpp_lib_bit_cast
51 #ifndef FMT_BEGIN_DETAIL_NAMESPACE
52 # define FMT_BEGIN_DETAIL_NAMESPACE namespace detail {
53 # define FMT_END_DETAIL_NAMESPACE }
56 #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
57 # define FMT_FALLTHROUGH [[fallthrough]]
58 #elif defined(__clang__)
59 # define FMT_FALLTHROUGH [[clang::fallthrough]]
60 #elif FMT_GCC_VERSION >= 700 && \
61 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
62 # define FMT_FALLTHROUGH [[gnu::fallthrough]]
64 # define FMT_FALLTHROUGH
67 #ifndef FMT_DEPRECATED
68 # if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VERSION >= 1900
69 # define FMT_DEPRECATED [[deprecated]]
71 # if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
72 # define FMT_DEPRECATED __attribute__((deprecated))
73 # elif FMT_MSC_VERSION
74 # define FMT_DEPRECATED __declspec(deprecated)
76 # define FMT_DEPRECATED
82 # define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
84 # define FMT_GCC_VISIBILITY_HIDDEN
88 # define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
90 # define FMT_CUDA_VERSION 0
94 # define FMT_HAS_BUILTIN(x) __has_builtin(x)
96 # define FMT_HAS_BUILTIN(x) 0
99 #if FMT_GCC_VERSION || FMT_CLANG_VERSION
100 # define FMT_NOINLINE __attribute__((noinline))
102 # define FMT_NOINLINE
107 # if FMT_MSC_VERSION || defined(__NVCC__)
110 template <
typename Exception>
inline void do_throw(
const Exception&
x) {
113 volatile bool b =
true;
118 # define FMT_THROW(x) detail::do_throw(x)
120 # define FMT_THROW(x) throw x
123 # define FMT_THROW(x) \
125 FMT_ASSERT(false, (x).what()); \
132 # define FMT_CATCH(x) catch (x)
134 # define FMT_TRY if (true)
135 # define FMT_CATCH(x) if (false)
138 #ifndef FMT_MAYBE_UNUSED
139 # if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
140 # define FMT_MAYBE_UNUSED [[maybe_unused]]
142 # define FMT_MAYBE_UNUSED
146 #ifndef FMT_USE_USER_DEFINED_LITERALS
148 # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
149 FMT_MSC_VERSION >= 1900) && \
150 (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 480)
151 # define FMT_USE_USER_DEFINED_LITERALS 1
153 # define FMT_USE_USER_DEFINED_LITERALS 0
161 #if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
162 # define FMT_REDUCE_INT_INSTANTIATIONS 0
168 # if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
169 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
171 # if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
172 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
179 # if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \
180 defined(__NVCOMPILER)
181 # define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
183 # if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \
184 FMT_ICC_VERSION || defined(__NVCOMPILER)
185 # define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
196 #if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \
197 !defined(FMT_BUILTIN_CTZLL)
201 # if !defined(__clang__)
202 # pragma intrinsic(_BitScanForward)
203 # pragma intrinsic(_BitScanReverse)
205 # pragma intrinsic(_BitScanForward64)
206 # pragma intrinsic(_BitScanReverse64)
210 inline auto clz(uint32_t
x) ->
int {
212 _BitScanReverse(&r, x);
218 return 31 ^
static_cast<int>(
r);
220 # define FMT_BUILTIN_CLZ(n) detail::clz(n)
222 inline auto clzll(uint64_t x) ->
int {
225 _BitScanReverse64(&r, x);
228 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))
229 return 63 ^
static_cast<int>(r + 32);
231 _BitScanReverse(&r, static_cast<uint32_t>(x));
235 return 63 ^
static_cast<int>(
r);
237 # define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
239 inline auto ctz(uint32_t x) ->
int {
241 _BitScanForward(&r, x);
244 return static_cast<int>(
r);
246 # define FMT_BUILTIN_CTZ(n) detail::ctz(n)
248 inline auto ctzll(uint64_t x) ->
int {
253 _BitScanForward64(&r, x);
256 if (_BitScanForward(&r, static_cast<uint32_t>(x)))
return static_cast<int>(
r);
258 _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
261 return static_cast<int>(
r);
263 # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
272 template <
typename P1,
typename... Pn>
278 template <
typename P1,
typename... Pn>
287 if (condition)
throw std::runtime_error(
"fuzzing limit reached");
292 static constexpr CharT
value[
sizeof...(C)] = {C...};
294 return {
value,
sizeof...(C)};
298 #if FMT_CPLUSPLUS < 201703L
299 template <
typename CharT, CharT... C>
303 template <
typename Streambuf>
class formatbuf :
public Streambuf {
306 using streamsize = decltype(std::declval<Streambuf>().sputn(
nullptr, 0));
308 using traits_type =
typename Streambuf::traits_type;
323 if (!traits_type::eq_int_type(ch, traits_type::eof()))
324 buffer_.push_back(static_cast<char_type>(ch));
328 auto xsputn(
const char_type*
s, streamsize
count) -> streamsize
override {
335 template <
typename To,
typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>
337 #ifdef __cpp_lib_bit_cast
342 std::memcpy(static_cast<void*>(&to), &from,
sizeof(to));
349 #elif defined(__BIG_ENDIAN__)
351 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
352 return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
371 constexpr uint64_t
high() const noexcept {
return hi_; }
372 constexpr uint64_t
low() const noexcept {
return lo_; }
375 constexpr
explicit operator T()
const {
376 return static_cast<T>(lo_);
381 return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
385 return !(lhs == rhs);
389 return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;
394 return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};
399 return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
403 return {~
n.hi_, ~
n.lo_};
414 uint64_t hi = (lhs.lo_ >> 32) * rhs;
415 uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;
416 uint64_t new_lo = (hi << 32) + lo;
417 return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};
421 return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};
424 if (shift == 64)
return {0, hi_};
426 return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
429 if (shift == 64)
return {lo_, 0};
431 return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
434 return *
this = *
this >> shift;
437 uint64_t new_lo = lo_ + n.lo_;
438 uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);
451 hi_ += (lo_ <
n ? 1 : 0);
454 #if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)
455 unsigned long long carry;
456 lo_ = __builtin_addcll(lo_,
n, 0, &carry);
458 #elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)
459 unsigned long long result;
460 auto carry = __builtin_ia32_addcarryx_u64(0, lo_,
n, &result);
463 #elif defined(_MSC_VER) && defined(_M_X64)
464 auto carry = _addcarry_u64(0, lo_,
n, &lo_);
465 _addcarry_u64(carry, hi_, 0, &hi_);
468 hi_ += (lo_ <
n ? 1 : 0);
487 template <
typename T> constexpr
auto num_bits() ->
int {
488 return std::numeric_limits<T>::digits;
496 template <
typename To,
typename From, FMT_ENABLE_IF(sizeof(To) >
sizeof(From))>
498 constexpr
auto size =
static_cast<int>(
sizeof(From) /
sizeof(
unsigned));
500 unsigned value[
static_cast<unsigned>(
size)];
504 for (
int i = 0; i <
size; ++i)
505 result = (result << num_bits<unsigned>()) |
data.value[i];
507 for (
int i = size - 1; i >= 0; --i)
508 result = (result << num_bits<unsigned>()) |
data.value[i];
513 template <
typename UInt>
516 constexpr UInt msb_mask =
static_cast<UInt
>(1) << (num_bits<UInt>() - 1);
517 for (; (
n & msb_mask) == 0;
n <<= 1) lz++;
522 #ifdef FMT_BUILTIN_CLZ
529 #ifdef FMT_BUILTIN_CLZLL
537 #if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
538 __builtin_assume(condition);
543 template <
typename T>
548 template <
typename Char>
552 template <
typename Container>
557 #if defined(_SECURE_SCL) && _SECURE_SCL
559 template <
typename T>
using checked_ptr = stdext::checked_array_iterator<T*>;
560 template <
typename T>
575 __attribute__((no_sanitize(
"undefined")))
578 reserve(std::back_insert_iterator<Container> it,
size_t n)
581 size_t size = c.size();
586 template <
typename T>
593 template <
typename Iterator>
594 constexpr
auto reserve(Iterator& it,
size_t) -> Iterator& {
598 template <
typename OutputIt>
602 template <
typename T,
typename OutputIt>
617 -> std::back_insert_iterator<Container> {
621 template <
typename Iterator>
628 template <
typename OutputIt,
typename Size,
typename T>
631 for (Size i = 0; i <
count; ++i) *out++ =
value;
634 template <
typename T,
typename Size>
637 return fill_n<T*, Size, T>(out,
count,
value);
649 template <
typename OutChar,
typename InputIt,
typename OutputIt>
651 OutputIt out) -> OutputIt {
652 return copy_str<OutChar>(
begin,
end, out);
674 constexpr
const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
675 constexpr
const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
676 constexpr
const int shiftc[] = {0, 18, 12, 6, 0};
677 constexpr
const int shifte[] = {0, 6, 4, 2, 0};
679 int len =
"\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4"
680 [
static_cast<unsigned char>(*s) >> 3];
684 const char* next =
s + len + !len;
686 using uchar =
unsigned char;
690 *
c = uint32_t(
uchar(
s[0]) & masks[len]) << 18;
691 *
c |= uint32_t(
uchar(
s[1]) & 0x3f) << 12;
692 *
c |= uint32_t(
uchar(
s[2]) & 0x3f) << 6;
693 *
c |= uint32_t(
uchar(
s[3]) & 0x3f) << 0;
697 *e = (*
c < mins[len]) << 6;
698 *e |= ((*
c >> 11) == 0x1b) << 7;
699 *e |= (*
c > 0x10FFFF) << 8;
700 *e |= (
uchar(
s[1]) & 0xc0) >> 2;
701 *e |= (
uchar(
s[2]) & 0xc0) >> 4;
713 template <
typename F>
715 auto decode = [
f](
const char* buf_ptr,
const char*
ptr) {
716 auto cp = uint32_t();
721 return result ? (
error ? buf_ptr + 1 :
end) :
nullptr;
724 const size_t block_size = 4;
725 if (s.
size() >= block_size) {
726 for (
auto end = p + s.
size() - block_size + 1; p <
end;) {
731 if (
auto num_chars_left = s.
data() + s.
size() - p) {
732 char buf[2 * block_size - 1] = {};
733 copy_str<char>(p, p + num_chars_left,
buf);
734 const char* buf_ptr =
buf;
736 auto end = decode(buf_ptr, p);
740 }
while (buf_ptr - buf < num_chars_left);
744 template <
typename Char>
751 size_t num_code_points = 0;
753 struct count_code_points {
763 (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
764 (cp >= 0xac00 && cp <= 0xd7a3) ||
765 (cp >= 0xf900 && cp <= 0xfaff) ||
766 (cp >= 0xfe10 && cp <= 0xfe19) ||
767 (cp >= 0xfe30 && cp <= 0xfe6f) ||
768 (cp >= 0xff00 && cp <= 0xff60) ||
769 (cp >= 0xffe0 && cp <= 0xffe6) ||
770 (cp >= 0x20000 && cp <= 0x2fffd) ||
771 (cp >= 0x30000 && cp <= 0x3fffd) ||
773 (cp >= 0x1f300 && cp <= 0x1f64f) ||
775 (cp >= 0x1f900 && cp <= 0x1f9ff))));
781 return num_code_points;
786 string_view(reinterpret_cast<const char*>(
s.data()),
s.size()));
789 template <
typename Char>
791 size_t size =
s.size();
792 return n < size ?
n :
size;
797 const char*
data =
s.data();
798 size_t num_code_points = 0;
799 for (
size_t i = 0,
size =
s.size(); i !=
size; ++i) {
800 if ((data[i] & 0xc0) != 0x80 && ++num_code_points >
n)
return i;
808 string_view(reinterpret_cast<const char*>(
s.data()),
s.size()),
n);
811 template <
typename T>
struct is_integral : std::is_integral<T> {};
815 template <
typename T>
820 template <
typename T>
826 #ifndef FMT_USE_FLOAT
827 # define FMT_USE_FLOAT 1
829 #ifndef FMT_USE_DOUBLE
830 # define FMT_USE_DOUBLE 1
832 #ifndef FMT_USE_LONG_DOUBLE
833 # define FMT_USE_LONG_DOUBLE 1
836 #ifndef FMT_USE_FLOAT128
839 # if FMT_HAS_INCLUDE(<quadmath.h>)
840 # define FMT_USE_FLOAT128 1
842 # elif defined(__GNUC__)
844 # if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
845 # define FMT_USE_FLOAT128 1
848 # ifndef FMT_USE_FLOAT128
849 # define FMT_USE_FLOAT128 0
858 template <
typename T>
using is_float128 = std::is_same<T, float128>;
860 template <
typename T>
865 struct is_fast_float :
bool_constant<std::numeric_limits<T>::is_iec559 &&
866 sizeof(T) <= sizeof(double)> {};
867 template <typename T> struct is_fast_float<T, false> : std::false_type {};
869 template <typename T>
870 using is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;
872 #ifndef FMT_USE_FULL_CACHE_DRAGONBOX
873 # define FMT_USE_FULL_CACHE_DRAGONBOX 0
876 template <typename T>
877 template <typename U>
878 void buffer<T>::append(const U* begin, const U* end) {
879 while (begin != end) {
880 auto count = to_unsigned(end - begin);
881 try_reserve(size_ + count);
882 auto free_cap = capacity_ - size_;
883 if (free_cap < count) count = free_cap;
884 std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
890 template <typename T, typename Enable = void>
891 struct is_locale : std::false_type {};
892 template <typename T>
893 struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
900 enum { inline_buffer_size = 500 };
923 template <typename T, size_t SIZE = inline_buffer_size,
924 typename Allocator = std::allocator<T>>
925 class basic_memory_buffer final : public detail::buffer<T> {
933 FMT_CONSTEXPR20 void deallocate() {
934 T* data = this->data();
935 if (data != store_) alloc_.deallocate(data, this->capacity());
941 const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
942 size_t old_capacity = this->capacity();
943 size_t new_capacity = old_capacity + old_capacity / 2;
944 if (
size > new_capacity)
946 else if (new_capacity > max_size)
947 new_capacity =
size > max_size ?
size : max_size;
948 T* old_data = this->
data();
950 std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
952 std::uninitialized_copy(old_data, old_data + this->
size(),
954 this->
set(new_data, new_capacity);
958 if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
966 const Allocator& alloc = Allocator())
976 alloc_ = std::move(other.alloc_);
979 if (data == other.store_) {
980 this->
set(store_, capacity);
981 detail::copy_str<T>(other.store_, other.store_ +
size,
984 this->
set(data, capacity);
987 other.
set(other.store_, 0);
1026 void reserve(
size_t new_capacity) { this->try_reserve(new_capacity); }
1030 template <
typename ContiguousRange>
1032 append(range.data(), range.data() + range.size());
1038 template <
typename T,
size_t SIZE,
typename Allocator>
1050 #if FMT_CLANG_VERSION
1051 # pragma clang diagnostic ignored "-Wweak-vtables"
1057 using std::runtime_error::runtime_error;
1060 namespace detail_exported {
1061 #if FMT_USE_NONTYPE_TEMPLATE_ARGS
1062 template <
typename Char,
size_t N>
struct fixed_string {
1063 constexpr fixed_string(
const Char (&str)[
N]) {
1064 detail::copy_str<Char, const Char*, Char*>(
static_cast<const Char*
>(str),
1072 template <
typename Char,
size_t N>
1077 return {
s,
N - (std::char_traits<Char>::to_int_type(
s[
N - 1]) == 0 ? 1 : 0)};
1079 template <
typename Char>
1082 return {
s.
data(),
s.size()};
1097 template <
typename Visitor>
auto visit(Visitor&& vis) -> decltype(vis(0)) {
1106 std::string separator_;
1107 std::string grouping_;
1108 std::string decimal_point_;
1119 std::initializer_list<unsigned char>
g = {3},
1121 : separator_(sep.data(), sep.size()),
1122 grouping_(
g.begin(),
g.end()),
1127 return do_put(out, val, specs);
1144 template <
typename T>
1154 template <
typename T>
1159 template <
typename T>
1162 #define FMT_POWERS_OF_10(factor) \
1163 factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
1164 (factor)*1000000, (factor)*10000000, (factor)*100000000, \
1170 return &
"0001020304050607080910111213141516171819"
1171 "2021222324252627282930313233343536373839"
1172 "4041424344454647484950515253545556575859"
1173 "6061626364656667686970717273747576777879"
1174 "8081828384858687888990919293949596979899"[value * 2];
1178 template <
typename Char,
typename Sign> constexpr Char
sign(
Sign s) {
1179 #if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
1182 return static_cast<Char
>(
"\0-+ "[
s]);
1191 if (
n < 10)
return count;
1192 if (
n < 100)
return count + 1;
1193 if (
n < 1000)
return count + 2;
1194 if (
n < 10000)
return count + 3;
1205 #ifdef FMT_BUILTIN_CLZLL
1208 inline auto do_count_digits(uint64_t
n) ->
int {
1213 static constexpr uint8_t bsr2log10[] = {
1214 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
1215 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
1216 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
1217 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
1218 auto t = bsr2log10[FMT_BUILTIN_CLZLL(
n | 1) ^ 63];
1219 static constexpr
const uint64_t zero_or_powers_of_10[] = {
1221 10000000000000000000ULL};
1222 return t - (
n < zero_or_powers_of_10[
t]);
1229 #ifdef FMT_BUILTIN_CLZLL
1231 return do_count_digits(
n);
1238 template <
int BITS,
typename UInt>
1240 #ifdef FMT_BUILTIN_CLZ
1242 return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(
n) | 1) ^ 31) / BITS + 1;
1249 }
while ((m >>= BITS) != 0);
1254 #ifdef FMT_BUILTIN_CLZ
1257 FMT_INLINE auto do_count_digits(uint32_t
n) ->
int {
1260 # define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T)
1261 static constexpr uint64_t
table[] = {
1262 FMT_INC(0), FMT_INC(0), FMT_INC(0),
1263 FMT_INC(10), FMT_INC(10), FMT_INC(10),
1264 FMT_INC(100), FMT_INC(100), FMT_INC(100),
1265 FMT_INC(1000), FMT_INC(1000), FMT_INC(1000),
1266 FMT_INC(10000), FMT_INC(10000), FMT_INC(10000),
1267 FMT_INC(100000), FMT_INC(100000), FMT_INC(100000),
1268 FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000),
1269 FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000),
1270 FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000),
1271 FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000),
1272 FMT_INC(1000000000), FMT_INC(1000000000)
1274 auto inc = table[FMT_BUILTIN_CLZ(
n | 1) ^ 31];
1275 return static_cast<int>((
n + inc) >> 32);
1281 #ifdef FMT_BUILTIN_CLZ
1283 return do_count_digits(
n);
1289 template <
typename Int> constexpr
auto digits10() noexcept ->
int {
1300 template <
typename Char>
1302 template <
typename Char>
1312 template <
typename Char>
1315 return Char(decimal_point_impl<char>(loc));
1318 return decimal_point_impl<wchar_t>(loc);
1322 template <
typename Char>
auto equal2(
const Char* lhs,
const char* rhs) ->
bool {
1323 return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
1325 inline auto equal2(
const char* lhs,
const char* rhs) ->
bool {
1326 return memcmp(lhs, rhs, 2) == 0;
1330 template <
typename Char>
1333 memcpy(dst, src, 2);
1336 *dst++ =
static_cast<Char
>(*src++);
1337 *dst =
static_cast<Char
>(*src);
1348 template <
typename Char,
typename UInt>
1354 while (value >= 100) {
1363 *--out =
static_cast<Char
>(
'0' +
value);
1371 template <
typename Char,
typename UInt,
typename Iterator,
1376 Char
buffer[digits10<UInt>() + 1] = {};
1378 return {out, detail::copy_str_noinline<Char>(
buffer,
end, out)};
1381 template <
unsigned BASE_BITS,
typename Char,
typename UInt>
1383 bool upper =
false) -> Char* {
1387 const char* digits =
upper ?
"0123456789ABCDEF" :
"0123456789abcdef";
1388 unsigned digit =
static_cast<unsigned>(value & ((1 << BASE_BITS) - 1));
1389 *--
buffer =
static_cast<Char
>(BASE_BITS < 4 ? static_cast<char>(
'0' + digit)
1391 }
while ((value >>= BASE_BITS) != 0);
1395 template <
unsigned BASE_BITS,
typename Char,
typename It,
typename UInt>
1403 char buffer[num_bits<UInt>() / BASE_BITS + 1];
1405 return detail::copy_str_noinline<Char>(
buffer, buffer + num_digits, out);
1416 auto size() const ->
size_t {
return buffer_.size() - 1; }
1417 auto c_str() const -> const
wchar_t* {
return &buffer_[0]; }
1418 auto str() const -> std::wstring {
return {&buffer_[0],
size()}; }
1422 template <
typename WChar,
typename Buffer = memory_buffer>
1430 static_assert(
sizeof(WChar) == 2 ||
sizeof(WChar) == 4,
1431 "Expect utf16 or utf32");
1434 FMT_THROW(std::runtime_error(
sizeof(WChar) == 2 ?
"invalid utf16"
1435 :
"invalid utf32"));
1438 size_t size()
const {
return buffer_.size() - 1; }
1439 const char*
c_str()
const {
return &buffer_[0]; }
1440 std::string
str()
const {
return std::string(&buffer_[0],
size()); }
1446 if (!
convert(buffer_, s))
return false;
1447 buffer_.push_back(0);
1451 for (
auto p = s.
begin(); p != s.
end(); ++p) {
1452 uint32_t
c =
static_cast<uint32_t
>(*p);
1453 if (
sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {
1456 if (p == s.
end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {
1459 c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;
1462 buf.push_back(static_cast<char>(c));
1463 }
else if (c < 0x800) {
1464 buf.push_back(static_cast<char>(0xc0 | (c >> 6)));
1465 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1466 }
else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {
1467 buf.push_back(static_cast<char>(0xe0 | (c >> 12)));
1468 buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1469 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1470 }
else if (c >= 0x10000 && c <= 0x10ffff) {
1471 buf.push_back(static_cast<char>(0xf0 | (c >> 18)));
1472 buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));
1473 buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));
1474 buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));
1484 inline uint128_fallback
umul128(uint64_t x, uint64_t y) noexcept {
1486 auto p =
static_cast<uint128_opt>(
x) * static_cast<uint128_opt>(y);
1487 return {
static_cast<uint64_t
>(p >> 64), static_cast<uint64_t>(p)};
1488 #elif defined(_MSC_VER) && defined(_M_X64)
1489 auto result = uint128_fallback();
1493 const uint64_t
mask =
static_cast<uint64_t
>(max_value<uint32_t>());
1495 uint64_t
a = x >> 32;
1496 uint64_t
b = x &
mask;
1497 uint64_t
c = y >> 32;
1498 uint64_t d = y &
mask;
1500 uint64_t ac = a *
c;
1501 uint64_t bc = b *
c;
1502 uint64_t ad = a * d;
1503 uint64_t bd = b * d;
1507 return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
1508 (intermediate << 32) + (bd &
mask)};
1512 namespace dragonbox {
1516 FMT_ASSERT(e <= 2620 && e >= -2620,
"too large exponent");
1517 static_assert((-1 >> 1) == -1,
"right shift is not arithmetic");
1518 return (e * 315653) >> 20;
1522 FMT_ASSERT(e <= 1233 && e >= -1233,
"too large exponent");
1523 return (e * 1741647) >> 19;
1529 auto p =
static_cast<uint128_opt>(
x) * static_cast<uint128_opt>(y);
1530 return static_cast<uint64_t
>(p >> 64);
1531 #elif defined(_MSC_VER) && defined(_M_X64)
1532 return __umulh(x, y);
1541 uint128_fallback y) noexcept {
1542 uint128_fallback
r =
umul128(x, y.high());
1554 static const int exponent_bits = 8;
1555 static const int kappa = 1;
1556 static const int big_divisor = 100;
1557 static const int small_divisor = 10;
1558 static const int min_k = -31;
1559 static const int max_k = 46;
1560 static const int shorter_interval_tie_lower_threshold = -35;
1561 static const int shorter_interval_tie_upper_threshold = -35;
1566 static const int exponent_bits = 11;
1567 static const int kappa = 2;
1568 static const int big_divisor = 1000;
1569 static const int small_divisor = 100;
1570 static const int min_k = -292;
1571 static const int max_k = 341;
1572 static const int shorter_interval_tie_lower_threshold = -77;
1573 static const int shorter_interval_tie_upper_threshold = -77;
1577 template <
typename T>
1579 std::numeric_limits<T>::digits == 113 ||
1582 static const int exponent_bits = 15;
1586 template <
typename T>
1603 return std::numeric_limits<Float>::digits != 64;
1610 return is_float128<Float>() ? 112
1611 : (std::numeric_limits<Float>::digits -
1612 (has_implicit_bit<Float>() ? 1 : 0));
1615 template <
typename Float>
1620 << num_significand_bits<Float>();
1624 return is_float128<Float>() ? 16383
1625 : std::numeric_limits<Float>::max_exponent - 1;
1629 template <
typename Char,
typename It>
1631 FMT_ASSERT(-10000 < exp && exp < 10000,
"exponent out of range");
1633 *it++ =
static_cast<Char
>(
'-');
1636 *it++ =
static_cast<Char
>(
'+');
1640 if (exp >= 1000) *it++ =
static_cast<Char
>(top[0]);
1641 *it++ =
static_cast<Char
>(top[1]);
1645 *it++ =
static_cast<Char
>(d[0]);
1646 *it++ =
static_cast<Char
>(d[1]);
1656 static_cast<int>(
sizeof(F) * num_bits<unsigned char>());
1659 constexpr
basic_fp(uint64_t f_val,
int e_val) :
f(f_val), e(e_val) {}
1667 static_assert(std::numeric_limits<Float>::digits <= 113,
"unsupported FP");
1670 const auto num_float_significand_bits =
1671 detail::num_significand_bits<Float>();
1672 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
1673 const auto significand_mask = implicit_bit - 1;
1675 f =
static_cast<F
>(u & significand_mask);
1676 auto biased_e =
static_cast<int>((u & exponent_mask<Float>()) >>
1677 num_float_significand_bits);
1680 auto is_predecessor_closer = f == 0 && biased_e > 1;
1683 else if (has_implicit_bit<Float>())
1684 f += static_cast<F>(implicit_bit);
1685 e = biased_e - exponent_bias<Float>() - num_float_significand_bits;
1686 if (!has_implicit_bit<Float>()) ++e;
1687 return is_predecessor_closer;
1692 static_assert(std::numeric_limits<double>::is_iec559,
"unsupported FP");
1693 return assign(static_cast<double>(n));
1700 template <
int SHIFT = 0,
typename F>
1703 const auto implicit_bit = F(1) << num_significand_bits<double>();
1704 const auto shifted_implicit_bit = implicit_bit << SHIFT;
1705 while ((value.
f & shifted_implicit_bit) == 0) {
1711 num_significand_bits<double>() - SHIFT - 1;
1720 auto product =
static_cast<__uint128_t
>(lhs) * rhs;
1721 auto f =
static_cast<uint64_t
>(product >> 64);
1722 return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ?
f + 1 :
f;
1725 uint64_t mask = (1ULL << 32) - 1;
1726 uint64_t a = lhs >> 32, b = lhs &
mask;
1727 uint64_t c = rhs >> 32, d = rhs &
mask;
1728 uint64_t ac = a *
c, bc = b *
c, ad = a * d, bd = b * d;
1730 uint64_t mid = (bd >> 32) + (ad & mask) + (bc &
mask) + (1U << 31);
1731 return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
1742 static constexpr uint64_t pow10_significands[87] = {
1743 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
1744 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
1745 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
1746 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
1747 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
1748 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
1749 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
1750 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
1751 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
1752 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
1753 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
1754 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
1755 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
1756 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
1757 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
1758 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
1759 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
1760 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
1761 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
1762 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
1763 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
1764 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
1765 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
1766 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
1767 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
1768 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
1769 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
1770 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
1771 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
1774 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1775 # pragma GCC diagnostic push
1776 # pragma GCC diagnostic ignored "-Wnarrowing"
1780 static constexpr int16_t pow10_exponents[87] = {
1781 -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
1782 -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
1783 -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
1784 -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
1785 -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
1786 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
1787 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
1788 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
1789 #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
1790 # pragma GCC diagnostic pop
1793 static constexpr uint64_t power_of_10_64[20] = {
1795 10000000000000000000ULL};
1800 static constexpr uint32_t fractional_part_rounding_thresholds[8] = {
1812 #if FMT_CPLUSPLUS < 201703L
1816 template <
typename T>
1826 int& pow10_exponent) {
1827 const int shift = 32;
1829 const int64_t significand = 0x4d104d427de7fbcc;
1830 int index =
static_cast<int>(
1832 ((int64_t(1) << shift) - 1))
1836 const int first_dec_exp = -348;
1838 const int dec_exp_step = 8;
1839 index = (index - first_dec_exp - 1) / dec_exp_step + 1;
1840 pow10_exponent = first_dec_exp + index * dec_exp_step;
1847 template <
typename T>
1850 std::numeric_limits<T>::digits ==
1851 std::numeric_limits<double>::digits,
1854 template <
typename T>
1859 template <
typename OutputIt,
typename Char>
1861 const fill_t<Char>&
fill) -> OutputIt {
1862 auto fill_size =
fill.size();
1864 auto data =
fill.data();
1865 for (
size_t i = 0; i <
n; ++i)
1866 it = copy_str<Char>(data, data + fill_size, it);
1876 size_t size,
size_t width, F&&
f) -> OutputIt {
1879 size_t padding = spec_width >
width ? spec_width -
width : 0;
1882 auto* shifts = align ==
align::left ?
"\x1f\x1f\x00\x01" :
"\x00\x1f\x00\x01";
1883 size_t left_padding = padding >> shifts[specs.
align];
1884 size_t right_padding = padding - left_padding;
1885 auto it =
reserve(out, size + padding * specs.
fill.size());
1886 if (left_padding != 0) it =
fill(it, left_padding, specs.
fill);
1888 if (right_padding != 0) it =
fill(it, right_padding, specs.
fill);
1895 size_t size, F&&
f) -> OutputIt {
1896 return write_padded<align>(out, specs,
size,
size,
f);
1899 template <align::type align = align::left,
typename Char,
typename OutputIt>
1902 return write_padded<align>(
1903 out, specs,
bytes.size(), [
bytes](reserve_iterator<OutputIt> it) {
1904 const char* data =
bytes.data();
1905 return copy_str<Char>(
data, data +
bytes.size(), it);
1909 template <
typename Char,
typename OutputIt,
typename UIntPtr>
1912 int num_digits = count_digits<4>(
value);
1914 auto write = [=](reserve_iterator<OutputIt> it) {
1915 *it++ =
static_cast<Char
>(
'0');
1916 *it++ =
static_cast<Char
>(
'x');
1917 return format_uint<4, Char>(it,
value, num_digits);
1919 return specs ? write_padded<align::right>(out, *specs,
size,
write)
1927 return cp < 0x20 || cp == 0x7f || cp ==
'"' || cp ==
'\\' ||
1937 template <
typename Char>
1940 std::make_unsigned<Char>,
1943 template <
typename Char>
1948 if (
const_check(
sizeof(Char) == 1) && cp >= 0x80)
continue;
1951 return {
begin,
nullptr, 0};
1961 result = {sv.
begin(), sv.
end(), cp};
1969 #define FMT_STRING_IMPL(s, base, explicit) \
1973 struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
1974 using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t<decltype(s[0])>; \
1975 FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
1976 operator fmt::basic_string_view<char_type>() const { \
1977 return fmt::detail_exported::compile_string_to_view<char_type>(s); \
1980 return FMT_COMPILE_STRING(); \
1993 #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
1995 template <
size_t w
idth,
typename Char,
typename OutputIt>
1997 *out++ =
static_cast<Char
>(
'\\');
1998 *out++ =
static_cast<Char
>(prefix);
2002 return copy_str<Char>(
buf, buf +
width, out);
2005 template <
typename OutputIt,
typename Char>
2008 auto c =
static_cast<Char
>(escape.cp);
2009 switch (escape.cp) {
2011 *out++ =
static_cast<Char
>(
'\\');
2012 c =
static_cast<Char
>(
'n');
2015 *out++ =
static_cast<Char
>(
'\\');
2016 c =
static_cast<Char
>(
'r');
2019 *out++ =
static_cast<Char
>(
'\\');
2020 c =
static_cast<Char
>(
't');
2027 *out++ =
static_cast<Char
>(
'\\');
2030 if (escape.cp < 0x100) {
2031 return write_codepoint<2, Char>(out,
'x', escape.cp);
2033 if (escape.cp < 0x10000) {
2034 return write_codepoint<4, Char>(out,
'u', escape.cp);
2036 if (escape.cp < 0x110000) {
2037 return write_codepoint<8, Char>(out,
'U', escape.cp);
2040 escape.begin,
to_unsigned(escape.end - escape.begin))) {
2041 out = write_codepoint<2, Char>(out,
'x',
2042 static_cast<uint32_t
>(escape_char) & 0xFF);
2050 template <
typename Char,
typename OutputIt>
2053 *out++ =
static_cast<Char
>(
'"');
2054 auto begin = str.begin(),
end = str.end();
2057 out = copy_str<Char>(
begin, escape.begin, out);
2060 out = write_escaped_cp<OutputIt, Char>(out, escape);
2062 *out++ =
static_cast<Char
>(
'"');
2066 template <
typename Char,
typename OutputIt>
2068 *out++ =
static_cast<Char
>(
'\'');
2069 if ((
needs_escape(static_cast<uint32_t>(
v)) &&
v != static_cast<Char>(
'"')) ||
2070 v ==
static_cast<Char
>(
'\'')) {
2076 *out++ =
static_cast<Char
>(
'\'');
2080 template <
typename Char,
typename OutputIt>
2084 return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
2090 template <
typename Char,
typename OutputIt>
2095 using unsigned_type =
2099 :
write(out, static_cast<unsigned_type>(value), specs, loc);
2110 : size((prefix >> 24) +
to_unsigned(num_digits)), padding(0) {
2111 if (specs.
align == align::numeric) {
2117 }
else if (specs.
precision > num_digits) {
2128 template <
typename OutputIt,
typename Char,
typename W>
2132 W write_digits) -> OutputIt {
2137 for (
unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2138 *it++ = static_cast<Char>(p & 0xff);
2143 return write_padded<align::right>(
2144 out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
2145 for (
unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
2146 *it++ = static_cast<Char>(p & 0xff);
2148 return write_digits(it);
2154 std::string grouping_;
2158 std::string::const_iterator group;
2161 next_state initial_state()
const {
return {grouping_.begin(), 0}; }
2164 int next(next_state&
state)
const {
2165 if (thousands_sep_.empty())
return max_value<int>();
2166 if (state.group == grouping_.end())
return state.pos += grouping_.back();
2167 if (*state.group <= 0 || *state.group == max_value<char>())
2168 return max_value<int>();
2169 state.pos += *state.group++;
2175 if (!localized)
return;
2176 auto sep = thousands_sep<Char>(loc);
2177 grouping_ = sep.grouping;
2178 if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);
2181 : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}
2187 auto state = initial_state();
2188 while (num_digits > next(state)) ++
count;
2193 template <
typename Out,
typename C>
2195 auto num_digits =
static_cast<int>(digits.
size());
2198 auto state = initial_state();
2199 while (
int i = next(state)) {
2200 if (i >= num_digits)
break;
2201 separators.push_back(i);
2203 for (
int i = 0, sep_index = static_cast<int>(separators.size() - 1);
2204 i < num_digits; ++i) {
2205 if (num_digits - i == separators[sep_index]) {
2207 copy_str<Char>(thousands_sep_.data(),
2208 thousands_sep_.data() + thousands_sep_.size(), out);
2211 *out++ =
static_cast<Char
>(digits[
to_unsigned(i)]);
2218 template <
typename OutputIt,
typename UInt,
typename Char>
2226 unsigned size =
to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
2227 grouping.count_separators(num_digits));
2228 return write_padded<align::right>(
2229 out, specs,
size,
size, [&](reserve_iterator<OutputIt> it) {
2231 char sign =
static_cast<char>(prefix);
2232 *it++ =
static_cast<Char
>(
sign);
2241 template <
typename OutputIt,
typename Char>
2243 locale_ref) ->
bool {
2248 prefix |= prefix != 0 ? value << 8 :
value;
2249 prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
2257 template <
typename T>
2263 prefix = 0x01000000 |
'-';
2264 abs_value = 0 - abs_value;
2266 constexpr
const unsigned prefixes[4] = {0, 0, 0x1000000u |
'+',
2268 prefix = prefixes[
sign];
2270 return {abs_value, prefix};
2289 auto operator()(T) ->
bool {
2294 template <
typename Char,
typename OutputIt,
typename T>
2297 locale_ref) -> OutputIt {
2299 auto abs_value =
arg.abs_value;
2300 auto prefix =
arg.prefix;
2301 switch (specs.
type) {
2306 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2307 return format_decimal<Char>(it, abs_value, num_digits).
end;
2314 prefix_append(prefix,
unsigned(upper ?
'X' :
'x') << 8 |
'0');
2315 int num_digits = count_digits<4>(abs_value);
2317 out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
2318 return format_uint<4, Char>(it, abs_value, num_digits,
upper);
2325 prefix_append(prefix,
unsigned(upper ?
'B' :
'b') << 8 |
'0');
2326 int num_digits = count_digits<1>(abs_value);
2327 return write_int(out, num_digits, prefix, specs,
2328 [=](reserve_iterator<OutputIt> it) {
2329 return format_uint<1, Char>(it, abs_value, num_digits);
2333 int num_digits = count_digits<3>(abs_value);
2336 if (specs.
alt && specs.
precision <= num_digits && abs_value != 0)
2338 return write_int(out, num_digits, prefix, specs,
2339 [=](reserve_iterator<OutputIt> it) {
2340 return format_uint<3, Char>(it, abs_value, num_digits);
2344 return write_char(out, static_cast<Char>(abs_value), specs);
2350 template <
typename Char,
typename OutputIt,
typename T>
2353 locale_ref loc) -> OutputIt {
2356 template <
typename Char,
typename OutputIt,
typename T,
2359 std::is_same<OutputIt, buffer_appender<Char>>::value)>
2362 locale_ref loc) -> OutputIt {
2368 template <
typename Char,
typename OutputIt,
typename T,
2371 !std::is_same<OutputIt, buffer_appender<Char>>::value)>
2374 locale_ref loc) -> OutputIt {
2412 it.count_ +=
static_cast<size_t>(
n);
2419 template <
typename Char,
typename OutputIt>
2422 auto data =
s.data();
2423 auto size =
s.size();
2428 if (specs.
width != 0) {
2435 [=](reserve_iterator<OutputIt> it) {
2437 return copy_str<Char>(
data, data +
size, it);
2440 template <
typename Char,
typename OutputIt>
2445 return write(out,
s, specs);
2447 template <
typename Char,
typename OutputIt>
2453 : write_ptr<Char>(out, bit_cast<uintptr_t>(
s), &specs);
2456 template <
typename Char,
typename OutputIt,
typename T,
2464 if (negative) abs_value = ~abs_value + 1;
2466 auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
2468 if (
auto ptr = to_pointer<Char>(it, size)) {
2469 if (negative) *
ptr++ =
static_cast<Char
>(
'-');
2470 format_decimal<Char>(
ptr, abs_value, num_digits);
2473 if (negative) *it++ =
static_cast<Char
>(
'-');
2474 it = format_decimal<Char>(it, abs_value, num_digits).
end;
2496 template <
typename ErrorHandler = error_handler,
typename Char>
2503 switch (specs.
type) {
2534 eh.on_error(
"invalid format specifier");
2540 template <
typename Char,
typename OutputIt>
2545 isnan ? (fspecs.upper ?
"NAN" :
"nan") : (fspecs.upper ?
"INF" :
"inf");
2546 constexpr
size_t str_size = 3;
2547 auto sign = fspecs.sign;
2548 auto size = str_size + (
sign ? 1 : 0);
2550 const bool is_zero_fill =
2551 specs.
fill.size() == 1 && *specs.
fill.data() ==
static_cast<Char
>(
'0');
2552 if (is_zero_fill) specs.
fill[0] =
static_cast<Char
>(
' ');
2553 return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
2554 if (
sign) *it++ = detail::sign<Char>(
sign);
2555 return copy_str<Char>(str, str + str_size, it);
2567 return f.significand_size;
2569 template <
typename T>
2574 template <
typename Char,
typename OutputIt>
2576 int significand_size) -> OutputIt {
2577 return copy_str<Char>(significand, significand + significand_size, out);
2579 template <
typename Char,
typename OutputIt,
typename UInt>
2581 int significand_size) -> OutputIt {
2582 return format_decimal<Char>(out, significand, significand_size).
end;
2584 template <
typename Char,
typename OutputIt,
typename T,
typename Grouping>
2586 int significand_size,
int exponent,
2587 const Grouping& grouping) -> OutputIt {
2588 if (!grouping.has_separator()) {
2589 out = write_significand<Char>(out, significand, significand_size);
2593 write_significand<char>(
appender(
buffer), significand, significand_size);
2598 template <
typename Char,
typename UInt,
2604 out += significand_size + 1;
2606 int floating_size = significand_size - integral_size;
2607 for (
int i = floating_size / 2; i > 0; --i) {
2609 copy2(out,
digits2(static_cast<std::size_t>(significand % 100)));
2612 if (floating_size % 2 != 0) {
2613 *--out =
static_cast<Char
>(
'0' + significand % 10);
2621 template <
typename OutputIt,
typename UInt,
typename Char,
2624 int significand_size,
int integral_size,
2627 Char
buffer[digits10<UInt>() + 2];
2630 return detail::copy_str_noinline<Char>(
buffer,
end, out);
2633 template <
typename OutputIt,
typename Char>
2635 int significand_size,
int integral_size,
2637 out = detail::copy_str_noinline<Char>(significand,
2638 significand + integral_size, out);
2641 return detail::copy_str_noinline<Char>(significand + integral_size,
2642 significand + significand_size, out);
2645 template <
typename OutputIt,
typename Char,
typename T,
typename Grouping>
2647 int significand_size,
int integral_size,
2649 const Grouping& grouping) -> OutputIt {
2650 if (!grouping.has_separator()) {
2659 return detail::copy_str_noinline<Char>(
buffer.data() + integral_size,
2663 template <
typename OutputIt,
typename DecimalFP,
typename Char,
2669 auto significand =
f.significand;
2671 const Char
zero =
static_cast<Char
>(
'0');
2672 auto sign = fspecs.sign;
2674 using iterator = reserve_iterator<OutputIt>;
2677 fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>(
'.');
2679 int output_exp =
f.exponent + significand_size - 1;
2680 auto use_exp_format = [=]() {
2686 return output_exp < exp_lower ||
2687 output_exp >= (fspecs.precision > 0 ? fspecs.precision :
exp_upper);
2689 if (use_exp_format()) {
2691 if (fspecs.showpoint) {
2692 num_zeros = fspecs.precision - significand_size;
2693 if (num_zeros < 0) num_zeros = 0;
2695 }
else if (significand_size == 1) {
2696 decimal_point = Char();
2698 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2700 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2702 size +=
to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2703 char exp_char = fspecs.upper ?
'E' :
'e';
2704 auto write = [=](iterator it) {
2705 if (
sign) *it++ = detail::sign<Char>(
sign);
2710 *it++ =
static_cast<Char
>(exp_char);
2711 return write_exponent<Char>(output_exp, it);
2713 return specs.
width > 0 ? write_padded<align::right>(out, specs,
size,
write)
2717 int exp =
f.exponent + significand_size;
2718 if (
f.exponent >= 0) {
2721 int num_zeros = fspecs.precision - exp;
2723 if (fspecs.showpoint) {
2726 if (num_zeros > 0) size +=
to_unsigned(num_zeros);
2728 auto grouping = Grouping(loc, fspecs.locale);
2729 size +=
to_unsigned(grouping.count_separators(exp));
2730 return write_padded<align::right>(out, specs,
size, [&](iterator it) {
2731 if (
sign) *it++ = detail::sign<Char>(
sign);
2732 it = write_significand<Char>(it, significand, significand_size,
2733 f.exponent, grouping);
2734 if (!fspecs.showpoint)
return it;
2738 }
else if (exp > 0) {
2740 int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
2741 size += 1 +
to_unsigned(num_zeros > 0 ? num_zeros : 0);
2742 auto grouping = Grouping(loc, fspecs.locale);
2743 size +=
to_unsigned(grouping.count_separators(exp));
2744 return write_padded<align::right>(out, specs,
size, [&](iterator it) {
2745 if (
sign) *it++ = detail::sign<Char>(
sign);
2747 decimal_point, grouping);
2752 int num_zeros = -exp;
2753 if (significand_size == 0 && fspecs.precision >= 0 &&
2754 fspecs.precision < num_zeros) {
2755 num_zeros = fspecs.precision;
2757 bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
2758 size += 1 + (pointy ? 1 : 0) +
to_unsigned(num_zeros);
2759 return write_padded<align::right>(out, specs,
size, [&](iterator it) {
2760 if (
sign) *it++ = detail::sign<Char>(
sign);
2762 if (!pointy)
return it;
2765 return write_significand<Char>(it, significand, significand_size);
2777 template <
typename Out,
typename C>
2783 template <
typename OutputIt,
typename DecimalFP,
typename Char>
2797 template <
typename T> constexpr
bool isnan(T value) {
2798 return !(value >=
value);
2801 template <
typename T,
typename Enable =
void>
2804 template <
typename T>
2806 : std::true_type {};
2811 constexpr T inf = T(std::numeric_limits<double>::infinity());
2814 return std::isfinite(value);
2818 T inf = T(std::numeric_limits<double>::infinity());
2826 #ifdef __cpp_if_constexpr
2827 if constexpr (std::numeric_limits<double>::is_iec559) {
2829 return (bits >> (num_bits<uint64_t>() - 1)) != 0;
2849 if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
2852 if (remainder >= error &&
2853 remainder - error >= divisor - (remainder - error)) {
2875 uint64_t remainder, uint64_t error,
2878 buf[size++] = digit;
2885 if (error >= divisor || error >= divisor - error)
return digits::error;
2893 for (
int i = size - 1; i > 0 &&
buf[i] >
'9'; --i) {
2911 if (exp10 > 0 && precision > max_value<int>() - exp10)
2923 const fp one(1ULL << -value.e, value.e);
2927 auto integral =
static_cast<uint32_t
>(value.f >> -one.
e);
2931 uint64_t fractional = value.f & (one.
f - 1);
2934 if (handler.fixed) {
2938 if (handler.precision <= 0) {
2951 auto divmod_integral = [&](uint32_t
divisor) {
2959 divmod_integral(1000000000);
2962 divmod_integral(100000000);
2965 divmod_integral(10000000);
2968 divmod_integral(1000000);
2971 divmod_integral(100000);
2974 divmod_integral(10000);
2977 divmod_integral(1000);
2980 divmod_integral(100);
2983 divmod_integral(10);
2990 FMT_ASSERT(
false,
"invalid number of digits");
2993 auto remainder = (
static_cast<uint64_t
>(integral) << -one.
e) + fractional;
2994 auto result = handler.on_digit(static_cast<char>(
'0' + digit),
2996 remainder,
error,
true);
3003 char digit =
static_cast<char>(
'0' + (fractional >> -one.
e));
3004 fractional &= one.
f - 1;
3006 auto result = handler.on_digit(digit, one.
f, fractional,
error,
false);
3015 using bigit = uint32_t;
3016 using double_bigit = uint64_t;
3017 enum { bigits_capacity = 32 };
3028 static constexpr
const int bigit_bits = num_bits<bigit>();
3032 FMT_CONSTEXPR20 void subtract_bigits(
int index, bigit other, bigit& borrow) {
3033 auto result =
static_cast<double_bigit
>((*this)[
index]) - other - borrow;
3035 borrow =
static_cast<bigit
>(
result >> (bigit_bits * 2 - 1));
3039 int num_bigits =
static_cast<int>(bigits_.size()) - 1;
3040 while (num_bigits > 0 && (*
this)[num_bigits] == 0) --num_bigits;
3046 FMT_ASSERT(other.exp_ >= exp_,
"unaligned bigints");
3049 int i = other.exp_ - exp_;
3050 for (
size_t j = 0, n = other.bigits_.
size();
j !=
n; ++i, ++
j)
3051 subtract_bigits(i, other.bigits_[
j], borrow);
3052 while (borrow > 0) subtract_bigits(i, 0, borrow);
3053 remove_leading_zeros();
3057 const double_bigit wide_value =
value;
3059 for (
size_t i = 0, n = bigits_.size(); i <
n; ++i) {
3060 double_bigit
result = bigits_[i] * wide_value + carry;
3061 bigits_[i] =
static_cast<bigit
>(
result);
3062 carry =
static_cast<bigit
>(result >> bigit_bits);
3064 if (carry != 0) bigits_.push_back(carry);
3072 const int shift = num_bits<half_uint>() - bigit_bits;
3073 const UInt
lower =
static_cast<half_uint
>(
value);
3074 const UInt
upper = value >> num_bits<half_uint>();
3076 for (
size_t i = 0, n = bigits_.size(); i <
n; ++i) {
3077 UInt
result = lower * bigits_[i] +
static_cast<bigit
>(carry);
3078 carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
3079 (carry >> bigit_bits);
3080 bigits_[i] =
static_cast<bigit
>(
result);
3082 while (carry != 0) {
3083 bigits_.push_back(static_cast<bigit>(carry));
3084 carry >>= bigit_bits;
3091 size_t num_bigits = 0;
3093 bigits_[num_bigits++] =
static_cast<bigit
>(
n);
3096 bigits_.resize(num_bigits);
3108 auto size = other.bigits_.
size();
3109 bigits_.resize(size);
3110 auto data = other.bigits_.
data();
3121 return static_cast<int>(bigits_.size()) + exp_;
3126 exp_ += shift / bigit_bits;
3127 shift %= bigit_bits;
3128 if (shift == 0)
return *
this;
3130 for (
size_t i = 0, n = bigits_.size(); i <
n; ++i) {
3131 bigit c = bigits_[i] >> (bigit_bits - shift);
3132 bigits_[i] = (bigits_[i] << shift) + carry;
3135 if (carry != 0) bigits_.push_back(carry);
3147 if (num_lhs_bigits != num_rhs_bigits)
3148 return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
3149 int i =
static_cast<int>(lhs.bigits_.
size()) - 1;
3150 int j =
static_cast<int>(rhs.bigits_.
size()) - 1;
3152 if (end < 0) end = 0;
3153 for (; i >=
end; --i, --
j) {
3154 bigit lhs_bigit = lhs[i], rhs_bigit = rhs[
j];
3155 if (lhs_bigit != rhs_bigit)
return lhs_bigit > rhs_bigit ? 1 : -1;
3157 if (i != j)
return i > j ? 1 : -1;
3164 auto minimum = [](
int a,
int b) {
return a < b ? a :
b; };
3165 auto maximum = [](
int a,
int b) {
return a > b ? a :
b; };
3168 if (max_lhs_bigits + 1 < num_rhs_bigits)
return -1;
3169 if (max_lhs_bigits > num_rhs_bigits)
return 1;
3170 auto get_bigit = [](
const bigint&
n,
int i) -> bigit {
3171 return i >= n.exp_ && i < n.
num_bigits() ? n[i - n.exp_] : 0;
3173 double_bigit borrow = 0;
3174 int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_);
3175 for (
int i = num_rhs_bigits - 1; i >= min_exp; --i) {
3177 static_cast<double_bigit
>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
3178 bigit rhs_bigit = get_bigit(rhs, i);
3179 if (sum > rhs_bigit + borrow)
return 1;
3180 borrow = rhs_bigit + borrow - sum;
3181 if (borrow > 1)
return -1;
3182 borrow <<= bigit_bits;
3184 return borrow != 0 ? -1 : 0;
3190 if (exp == 0)
return *
this = 1;
3193 while (exp >= bitmask) bitmask <<= 1;
3199 while (bitmask != 0) {
3201 if ((exp & bitmask) != 0) *
this *= 5;
3208 int num_bigits =
static_cast<int>(bigits_.size());
3209 int num_result_bigits = 2 * num_bigits;
3213 for (
int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
3216 for (
int i = 0,
j = bigit_index;
j >= 0; ++i, --
j) {
3218 sum +=
static_cast<double_bigit
>(n[i]) * n[
j];
3220 (*this)[bigit_index] =
static_cast<bigit
>(sum);
3221 sum >>= num_bits<bigit>();
3224 for (
int bigit_index = num_bigits; bigit_index < num_result_bigits;
3226 for (
int j = num_bigits - 1, i = bigit_index -
j; i < num_bigits;)
3227 sum += static_cast<double_bigit>(n[i++]) * n[
j--];
3228 (*this)[bigit_index] =
static_cast<bigit
>(sum);
3229 sum >>= num_bits<bigit>();
3231 remove_leading_zeros();
3238 int exp_difference = exp_ - other.exp_;
3239 if (exp_difference <= 0)
return;
3240 int num_bigits =
static_cast<int>(bigits_.size());
3241 bigits_.resize(
to_unsigned(num_bigits + exp_difference));
3242 for (
int i = num_bigits - 1,
j = i + exp_difference; i >= 0; --i, --
j)
3243 bigits_[
j] = bigits_[i];
3244 std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
3245 exp_ -= exp_difference;
3252 if (
compare(*
this, divisor) < 0)
return 0;
3253 FMT_ASSERT(divisor.bigits_[divisor.bigits_.
size() - 1u] != 0,
"");
3257 subtract_aligned(divisor);
3259 }
while (
compare(*
this, divisor) >= 0);
3275 unsigned flags,
int num_digits,
3287 int shift = is_predecessor_closer ? 2 : 1;
3289 numerator = value.
f;
3290 numerator <<= value.
e + shift;
3293 if (is_predecessor_closer) {
3295 upper_store <<= value.
e + 1;
3296 upper = &upper_store;
3299 denominator <<= shift;
3300 }
else if (exp10 < 0) {
3302 lower.assign(numerator);
3303 if (is_predecessor_closer) {
3304 upper_store.assign(numerator);
3306 upper = &upper_store;
3308 numerator *= value.
f;
3309 numerator <<= shift;
3311 denominator <<= shift - value.
e;
3313 numerator = value.
f;
3314 numerator <<= shift;
3316 denominator <<= shift - value.
e;
3318 if (is_predecessor_closer) {
3319 upper_store = 1ULL << 1;
3320 upper = &upper_store;
3323 int even =
static_cast<int>((value.
f & 1) == 0);
3324 if (!upper) upper = &
lower;
3326 if (add_compare(numerator, *upper, denominator) + even <= 0) {
3329 if (num_digits < 0) {
3331 if (upper != &lower) *upper *= 10;
3337 if (num_digits < 0) {
3340 char* data = buf.data();
3343 bool low =
compare(numerator, lower) - even < 0;
3345 bool high = add_compare(numerator, *upper, denominator) + even > 0;
3346 data[num_digits++] =
static_cast<char>(
'0' + digit);
3349 ++data[num_digits - 1];
3351 int result = add_compare(numerator, numerator, denominator);
3353 if (result > 0 || (result == 0 && (digit % 2) != 0))
3354 ++data[num_digits - 1];
3357 exp10 -= num_digits - 1;
3362 if (upper != &lower) *upper *= 10;
3366 exp10 -= num_digits - 1;
3367 if (num_digits == 0) {
3369 auto digit = add_compare(numerator, numerator, denominator) > 0 ?
'1' :
'0';
3370 buf.push_back(digit);
3374 for (
int i = 0; i < num_digits - 1; ++i) {
3376 buf[i] =
static_cast<char>(
'0' + digit);
3380 auto result = add_compare(numerator, numerator, denominator);
3381 if (result > 0 || (result == 0 && (digit % 2) != 0)) {
3383 const auto overflow =
'0' + 10;
3384 buf[num_digits - 1] = overflow;
3386 for (
int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
3390 if (buf[0] == overflow) {
3398 buf[num_digits - 1] =
static_cast<char>(
'0' + digit);
3412 using carrier_uint =
typename info::carrier_uint;
3414 constexpr
auto num_float_significand_bits =
3415 detail::num_significand_bits<Float>();
3418 f.e += num_float_significand_bits;
3419 if (!has_implicit_bit<Float>()) --f.e;
3421 constexpr
auto num_fraction_bits =
3422 num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3423 constexpr
auto num_xdigits = (num_fraction_bits + 3) / 4;
3425 constexpr
auto leading_shift = ((num_xdigits - 1) * 4);
3426 const auto leading_mask = carrier_uint(0xF) << leading_shift;
3427 const auto leading_xdigit =
3428 static_cast<uint32_t
>((f.f & leading_mask) >> leading_shift);
3429 if (leading_xdigit > 1) f.e -= (32 -
countl_zero(leading_xdigit) - 1);
3431 int print_xdigits = num_xdigits - 1;
3432 if (precision >= 0 && print_xdigits > precision) {
3433 const int shift = ((print_xdigits - precision - 1) * 4);
3434 const auto mask = carrier_uint(0xF) << shift;
3435 const auto v =
static_cast<uint32_t
>((f.f &
mask) >> shift);
3438 const auto inc = carrier_uint(1) << (shift + 4);
3444 if (!has_implicit_bit<Float>()) {
3445 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3446 if ((f.f & implicit_bit) == implicit_bit) {
3455 char xdigits[num_bits<carrier_uint>() / 4];
3457 format_uint<4>(xdigits, f.f, num_xdigits, specs.
upper);
3460 while (print_xdigits > 0 && xdigits[print_xdigits] ==
'0') --print_xdigits;
3463 buf.push_back(specs.
upper ?
'X' :
'x');
3464 buf.push_back(xdigits[0]);
3465 if (specs.
showpoint || print_xdigits > 0 || print_xdigits < precision)
3467 buf.append(xdigits + 1, xdigits + 1 + print_xdigits);
3468 for (; print_xdigits <
precision; ++print_xdigits) buf.push_back(
'0');
3470 buf.push_back(specs.
upper ?
'P' :
'p');
3475 abs_e =
static_cast<uint32_t
>(-f.e);
3478 abs_e =
static_cast<uint32_t
>(f.e);
3489 template <
typename Float>
3499 if (precision <= 0 || !fixed) {
3509 bool use_dragon =
true;
3510 unsigned dragon_flags = 0;
3511 if (!is_fast_float<Float>()) {
3512 const auto inv_log2_10 = 0.3010299956639812;
3519 exp =
static_cast<int>(
3520 std::ceil((
f.e + count_digits<1>(
f.f) - 1) * inv_log2_10 - 1e-10));
3526 write<char>(buffer_appender<char>(
buf),
dec.significand);
3527 return dec.exponent;
3530 write<char>(buffer_appender<char>(
buf),
dec.significand);
3531 return dec.exponent;
3535 const int min_exp = -60;
3536 int cached_exp10 = 0;
3540 normalized = normalized * cached_pow;
3544 exp += handler.exp10;
3548 exp += handler.size - cached_exp10 - 1;
3549 precision = handler.precision;
3556 const uint64_t significand_mask =
3557 (
static_cast<uint64_t
>(1) << num_significand_bits<double>()) - 1;
3558 uint64_t significand = (br & significand_mask);
3559 int exponent =
static_cast<int>((br & exponent_mask<double>()) >>
3560 num_significand_bits<double>());
3562 if (exponent != 0) {
3563 exponent -= exponent_bias<double>() + num_significand_bits<double>();
3565 (
static_cast<uint64_t
>(1) << num_significand_bits<double>());
3569 FMT_ASSERT(significand != 0,
"zeros should not appear hear");
3571 FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3573 shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3574 exponent = (std::numeric_limits<double>::min_exponent -
3575 num_significand_bits<double>()) -
3577 significand <<= shift;
3585 uint64_t first_segment;
3586 bool has_more_segments;
3587 int digits_in_the_first_segment;
3591 first_segment =
r.high();
3592 has_more_segments =
r.low() != 0;
3595 if (first_segment >= 1000000000000000000ULL) {
3596 digits_in_the_first_segment = 19;
3600 digits_in_the_first_segment = 18;
3601 first_segment *= 10;
3612 if (digits_in_the_first_segment > precision) {
3615 if (precision <= 0) {
3616 exp += digits_in_the_first_segment;
3618 if (precision < 0) {
3624 if ((first_segment | static_cast<uint64_t>(has_more_segments)) >
3625 5000000000000000000ULL) {
3633 exp += digits_in_the_first_segment -
precision;
3642 const uint32_t first_subsegment =
static_cast<uint32_t
>(
3645 const uint64_t second_third_subsegments =
3646 first_segment - first_subsegment * 10000000000ULL;
3650 bool should_round_up;
3651 int number_of_digits_to_print = precision > 9 ? 9 :
precision;
3654 auto print_subsegment = [&](uint32_t subsegment,
char*
buffer) {
3655 int number_of_digits_printed = 0;
3658 if ((number_of_digits_to_print & 1) != 0) {
3664 prod = ((subsegment *
static_cast<uint64_t
>(720575941)) >> 24) + 1;
3665 digits =
static_cast<uint32_t
>(prod >> 32);
3666 *
buffer =
static_cast<char>(
'0' + digits);
3667 number_of_digits_printed++;
3677 prod = ((subsegment *
static_cast<uint64_t
>(450359963)) >> 20) + 1;
3678 digits =
static_cast<uint32_t
>(prod >> 32);
3680 number_of_digits_printed += 2;
3684 while (number_of_digits_printed < number_of_digits_to_print) {
3685 prod =
static_cast<uint32_t
>(prod) * static_cast<uint64_t>(100);
3686 digits =
static_cast<uint32_t
>(prod >> 32);
3688 number_of_digits_printed += 2;
3693 print_subsegment(first_subsegment, buf.data());
3697 if (precision <= 9) {
3711 if (precision < 9) {
3712 uint32_t fractional_part =
static_cast<uint32_t
>(prod);
3713 should_round_up = fractional_part >=
3715 [8 - number_of_digits_to_print] ||
3716 ((fractional_part >> 31) &
3717 ((digits & 1) | (second_third_subsegments != 0) |
3718 has_more_segments)) != 0;
3726 should_round_up = second_third_subsegments > 5000000000ULL ||
3727 (second_third_subsegments == 5000000000ULL &&
3728 ((digits & 1) != 0 || has_more_segments));
3737 const uint32_t second_subsegment =
3739 second_third_subsegments, 1844674407370955162ULL));
3740 const uint32_t third_subsegment =
3741 static_cast<uint32_t
>(second_third_subsegments) -
3742 second_subsegment * 10;
3744 number_of_digits_to_print = precision - 9;
3745 print_subsegment(second_subsegment, buf.data() + 9);
3748 if (precision < 18) {
3752 uint32_t fractional_part =
static_cast<uint32_t
>(prod);
3753 should_round_up = fractional_part >=
3755 [8 - number_of_digits_to_print] ||
3756 ((fractional_part >> 31) &
3757 ((digits & 1) | (third_subsegment != 0) |
3758 has_more_segments)) != 0;
3765 should_round_up = third_subsegment > 5 ||
3766 (third_subsegment == 5 &&
3767 ((digits & 1) != 0 || has_more_segments));
3772 if (should_round_up) {
3773 ++buf[precision - 1];
3774 for (
int i = precision - 1; i > 0 && buf[i] >
'9'; --i) {
3781 buf[precision++] =
'0';
3791 exp += digits_in_the_first_segment - 1;
3796 bool is_predecessor_closer = specs.
binary32
3797 ?
f.assign(static_cast<float>(value))
3798 :
f.assign(converted_value);
3803 const int max_double_digits = 767;
3804 if (precision > max_double_digits) precision = max_double_digits;
3809 auto num_digits = buf.size();
3810 while (num_digits > 0 && buf[num_digits - 1] ==
'0') {
3814 buf.try_resize(num_digits);
3818 template <
typename Char,
typename OutputIt,
typename T>
3825 fspecs.
sign = sign::minus;
3827 }
else if (fspecs.
sign == sign::minus) {
3834 if (specs.align == align::numeric && fspecs.
sign) {
3836 *it++ = detail::sign<Char>(fspecs.
sign);
3839 if (specs.width != 0) --specs.width;
3846 return write_bytes<align::right>(out, {buffer.
data(), buffer.
size()},
3853 if (precision == max_value<int>())
3867 template <
typename Char,
typename OutputIt,
typename T,
3870 locale_ref loc = {}) -> OutputIt {
3877 template <
typename Char,
typename OutputIt,
typename T,
3885 fspecs.sign = sign::minus;
3892 floaty_uint mask = exponent_mask<floaty>();
3893 if ((bit_cast<floaty_uint>(value) &
mask) == mask)
3900 template <
typename Char,
typename OutputIt,
typename T,
3903 inline auto write(OutputIt out, T value) -> OutputIt {
3907 template <
typename Char,
typename OutputIt>
3914 template <
typename Char,
typename OutputIt>
3917 auto it =
reserve(out, value.size());
3918 it = copy_str_noinline<Char>(value.begin(), value.end(), it);
3922 template <
typename Char,
typename OutputIt,
typename T,
3924 constexpr
auto write(OutputIt out,
const T& value) -> OutputIt {
3930 typename Char,
typename OutputIt,
typename T,
3933 mapped_type_constant<T, basic_format_context<OutputIt, Char>>
::value !=
3940 template <
typename Char,
typename OutputIt,
typename T,
3947 ?
write(out, value ? 1 : 0, specs, {})
3948 :
write_bytes(out, value ?
"true" :
"false", specs);
3951 template <
typename Char,
typename OutputIt>
3958 template <
typename Char,
typename OutputIt>
3966 template <
typename Char,
typename OutputIt,
typename T,
3969 locale_ref = {}) -> OutputIt {
3974 template <
typename Char,
typename OutputIt,
typename T,
3979 !std::is_same<T, remove_cvref_t<decltype(arg_mapper<Context>().map(
3982 return write<Char>(out, arg_mapper<Context>().map(value));
3985 template <
typename Char,
typename OutputIt,
typename T,
3990 auto ctx =
Context(out, {}, {});
3991 return typename Context::template formatter_type<T>().
format(value, ctx);
4005 return write<Char>(out,
value);
4010 h.format(parse_ctx, format_ctx);
4011 return format_ctx.out();
4023 template <
typename T>
4040 h.format(parse_ctx, ctx);
4051 if (
is_negative(value)) handler_.on_error(
"negative width");
4052 return static_cast<unsigned long long>(
value);
4057 handler_.on_error(
"width is not integer");
4071 if (
is_negative(value)) handler_.on_error(
"negative precision");
4072 return static_cast<unsigned long long>(
value);
4077 handler_.on_error(
"precision is not integer");
4085 template <
template <
typename>
class Handler,
typename FormatArg,
4089 if (value >
to_unsigned(max_value<int>())) eh.on_error(
"number is too big");
4090 return static_cast<int>(
value);
4093 template <
typename Context,
typename ID>
4095 typename Context::format_arg {
4096 auto arg = ctx.arg(
id);
4097 if (!
arg) ctx.on_error(
"argument not found");
4101 template <
template <
typename>
class Handler,
typename Context>
4103 arg_ref<typename Context::char_type>
ref,
4109 value = detail::get_dynamic_spec<Handler>(
get_arg(ctx, ref.val.index),
4110 ctx.error_handler());
4113 value = detail::get_dynamic_spec<Handler>(
get_arg(ctx, ref.val.name),
4114 ctx.error_handler());
4119 #if FMT_USE_USER_DEFINED_LITERALS
4120 template <
typename Char>
struct udl_formatter {
4123 template <
typename... T>
4124 auto operator()(T&&...
args) const -> std::basic_string<Char> {
4129 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
4130 template <
typename T,
typename Char,
size_t N,
4131 fmt::detail_exported::fixed_string<Char, N> Str>
4132 struct statically_named_arg : view {
4133 static constexpr
auto name = Str.
data;
4136 statically_named_arg(
const T&
v) : value(v) {}
4139 template <
typename T,
typename Char,
size_t N,
4140 fmt::detail_exported::fixed_string<Char, N> Str>
4141 struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
4143 template <
typename T,
typename Char,
size_t N,
4144 fmt::detail_exported::fixed_string<Char, N> Str>
4145 struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
4146 : std::true_type {};
4148 template <
typename Char,
size_t N,
4149 fmt::detail_exported::fixed_string<Char, N> Str>
4151 template <
typename T>
auto operator=(T&& value)
const {
4152 return statically_named_arg<T, Char, N, Str>(std::forward<T>(
value));
4156 template <
typename Char>
struct udl_arg {
4159 template <
typename T>
auto operator=(T&& value) const -> named_arg<Char, T> {
4160 return {str, std::forward<T>(
value)};
4164 #endif // FMT_USE_USER_DEFINED_LITERALS
4166 template <
typename Locale,
typename Char>
4172 return {buf.data(), buf.size()};
4181 const char*
message) noexcept;
4204 template <
typename... T>
4227 const char*
message) noexcept;
4239 mutable char buffer_[buffer_size];
4242 template <
typename UInt>
auto format_unsigned(UInt value) ->
char* {
4243 auto n =
static_cast<detail::uint32_or_64_or_128_t<UInt>
>(
value);
4247 template <
typename Int>
auto format_signed(
Int value) ->
char* {
4248 auto abs_value =
static_cast<detail::uint32_or_64_or_128_t<Int>
>(
value);
4250 if (negative) abs_value = 0 - abs_value;
4251 auto begin = format_unsigned(abs_value);
4252 if (negative) *--
begin =
'-';
4259 explicit format_int(
long long value) : str_(format_signed(value)) {}
4260 explicit format_int(
unsigned value) : str_(format_unsigned(value)) {}
4261 explicit format_int(
unsigned long value) : str_(format_unsigned(value)) {}
4263 : str_(format_unsigned(value)) {}
4274 auto data() const -> const
char* {
return str_; }
4281 buffer_[buffer_size - 1] =
'\0';
4290 auto str() const -> std::
string {
return std::string(str_,
size()); }
4293 template <
typename T,
typename Char>
4295 :
private formatter<detail::format_as_t<T>> {
4299 template <
typename FormatContext>
4300 auto format(
const T& value, FormatContext& ctx)
const -> decltype(ctx.out()) {
4305 template <
typename Char>
4307 template <
typename FormatContext>
4308 auto format(
void* val, FormatContext& ctx)
const -> decltype(ctx.out()) {
4313 template <
typename Char,
size_t N>
4315 template <
typename FormatContext>
4317 -> decltype(ctx.out()) {
4331 template <
typename T>
auto ptr(T p) ->
const void* {
4335 template <
typename T,
typename Deleter>
4336 auto ptr(
const std::unique_ptr<T, Deleter>& p) ->
const void* {
4339 template <
typename T>
auto ptr(
const std::shared_ptr<T>& p) ->
const void* {
4353 template <
typename Enum>
4379 template <
typename ParseContext>
4385 template <
typename FormatContext>
4387 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4388 specs_.width_ref, ctx);
4389 detail::handle_dynamic_spec<detail::precision_checker>(
4390 specs_.precision, specs_.precision_ref, ctx);
4418 template <
typename ParseContext>
4424 template <
typename FormatContext>
4426 -> decltype(ctx.out()) {
4427 detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
4428 specs_.width_ref, ctx);
4429 detail::handle_dynamic_spec<detail::precision_checker>(
4430 specs_.precision, specs_.precision_ref, ctx);
4432 ctx.out(),
static_cast<detail::uint64_or_128_t<T>
>(
t.value), 0, specs_,
4433 detail::digit_grouping<char>(
"\3",
","));
4438 template <
typename It,
typename Sentinel,
typename Char =
char>
4448 template <
typename It,
typename Sentinel,
typename Char>
4452 #ifdef __cpp_lib_ranges
4453 std::iter_value_t<It>;
4460 template <
typename ParseContext>
4462 return value_formatter_.parse(ctx);
4465 template <
typename FormatContext>
4467 FormatContext& ctx)
const -> decltype(ctx.out()) {
4468 auto it = value.begin;
4469 auto out = ctx.out();
4470 if (it != value.end) {
4471 out = value_formatter_.format(*it, ctx);
4473 while (it != value.end) {
4474 out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
4475 ctx.advance_to(out);
4476 out = value_formatter_.format(*it, ctx);
4488 template <
typename It,
typename Sentinel>
4509 template <
typename Range>
4530 return {buffer.
data(), buffer.
size()};
4537 constexpr
int max_size = detail::digits10<T>() + 2;
4538 char buffer[max_size > 5 ?
static_cast<unsigned>(max_size) : 5];
4540 return std::string(begin, detail::write<char>(begin, value));
4543 template <
typename Char,
size_t SIZE>
4546 auto size = buf.size();
4553 template <
typename Char>
4556 auto out = buffer_appender<Char>(
buf);
4558 auto arg = args.get(0);
4559 if (!
arg) error_handler().on_error(
"argument not found");
4564 struct format_handler : error_handler {
4571 : parse_context(str), context(p_out, p_args, p_loc) {}
4573 void on_text(
const Char*
begin,
const Char*
end) {
4575 context.advance_to(write<Char>(context.out(), text));
4579 return parse_context.next_arg_id();
4582 return parse_context.check_arg_id(
id),
id;
4585 int arg_id = context.arg_id(
id);
4586 if (arg_id < 0) on_error(
"argument not found");
4590 FMT_INLINE void on_replacement_field(
int id,
const Char*) {
4598 auto on_format_specs(
int id,
const Char* begin,
const Char* end)
4602 parse_context.advance_to(begin);
4604 return parse_context.begin();
4608 detail::handle_dynamic_spec<detail::width_checker>(
4609 specs.
width, specs.width_ref, context);
4610 detail::handle_dynamic_spec<detail::precision_checker>(
4611 specs.
precision, specs.precision_ref, context);
4612 if (begin == end || *begin !=
'}')
4613 on_error(
"missing '}' in format string");
4619 detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
4622 #ifndef FMT_HEADER_ONLY
4632 #endif // FMT_HEADER_ONLY
4636 #if FMT_USE_USER_DEFINED_LITERALS
4637 inline namespace literals {
4648 # if FMT_USE_NONTYPE_TEMPLATE_ARGS
4649 template <detail_exported::fixed_
string Str> constexpr
auto operator""_a() {
4651 return detail::udl_arg<
char_t,
sizeof(Str.data) /
sizeof(char_t), Str>();
4654 constexpr
auto operator"" _a(
const char*
s,
size_t) -> detail::udl_arg<char> {
4659 #endif // FMT_USE_USER_DEFINED_LITERALS
4667 template <
typename Locale,
typename... T,
4674 template <
typename OutputIt,
typename Locale,
4680 auto&& buf = get_buffer<char>(out);
4685 template <
typename OutputIt,
typename Locale,
typename... T,
4693 template <
typename Locale,
typename... T,
4697 T&&... args) ->
size_t {
4706 template <
typename T,
typename Char>
4707 template <
typename FormatContext>
4713 const -> decltype(ctx.out()) {
4716 auto specs = specs_;
4717 detail::handle_dynamic_spec<detail::width_checker>(specs.
width,
4718 specs.width_ref, ctx);
4719 detail::handle_dynamic_spec<detail::precision_checker>(
4720 specs.
precision, specs.precision_ref, ctx);
4721 return detail::write<Char>(ctx.out(),
val, specs, ctx.locale());
4723 return detail::write<Char>(ctx.out(),
val, specs_, ctx.locale());
4728 #ifdef FMT_HEADER_ONLY
4729 # define FMT_FUNC inline
4735 #endif // FMT_FORMAT_H_
constexpr auto max_value() -> T
FMT_NORETURN FMT_API void throw_format_error(const char *message)
FMT_CONSTEXPR20 void try_resize(size_t count)
std::basic_string< Char > sep
#define FMT_ENABLE_IF(...)
GLuint GLsizei const GLchar * message
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
FMT_CONSTEXPR precision_checker(ErrorHandler &eh)
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
GLenum GLuint GLenum GLsizei const GLchar * buf
std::string upper(string_view a)
Return an all-upper case version of a (locale-independent).
typename float_info< T >::carrier_uint significand_type
bool_constant< is_integral< T >::value &&!std::is_same< T, bool >::value &&!std::is_same< T, char >::value &&!std::is_same< T, wchar_t >::value > is_integer
constexpr fallback_digit_grouping(locale_ref, bool)
friend constexpr auto operator>(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
conditional_t< FMT_USE_INT128, uint128_opt, uint128_fallback > uint128_t
typename detail::char_t_impl< S >::type char_t
FMT_CONSTEXPR20 void assign(const bigint &other)
static constexpr int16_t pow10_exponents[87]
void reserve(size_t new_capacity)
FMT_CONSTEXPR auto data() noexcept-> T *
FMT_CONSTEXPR20 auto countl_zero(uint32_t n) -> int
FMT_CONSTEXPR size_t count() const
T negative(const T &val)
Return the unary negation of the given value.
typename std::underlying_type< T >::type underlying_t
typename std::conditional< B, T, F >::type conditional_t
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
FMT_CONSTEXPR20 void square()
FMT_CONSTEXPR void ignore_unused(const T &...)
GLsizei const GLfloat * value
const char * c_str() const
FMT_CONSTEXPR20 void resize(size_t count)
conditional_t< std::is_same< T, char >::value, appender, std::back_insert_iterator< buffer< T >>> buffer_appender
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
**And then you can **find out if it s done
constexpr auto num_bits() -> int
decltype(std::begin(std::declval< T & >())) iterator_t
FMT_API auto to_decimal(T x) noexcept-> decimal_fp< T >
#define FMT_CONSTEXPR_CHAR_TRAITS
FMT_CONSTEXPR auto assign(Float n) -> bool
void vformat_to(buffer< Char > &buf, basic_string_view< Char > fmt, typename vformat_args< Char >::type args, locale_ref loc={})
GLboolean GLboolean GLboolean GLboolean a
static constexpr uint64_t pow10_significands[87]
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
bool_constant< std::is_floating_point< T >::value||is_float128< T >::value > is_floating_point
auto c_str() const -> const wchar_t *
constexpr auto num_bits< int128_opt >() -> int
void append(const ContiguousRange &range)
decltype(std::end(std::declval< T & >())) sentinel_t
bool has_separator() const
auto bit_cast(const From &from) -> To
auto is_printable(uint16_t x, const singleton *singletons, size_t singletons_size, const unsigned char *singleton_lowers, const unsigned char *normal, size_t normal_size) -> bool
friend constexpr auto operator&(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
__hostdev__ T Sign(const T &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Tto convert(const Tfrom &source)
**But if you need a result
detail::uint128_t carrier_uint
int count_separators(int num_digits) const
typename std::remove_cv< remove_reference_t< T >>::type remove_cvref_t
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
remove_reference_t< decltype(reserve(std::declval< OutputIt & >(), 0))> reserve_iterator
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
auto code_point_index(basic_string_view< Char > s, size_t n) -> size_t
constexpr uint64_t high() const noexcept
FMT_CONSTEXPR20 void try_reserve(size_t new_capacity)
SYS_FORCE_INLINE const char * data() const
FMT_INLINE auto get_iterator(Buf &buf, OutputIt) -> decltype(buf.out())
#define FMT_END_NAMESPACE
FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result< Char >
constexpr int count_separators(int) const
significand_type significand
basic_string_view< char > string_view
FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix, const format_specs< Char > &specs)
buffer_appender< Char > out
FMT_CONSTEXPR void operator&=(uint128_fallback n)
constexpr auto end() const noexcept-> iterator
auto get_data(std::basic_string< Char > &s) -> Char *
static constexpr uint64_t power_of_10_64[20]
FMT_CONSTEXPR auto check_char_specs(const format_specs< Char > &specs) -> bool
FMT_INLINE auto to_string_view(const Char *s) -> basic_string_view< Char >
auto base_iterator(std::back_insert_iterator< Container > &it, checked_ptr< typename Container::value_type >) -> std::back_insert_iterator< Container >
auto str() const -> std::wstring
#define FMT_MSC_WARNING(...)
auto get_allocator() const -> Allocator
static constexpr uint32_t fractional_part_rounding_thresholds[8]
FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback
FMT_CONSTEXPR void set(T *buf_data, size_t buf_capacity) noexcept
Out apply(Out out, basic_string_view< C > digits) const
FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback
FMT_CONSTEXPR counting_iterator operator++(int)
constexpr auto format_as(Enum e) noexcept-> underlying_t< Enum >
FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, difference_type n)
FMT_CONSTEXPR counting_iterator & operator++()
constexpr uint128_fallback(uint64_t value=0)
FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, uint64_t error, bool integral)
uint128_fallback umul192_upper128(uint64_t x, uint128_fallback y) noexcept
auto size() const -> size_t
auto get_container(std::back_insert_iterator< Container > it) -> Container &
constexpr auto set(type rhs) -> int
#define FMT_INLINE_VARIABLE
auto operator=(basic_memory_buffer &&other) noexcept-> basic_memory_buffer &
FMT_FUNC void print(std::FILE *f, string_view text)
detail::uint128_t carrier_uint
GLint GLint GLsizei GLint GLenum format
join_view(It b, Sentinel e, basic_string_view< Char > s)
friend FMT_CONSTEXPR20 int add_compare(const bigint &lhs1, const bigint &lhs2, const bigint &rhs)
typename std::remove_reference< T >::type remove_reference_t
FMT_FUNC auto write_loc(appender out, loc_value value, const format_specs<> &specs, locale_ref loc) -> bool
FMT_CONSTEXPR20 ~basic_memory_buffer()
digit_grouping(locale_ref loc, bool localized=true)
FMT_CONSTEXPR20 uint128_fallback & operator+=(uint64_t n) noexcept
digit_grouping(std::string grouping, std::basic_string< Char > sep)
constexpr auto count() -> size_t
int floor_log10_pow2(int e) noexcept
friend constexpr auto operator!=(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
FMT_CONSTEXPR basic_fp(Float n)
FMT_CONSTEXPR20 void align(const bigint &other)
FMT_FUNC void format_error_code(detail::buffer< char > &out, int error_code, string_view message) noexcept
constexpr auto make_checked(T *p, size_t) -> T *
GLuint const GLchar * name
constexpr auto size() const noexcept-> size_t
friend auto operator+(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
FMT_CONSTEXPR auto utf8_decode(const char *s, uint32_t *c, int *e) -> const char *
std::ptrdiff_t difference_type
GLint GLenum GLboolean normalized
std::wstring OIIO_UTIL_API utf8_to_utf16(string_view utf8str) noexcept
GLboolean GLboolean GLboolean b
#define FMT_UNCHECKED_ITERATOR(It)
FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end, OutputIt out) -> OutputIt
friend constexpr auto operator==(const uint128_fallback &lhs, const uint128_fallback &rhs) -> bool
GLenum GLenum GLsizei void * table
FMT_MODULE_EXPORT FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(Visitor &&vis, const basic_format_arg< Context > &arg) -> decltype(vis(0))
GLenum GLint GLint * precision
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
constexpr auto size() const noexcept-> size_t
FMT_CONSTEXPR value_type operator*() const
friend auto operator-(const uint128_fallback &lhs, uint64_t rhs) -> uint128_fallback
constexpr auto make_format_args(T &&...args) -> format_arg_store< Context, remove_cvref_t< T >...>
auto visit(Visitor &&vis) -> decltype(vis(0))
FMT_INLINE void assume(bool condition)
GLfloat GLfloat GLfloat GLfloat h
IMATH_HOSTDEVICE constexpr int ceil(T x) IMATH_NOEXCEPT
basic_string_view< Char > sep
FMT_CONSTEXPR20 void assign_pow10(int exp)
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_opt >::value > is_signed
std::is_same< T, float128 > is_float128
FMT_CONSTEXPR20 basic_memory_buffer(const Allocator &alloc=Allocator())
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
static constexpr CharT value[sizeof...(C)]
ImageBuf OIIO_API resize(const ImageBuf &src, string_view filtername="", float filterwidth=0.0f, ROI roi={}, int nthreads=0)
const format_specs< Char > & specs
FMT_CONSTEXPR20 auto bit_cast(const From &from) -> To
FMT_CONSTEXPR20 int divmod_assign(const bigint &divisor)
FMT_CONSTEXPR width_checker(ErrorHandler &eh)
FMT_CONSTEXPR20 auto countl_zero_fallback(UInt n) -> int
std::string lower(string_view a)
Return an all-upper case version of a (locale-independent).
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept-> bool
typename type_identity< T >::type type_identity_t
FMT_CONSTEXPR20 bigint & operator*=(Int value)
constexpr auto num_bits< uint128_t >() -> int
friend FMT_CONSTEXPR20 int compare(const bigint &lhs, const bigint &rhs)
constexpr basic_fp(uint64_t f_val, int e_val)
LeafData & operator=(const LeafData &)=delete
FMT_CONSTEXPR counting_iterator()
FMT_CONSTEXPR20 void push_back(const T &value)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
constexpr auto to_pointer(OutputIt, size_t) -> T *
constexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point
GA_API const UT_StringHolder N
FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char *begin, const Char *end, dynamic_format_specs< Char > &specs, basic_format_parse_context< Char > &ctx, type arg_type) -> const Char *
FMT_CONSTEXPR void operator=(const T &)
Context provides a wrapper around the Core library context object.
**If you just want to fire and args
constexpr bool has_separator() const
constexpr auto data() const noexcept-> const Char *
GLdouble GLdouble GLdouble top
friend constexpr auto operator|(const uint128_fallback &lhs, const uint128_fallback &rhs) -> uint128_fallback
auto write(OutputIt out, const std::tm &time, const std::locale &loc, char format, char modifier=0) -> OutputIt
FMT_CONSTEXPR void abort_fuzzing_if(bool condition)
FMT_FUNC uint128_fallback get_cached_power(int k) noexcept
#define FMT_CLANG_VERSION
FMT_CONSTEXPR auto is_utf8() -> bool
constexpr auto begin() const noexcept-> iterator
#define FMT_ASSERT(condition, message)
uint64_t umul128_upper64(uint64_t x, uint64_t y) noexcept
FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer &&other) noexcept
#define FMT_BEGIN_NAMESPACE
auto get_buffer(OutputIt out) -> iterator_buffer< OutputIt, T >
const wchar_t & const_reference
auto compute_width(basic_string_view< Char > s) -> size_t
IMATH_HOSTDEVICE void intermediate(const Quat< T > &q0, const Quat< T > &q1, const Quat< T > &q2, const Quat< T > &q3, Quat< T > &qa, Quat< T > &qb) IMATH_NOEXCEPT
friend auto operator*(const uint128_fallback &lhs, uint32_t rhs) -> uint128_fallback
unicode_to_utf8(basic_string_view< WChar > s)
constexpr auto compile_string_to_view(detail::std_string_view< Char > s) -> basic_string_view< Char >
constexpr FMT_INLINE auto const_check(T value) -> T
FMT_CONSTEXPR void for_each_codepoint(string_view s, F f)
FMT_FUNC bool write_console(std::FILE *, string_view)
int floor_log2_pow10(int e) noexcept
friend constexpr auto operator~(const uint128_fallback &n) -> uint128_fallback
constexpr Out apply(Out out, basic_string_view< C >) const
FMT_CONSTEXPR20 int num_bigits() const
auto is_big_endian() -> bool
static bool convert(Buffer &buf, basic_string_view< WChar > s)
std::integral_constant< bool, B > bool_constant
FMT_FUNC void report_error(format_func func, int error_code, const char *message) noexcept
FMT_NOINLINE FMT_CONSTEXPR20 bigint & operator<<=(int shift)
PXR_NAMESPACE_OPEN_SCOPE typedef unsigned char uchar
decimal_fp< T > to_decimal(T x) noexcept
bool convert(basic_string_view< WChar > s)
constexpr auto capacity() const noexcept-> size_t
FMT_CONSTEXPR void operator+=(uint128_fallback n)
FMT_CONSTEXPR20 void operator=(Int n)
FMT_FUNC Char decimal_point_impl(locale_ref loc)
FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback &
std::output_iterator_tag iterator_category
std::basic_string< Char > decimal_point
static constexpr const int num_significand_bits
constexpr uint128_fallback(uint64_t hi, uint64_t lo)
constexpr uint64_t low() const noexcept
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.