224 default:
return "error";
309 default:
return false;
340 switch (fmt_literal) {
415 fmt = std::string_view();
439 std::string_view m_fmt;
448 : m_fmt(
f), m_pos(
pos), m_arg_count(acount), m_line(line), m_opts(o), m_success(ok) {}
451 constexpr bool success() const noexcept {
return m_success; }
457 constexpr const std::string_view&
fmt() const noexcept {
return m_fmt; }
462 constexpr size_t pos() const noexcept {
return m_pos; }
464 constexpr int errorLine() const noexcept {
return m_line; }
475 inline constexpr const size_t char32buf_maxlen = 32;
476 inline constexpr const uint32_t default_float_precision = 6;
477 inline constexpr const double_t max_append_float = (double_t)1e9;
479 void append_rev(std::string &dest,
const size_t dest_maxlen, std::string_view src,
bool prec_cut,
bool reverse,
const FormatOpts &opts);
480 inline void append_string(std::string &dest,
const size_t dest_maxlen, std::string_view src,
const FormatOpts &opts) {
481 append_rev(dest, dest_maxlen, src,
true ,
false , opts);
483 void append_integral(std::string &dest,
const size_t dest_maxlen, uint64_t v,
const bool negative,
const FormatOpts &opts,
const bool inject_dot=
false);
485 void append_integral_simple(std::string &dest,
const size_t dest_maxlen, uint64_t v,
const bool negative,
const FormatOpts &opts);
488 bool is_float_validF64(std::string &dest,
const size_t dest_maxlen,
const double value,
const FormatOpts &opts);
489 void append_floatF64(std::string &dest,
const size_t dest_maxlen,
const double value,
const FormatOpts &opts);
490 void append_efloatF64(std::string &dest,
const size_t dest_maxlen,
const double ivalue,
const FormatOpts &iopts);
491 void append_afloatF64(std::string &dest,
const size_t dest_maxlen,
const double ivalue,
const size_t ivalue_size,
const FormatOpts &iopts);
494 concept OutputType =
requires(T
t) {
495 {
t.maxLen() } -> std::same_as<size_t>;
498 {
t.get() } -> std::same_as<std::string_view>;
504 constexpr NullOutput() noexcept = default;
506 constexpr
size_t maxLen() const noexcept {
return 0; }
507 constexpr bool fits(
size_t)
const noexcept {
return false; }
509 std::string_view get() const noexcept {
return "(nil)"; }
512 requires jau::req::stringifyable_jau<T>
513 constexpr void appendFormatted(
const FormatOpts&,
const T&)
noexcept { }
516 requires jau::req::unsigned_integral<T> && (!jau::req::boolean<T>)
517 constexpr void appendFormattedInt(
const FormatOpts&,
const T&,
bool)
noexcept { }
520 requires std::is_floating_point_v<T>
521 constexpr void appendFormattedFloat(
const FormatOpts&,
const T&,
nsize_t)
noexcept {}
523 constexpr void appendText(std::string_view )
noexcept { }
524 constexpr void appendError(
size_t,
int ,
const std::string_view )
noexcept {}
530 std::size_t m_maxLen;
534 constexpr StringOutput(std::size_t maxLen, std::string &s) noexcept
535 : m_maxLen(maxLen), m_s(s) {}
537 constexpr size_t maxLen() const noexcept {
return m_maxLen; }
538 constexpr bool fits(
size_t n)
const noexcept {
return m_s.size() + n <= m_maxLen; }
540 std::string_view get() const noexcept {
return m_s; }
543 requires jau::req::string_literal<T> || jau::req::string_class<T>
544 void appendFormatted(
const FormatOpts& opts,
const T& v) {
545 impl::append_string(m_s, m_maxLen, v, opts);
548 requires jau::req::char_pointer<T>
549 void appendFormatted(
const FormatOpts& opts,
const T& v) {
551 impl::append_string(m_s, m_maxLen, std::string_view(v), opts);
553 impl::append_string(m_s, m_maxLen,
"(null)", opts);
557 requires jau::req::pointer<T> && (!jau::req::string_alike<T>)
558 void appendFormatted(
const FormatOpts& opts,
const T& v) {
560 const uintptr_t v_le =
jau::cpu_to_le(
reinterpret_cast<uintptr_t
>(v));
561 if (!opts.width_set && !opts.precision_set) {
562 impl::append_integral_simple(m_s, m_maxLen, v_le,
false, opts);
564 impl::append_integral(m_s, m_maxLen, v_le,
false, opts);
567 impl::append_string(m_s, m_maxLen,
"(nil)", opts);
571 requires jau::req::unsigned_integral<T>
572 void appendFormattedInt(
const FormatOpts& opts,
const T& v,
bool negative) {
573 if (!opts.width_set && !opts.precision_set) {
574 impl::append_integral_simple(m_s, m_maxLen, uint64_t(v), negative, opts);
576 impl::append_integral(m_s, m_maxLen, uint64_t(v), negative, opts);
580 requires std::is_floating_point_v<T>
581 void appendFormattedFloat(
const FormatOpts& opts,
const T& v,
nsize_t floatSize) {
583 impl::append_floatF64(m_s, m_maxLen, v, opts);
585 impl::append_afloatF64(m_s, m_maxLen, v, floatSize, opts);
588 impl::append_efloatF64(m_s, m_maxLen, v, opts);
591 inline void appendText(
const std::string_view v) {
592 if (fits(v.size())) {
597 void appendError(
size_t argIdx,
int line,
const std::string_view tag);
600 template<OutputType Output>
605 template<OutputType Output>
608 std::string_view fmt;
618 unsigned int m_argtype_size;
619 bool m_argtype_signed:1;
620 bool m_argval_negative:1;
623 constexpr FResult(Output p, std::string_view fmt_) noexcept
624 : fmt(fmt_), pos(0), arg_count(0), line(0), opts(),
626 m_out(std::move(p)), pos_lstart(0),
628 m_argtype_signed(
false),
629 m_argval_negative(
false)
632 constexpr FResult(
const FResult &pre)
noexcept =
default;
633 constexpr FResult &operator=(
const FResult &x)
noexcept =
default;
635 constexpr operator Result() const noexcept {
639 constexpr bool hasNext() const noexcept {
640 return !error() && pos < fmt.length();
643 constexpr ssize_t argCount() const noexcept {
return arg_count; }
644 constexpr bool error() const noexcept {
return pstate_t::error == state; }
646 std::string toString()
const {
647 const char c = pos < fmt.length() ? fmt[pos] :
'@';
648 std::string s =
"args ";
649 s.append(std::to_string(arg_count))
653 .append(std::to_string(line))
655 .append(std::to_string(pos))
657 .append(std::string(1, c))
659 .append(opts.toString())
660 .append(
"`, type[signed ")
663 .append(std::to_string(m_argtype_size))
664 .append(
"], negative ")
675 friend class impl::Parser<Output>;
677 constexpr void reset() noexcept {
680 constexpr bool nextSymbol(
char &c)
noexcept {
681 if (pos < fmt.length()) {
688 constexpr bool toConversion() noexcept {
691 }
else if (fmt[pos] ==
'%') {
696 }
else if (pos < fmt.length()) {
698 const size_t q = fmt.find(
'%', pos + 1);
699 if (q == std::string::npos) {
701 appendText(fmt.substr(pos, fmt.length() - pos));
706 appendText(fmt.substr(pos, q - pos));
719 constexpr void setLastSpec(
size_t endpos)
noexcept {
720 if (endpos > pos_lstart) {
721 opts.fmt = fmt.substr(pos_lstart, endpos - pos_lstart);
725 constexpr void setError(
int l)
noexcept {
728 if (0 == arg_count) {
729 arg_count = std::numeric_limits<ssize_t>::min();
730 }
else if (0 < arg_count) {
736 requires jau::req::stringifyable_jau<T> && (!jau::req::unsigned_integral<T>) && (!std::floating_point<T>)
737 constexpr void appendFormatted(
const T &v) {
738 m_out.appendFormatted(opts, v);
741 requires jau::req::unsigned_integral<T> && (!jau::req::boolean<T>)
742 constexpr void appendFormatted(
const T &v) {
743 m_out.appendFormattedInt(opts, v, m_argval_negative);
747 requires jau::req::boolean<T>
748 constexpr void appendFormatted(
const T &v) {
749 m_out.appendFormatted(opts, v ?
"true" :
"false");
753 requires std::floating_point<T>
754 constexpr void appendFormatted(
const T &v) {
755 m_out.appendFormattedFloat(opts, v, m_argtype_size);
758 constexpr void appendText(
const std::string_view v) {
762 constexpr void appendError(
const std::string_view tag) {
763 const ssize_t c = arg_count == std::numeric_limits<ssize_t>::min() ? 0 : arg_count;
764 m_out.appendError(
jau::abs(c), line, tag);
768 template <jau::req::
signed_
integral T>
769 constexpr std::make_unsigned_t<T>
unsigned_int(
const T x)
noexcept
775 requires (!jau::req::signed_integral<T>)
781 requires jau::req::signed_integral<T>
782 constexpr bool is_positive(
const T a)
noexcept {
787 requires std::floating_point<T>
788 constexpr bool is_positive(
const T a)
noexcept {
793 requires (!jau::req::signed_integral<T>) && (!std::floating_point<T>)
794 constexpr bool is_positive(
const T&)
noexcept {
800 using make_int_unsigned_t =
typename std::conditional_t<std::is_integral_v<T> || jau::req::boolean<T>, std::type_identity<uint64_t>, std::type_identity<T>>::type;
804 using make_int_signed_t =
typename std::conditional_t<jau::req::unsigned_integral<T> && !jau::req::boolean<T>, std::make_signed<T>, std::type_identity<T>>::type;
808 using make_simple_pointer_t =
typename std::conditional_t<jau::req::pointer<T>, std::type_identity<const char * const>, std::type_identity<T>>::type;
811 typedef FResult<NullOutput> CheckResult;
814 typedef FResult<StringOutput> StringResult;
816 template<OutputType Output>
819 typedef FResult<Output> Result;
820 constexpr Parser() noexcept = delete;
825 template <typename T>
826 requires std::is_integral_v<T> && (!jau::req::
boolean<T>)
827 static constexpr
void parseOne(Result &pc, const T &val) {
828 pc.m_argtype_size =
sizeof(T);
829 pc.m_argtype_signed = std::is_signed_v<T>;
831 using U = make_int_unsigned_t<T>;
835 template <
typename T>
836 requires std::is_floating_point_v<T>
837 static constexpr void parseOne(Result &pc,
const T &val) {
838 pc.m_argtype_size =
sizeof(T);
839 pc.m_argtype_signed =
true;
841 parseOneImpl<double>(pc,
double(val));
844 template <
typename T>
845 requires jau::req::pointer<T>
846 static constexpr void parseOne(Result &pc,
const T &val) {
847 pc.m_argtype_size =
sizeof(T);
848 pc.m_argtype_signed =
false;
849 pc.m_argval_negative =
false;
850 using U = make_simple_pointer_t<T>;
851 parseOneImpl<U>(pc, U(val));
854 template <
typename T>
855 requires jau::req::string_literal<T> || jau::req::string_class<T>
856 static constexpr void parseOne(Result &pc,
const T &val) {
857 pc.m_argtype_size =
sizeof(T);
858 pc.m_argtype_signed =
false;
859 pc.m_argval_negative =
false;
860 parseOneImpl<std::string_view>(pc, std::string_view(val));
863 template <
typename T>
864 requires (!( std::is_integral_v<T>
865 || std::is_floating_point_v<T>
866 || jau::req::pointer<T>
867 || jau::req::string_alike<T>)
868 ) || jau::req::boolean<T>
869 static constexpr void parseOne(Result &pc,
const T &val) {
870 pc.m_argtype_size =
sizeof(T);
871 pc.m_argtype_signed = std::is_signed_v<T>;
873 parseOneImpl<T>(pc, val);
876 template <
typename T>
877 requires std::is_integral_v<T> && (!jau::req::boolean<T>)
878 static constexpr void checkOne(CheckResult &pc)
noexcept {
879 pc.m_argtype_size =
sizeof(T);
880 pc.m_argtype_signed = std::is_signed_v<T>;
881 pc.m_argval_negative =
false;
882 using U = make_int_unsigned_t<T>;
883 parseOneImpl<U>(pc, U());
886 template <
typename T>
887 requires std::is_floating_point_v<T>
888 static constexpr void checkOne(CheckResult &pc)
noexcept {
889 pc.m_argtype_size =
sizeof(T);
890 pc.m_argtype_signed =
true;
891 pc.m_argval_negative =
false;
892 parseOneImpl<double>(pc,
double());
895 template <
typename T>
896 requires jau::req::pointer<T>
897 static constexpr void checkOne(CheckResult &pc)
noexcept {
898 pc.m_argtype_size =
sizeof(T);
899 pc.m_argtype_signed =
false;
900 pc.m_argval_negative =
false;
902 parseOneImpl<U>(pc, U());
905 template <
typename T>
906 requires jau::req::string_literal<T> || jau::req::string_class<T>
907 static constexpr void checkOne(CheckResult &pc)
noexcept {
908 pc.m_argtype_size =
sizeof(T);
909 pc.m_argtype_signed =
false;
910 pc.m_argval_negative =
false;
911 parseOneImpl<std::string_view>(pc, std::string_view());
914 template <
typename T>
915 requires (!( std::is_integral_v<T>
916 || std::is_floating_point_v<T>
917 || jau::req::pointer<T>
918 || jau::req::string_alike<T>)
919 ) || jau::req::boolean<T>
920 static constexpr void checkOne(CheckResult &pc)
noexcept {
921 pc.m_argtype_size =
sizeof(T);
922 pc.m_argtype_signed = std::is_signed_v<T>;
923 pc.m_argval_negative =
false;
924 parseOneImpl<T>(pc, T());
943 template <
typename T>
944 static constexpr void parseOneImpl(Result &pc,
const T &val) {
945 if( !pc.hasNext() ) {
952 if( !pc.toConversion() ) {
958 if( !pc.nextSymbol(c) ) {
959 pc.setError(__LINE__);
970 parseArgWidthPrecision<T>(
true, pc, val);
973 if( !parseFmtWidthPrecision(
true, pc, c) ) {
986 if( !pc.nextSymbol(c) ) {
987 pc.setError(__LINE__);
992 parseArgWidthPrecision<T>(
false, pc, val);
995 if( !parseFmtWidthPrecision(
false, pc, c) ) {
1000 pc.opts.setPrecision(0);
1006 if( !parseLengthMods(pc, c) ) {
1007 pc.appendError(
"Len");
1010 pc.setLastSpec(pc.pos);
1017 if( !parseFmtSpec<T>(pc, c, val) ) {
1018 pc.appendError(
"Cnv");
1026 }
while (loop_next);
1031 static constexpr void parseFlags(Result &pc,
char &c)
noexcept {
1032 while( pc.opts.addFlag(c) && pc.nextSymbol(c) ) { }
1036 template <
typename T>
1037 requires (!jau::req::unsigned_integral<T>)
1038 static constexpr void parseArgWidthPrecision(
bool, Result &pc,
const T &)
noexcept {
1039 pc.setError(__LINE__);
1042 template <
typename T>
1043 requires (jau::req::unsigned_integral<T>)
1044 static constexpr void parseArgWidthPrecision(
bool is_width, Result &pc,
const T &val)
noexcept {
1045 if constexpr( std::is_same_v<no_type_t, T> ) {
1046 pc.setError(__LINE__);
1050 if ( pc.m_argtype_size >
sizeof(
int) ) {
1051 pc.setError(__LINE__);
1054 if( pc.m_argval_negative ) {
1057 pc.opts.setWidth((uint32_t)val);
1059 pc.opts.setPrecision(0);
1063 pc.opts.setWidth((uint32_t)val);
1065 pc.opts.setPrecision((uint32_t)val);
1073 static constexpr bool parseFmtWidthPrecision(
bool is_width, Result &pc,
char &c)
noexcept {
1075 char *s = &buffer[0];
1076 const char *s_begin = s;
1080 if( !pc.nextSymbol(c) ) {
1081 pc.setError(__LINE__);
1086 pc.setError(__LINE__);
1089 std::string_view sv(s_begin, s - s_begin);
1099 if( num < 0 || num > std::numeric_limits<int>::max() ) {
1104 pc.opts.setWidth((uint32_t)num);
1106 pc.opts.setPrecision((uint32_t)num);
1112 static constexpr bool parseLengthMods(Result &pc,
char &c)
noexcept {
1114 if( !pc.nextSymbol(c) ) {
return false; }
1116 if( !pc.nextSymbol(c) ) {
return false; }
1121 }
else if(
'l' == c ) {
1122 if( !pc.nextSymbol(c) ) {
return false; }
1124 if( !pc.nextSymbol(c) ) {
return false; }
1129 }
else if(
'q' == c ) {
1130 if( !pc.nextSymbol(c) ) {
return false; }
1132 }
else if(
'L' == c ) {
1133 if( !pc.nextSymbol(c) ) {
return false; }
1135 }
else if(
'j' == c ) {
1136 if( !pc.nextSymbol(c) ) {
return false; }
1138 }
else if(
'z' == c ||
'Z' == c ) {
1139 if( !pc.nextSymbol(c) ) {
return false; }
1141 }
else if(
't' == c ) {
1142 if( !pc.nextSymbol(c) ) {
return false; }
1150 template <
typename T>
1151 static constexpr bool parseFmtSpec(Result &pc,
char fmt_literal,
const T &val) {
1152 if( !pc.opts.setConversion(fmt_literal) ) {
1153 pc.setError(__LINE__);
1157 switch( pc.opts.conversion ) {
1159 return parseCharFmtSpec<T>(pc, val);
1161 return parseStringFmtSpec<T>(pc, val);
1163 return parseAPointerFmtSpec<T>(pc, val);
1165 return parseSignedFmtSpec<T>(pc, val);
1167 return parseUnsignedFmtSpec<T>(pc, val);
1172 return parseFloatFmtSpec<T>(pc, fmt_literal, val);
1174 pc.setError(__LINE__);
1179 template <
typename T>
1180 requires (!jau::req::unsigned_integral<T>) || jau::req::boolean<T>
1181 static constexpr bool parseCharFmtSpec(Result &pc,
const T &)
noexcept {
1182 if constexpr( !std::is_same_v<no_type_t, T> ) {
1185 pc.setError(__LINE__);
1189 template <
typename T>
1190 requires jau::req::unsigned_integral<T> && (!jau::req::boolean<T>)
1191 static constexpr bool parseCharFmtSpec(Result &pc,
const T &val0) {
1194 using V = make_int_signed_t<T>;
1195 const V val = V(val0);
1196 const V
sign = pc.m_argval_negative ? -1 : 1;
1198 switch( pc.opts.length_mod ) {
1200 if ( !pc.m_argtype_signed ||
1201 (
sizeof(
char) != pc.m_argtype_size &&
1202 sizeof(
int) != pc.m_argtype_size ) ) {
1203 pc.setError(__LINE__);
1206 std::string s(1, (
char)(val*
sign));
1207 pc.appendFormatted(std::string_view(s));
1210 if ( !pc.m_argtype_signed ||
1211 (
sizeof(
wchar_t) != pc.m_argtype_size &&
1212 sizeof(wint_t) != pc.m_argtype_size ) ) {
1213 pc.setError(__LINE__);
1216 std::string s(1, (
char)(val*
sign));
1217 pc.appendFormatted(std::string_view(s));
1220 pc.setError(__LINE__);
1226 template <
typename T>
1227 requires (!(jau::req::string_alike<T> || jau::req::boolean<T>))
1228 static constexpr bool parseStringFmtSpec(Result &pc,
const T &)
noexcept {
1229 if constexpr( !std::is_same_v<no_type_t, T> ) {
1232 pc.setError(__LINE__);
1236 template <
typename T>
1237 requires jau::req::string_alike<T> || jau::req::boolean<T>
1238 static constexpr bool parseStringFmtSpec(Result &pc,
const T &val) {
1240 switch( pc.opts.length_mod ) {
1244 if constexpr( !(std::is_pointer_v<T> &&
1245 std::is_same_v<wchar_t, std::remove_cv_t<std::remove_pointer_t<T>>>) ) {
1246 pc.setError(__LINE__);
1252 pc.setError(__LINE__);
1255 pc.appendFormatted(val);
1259 template <
typename T>
1260 requires (!jau::req::pointer<T>)
1261 static constexpr bool parseAPointerFmtSpec(Result &pc,
const T &)
noexcept {
1262 if constexpr( !std::is_same_v<no_type_t, T> ) {
1265 pc.setError(__LINE__);
1268 template <
typename T>
1269 requires jau::req::pointer<T>
1270 static constexpr bool parseAPointerFmtSpec(Result &pc,
const T &val) {
1273 pc.appendFormatted((
void *)
const_cast<std::remove_const_t<T>
>(val));
1277 template <
typename T>
1278 requires (!(jau::req::unsigned_integral<T> || std::is_enum_v<T>))
1279 static constexpr bool parseSignedFmtSpec(Result &pc,
const T &)
noexcept {
1280 if constexpr( !std::is_same_v<no_type_t, T> ) {
1283 pc.setError(__LINE__);
1286 template <
typename T>
1287 requires std::is_enum_v<T> && (!jau::req::signed_integral<std::underlying_type_t<T>>)
1288 static constexpr bool parseSignedFmtSpec(Result &pc,
const T &)
noexcept {
1289 if constexpr( !std::is_same_v<no_type_t, T> ) {
1292 pc.setError(__LINE__);
1295 template <
typename T>
1296 requires std::is_enum_v<T> && jau::req::signed_integral<std::underlying_type_t<T>>
1297 static constexpr bool parseSignedFmtSpec(Result &pc,
const T &val0) {
1298 using U = std::underlying_type_t<T>;
1299 using V = make_int_unsigned_t<U>;
1300 const U u = U(val0);
1301 pc.m_argtype_signed =
true;
1302 pc.m_argtype_size =
sizeof(U);
1306 template <
typename T>
1307 requires jau::req::unsigned_integral<T>
1308 static constexpr bool parseSignedFmtSpec(Result &pc,
const T &val) {
1312 const unsigned int signed_argtype_size = pc.m_argtype_signed ? pc.m_argtype_size : pc.m_argtype_size + 1;
1315 pc.opts.flags &= ~flags_t
::hash;
1320 switch( pc.opts.length_mod ) {
1322 if ( signed_argtype_size >
sizeof(
char) ) {
1323 pc.setError(__LINE__);
1328 if ( signed_argtype_size >
sizeof(
short) ) {
1329 pc.setError(__LINE__);
1334 if ( signed_argtype_size >
sizeof(
int) ) {
1335 pc.setError(__LINE__);
1340 if ( signed_argtype_size >
sizeof(
long) ) {
1341 pc.setError(__LINE__);
1346 if ( signed_argtype_size >
sizeof(
long long) ) {
1347 pc.setError(__LINE__);
1352 if ( signed_argtype_size >
sizeof(intmax_t) ) {
1353 pc.setError(__LINE__);
1358 if ( signed_argtype_size >
sizeof(ssize_t) ) {
1359 pc.setError(__LINE__);
1364 if ( signed_argtype_size >
sizeof(ptrdiff_t) ) {
1365 pc.setError(__LINE__);
1370 pc.setError(__LINE__);
1373 if constexpr (jau::req::boolean<T>) {
1374 pc.appendFormatted((
unsigned int)val);
1376 pc.appendFormatted(val);
1381 template <
typename T>
1382 requires (!(jau::req::unsigned_integral<T> || std::is_enum_v<T>))
1383 static constexpr bool parseUnsignedFmtSpec(Result &pc,
const T &)
noexcept {
1384 if constexpr( !std::is_same_v<no_type_t, T> ) {
1387 pc.setError(__LINE__);
1390 template <
typename T>
1391 requires std::is_enum_v<T>
1392 static constexpr bool parseUnsignedFmtSpec(Result &pc,
const T &val0) {
1393 using U = std::underlying_type_t<T>;
1394 using V = make_int_unsigned_t<U>;
1395 const U u = U(val0);
1396 pc.m_argtype_signed = std::is_signed_v<U>;
1397 pc.m_argtype_size =
sizeof(U);
1401 template <
typename T>
1402 requires jau::req::unsigned_integral<T>
1403 static constexpr bool parseUnsignedFmtSpec(Result &pc,
const T &val) {
1407 if( pc.m_argval_negative ) {
1408 pc.setError(__LINE__);
1413 pc.opts.flags &= ~flags_t
::hash;
1418 switch( pc.opts.length_mod ) {
1420 if ( pc.m_argtype_size >
sizeof(
unsigned char) ) {
1421 pc.setError(__LINE__);
1426 if ( pc.m_argtype_size >
sizeof(
unsigned short) ) {
1427 pc.setError(__LINE__);
1432 if ( pc.m_argtype_size >
sizeof(
unsigned int) ) {
1433 pc.setError(__LINE__);
1438 if ( pc.m_argtype_size >
sizeof(
unsigned long) ) {
1439 pc.setError(__LINE__);
1444 if ( pc.m_argtype_size >
sizeof(
unsigned long long) ) {
1445 pc.setError(__LINE__);
1450 if ( pc.m_argtype_size >
sizeof(uintmax_t) ) {
1451 pc.setError(__LINE__);
1456 if ( pc.m_argtype_size >
sizeof(
size_t) ) {
1457 pc.setError(__LINE__);
1463 if ( pc.m_argtype_size >
sizeof(ptrdiff_t) ) {
1464 pc.setError(__LINE__);
1470 pc.setError(__LINE__);
1473 if constexpr (jau::req::boolean<T>) {
1474 pc.appendFormatted((
unsigned int)val);
1476 pc.appendFormatted(val);
1481 template <
typename T>
1482 requires (!std::floating_point<T>)
1483 static constexpr bool parseFloatFmtSpec(Result &pc,
const char ,
const T &)
noexcept {
1484 if constexpr( !std::is_same_v<no_type_t, T> ) {
1487 pc.setError(__LINE__);
1490 template <
typename T>
1491 requires std::floating_point<T>
1492 static constexpr bool parseFloatFmtSpec(Result &pc,
const char ,
const T &val) {
1495 using U = std::remove_cv_t<T>;
1497 switch( pc.opts.length_mod ) {
1500 if constexpr( !std::is_same_v<float, U> &&
1501 !std::is_same_v<double, U> ) {
1502 pc.setError(__LINE__);
1507 if constexpr( !std::is_same_v<float, U> &&
1508 !std::is_same_v<double, U> &&
1509 !std::is_same_v<long double, U> ) {
1511 pc.setError(__LINE__);
1516 pc.setError(__LINE__);
1519 pc.appendFormatted(val);
1524 typedef Parser<NullOutput> CheckParser;
1525 typedef Parser<StringOutput> FormatParser;
1544 template <
typename... Targs>
1545 inline __attribute__((always_inline))
1548 impl::StringResult ctx(impl::StringOutput(s.max_size(), s), fmt);
1550 std::exception_ptr eptr;
1552 if constexpr( 0 <
sizeof...(Targs) ) {
1553 ((impl::FormatParser::parseOne<Targs>(ctx, args)), ...);
1555 impl::FormatParser::parseOne<impl::no_type_t>(ctx, impl::no_type_t());
1557 eptr = std::current_exception();
1575 template <
typename... Targs>
1576 inline __attribute__((always_inline))
1577 std::
string format(
size_t maxLen,
std::string_view fmt, const Targs &...args) noexcept {
1579 impl::StringResult ctx(impl::StringOutput(std::min(maxLen, s.max_size()), s), fmt);
1581 std::exception_ptr eptr;
1583 if constexpr( 0 <
sizeof...(Targs) ) {
1584 ((impl::FormatParser::parseOne<Targs>(ctx, args)), ...);
1586 impl::FormatParser::parseOne<impl::no_type_t>(ctx, impl::no_type_t());
1588 eptr = std::current_exception();
1608 template <
typename... Targs>
1609 inline __attribute__((always_inline))
1611 impl::StringResult ctx(impl::StringOutput(std::min(maxLen, s.max_size()), s), fmt);
1613 std::exception_ptr eptr;
1615 if constexpr( 0 <
sizeof...(Targs) ) {
1616 ((impl::FormatParser::parseOne<Targs>(ctx, args)), ...);
1618 impl::FormatParser::parseOne<impl::no_type_t>(ctx, impl::no_type_t());
1620 eptr = std::current_exception();
1638 template <
typename... Targs>
1639 inline __attribute__((always_inline))
1641 return formatR(s, s.max_size(), fmt, args...);
1664 template <
typename... Targs>
1665 inline __attribute__((always_inline))
1666 Result formatR(const
std::
size_t strLenHint,
std::
string &s,
size_t maxLen,
std::string_view fmt, const Targs &...args) noexcept {
1667 impl::StringResult ctx(impl::StringOutput(std::min(maxLen, s.max_size()), s), fmt);
1669 std::exception_ptr eptr;
1671 s.reserve(strLenHint+1);
1672 if constexpr( 0 <
sizeof...(Targs) ) {
1673 ((impl::FormatParser::parseOne<Targs>(ctx, args)), ...);
1675 impl::FormatParser::parseOne<impl::no_type_t>(ctx, impl::no_type_t());
1677 eptr = std::current_exception();
1700 template <
typename... Targs>
1701 inline __attribute__((always_inline))
1703 return formatR(strLenHint, s, s.max_size(), fmt, args...);
1725 template <
typename... Targs>
1727 impl::CheckResult ctx(impl::NullOutput(), fmt);
1728 if constexpr( 0 <
sizeof...(Targs) ) {
1729 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1731 impl::CheckParser::checkOne<impl::no_type_t>(ctx);
1732 return ctx.arg_count;
1748 template <
typename... Targs>
1750 impl::CheckResult ctx(impl::NullOutput(), fmt);
1751 if constexpr( 0 <
sizeof...(Targs) ) {
1752 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1754 impl::CheckParser::checkOne<impl::no_type_t>(ctx);
1769 template <
typename... Targs>
1771 impl::CheckResult ctx(impl::NullOutput(), fmt);
1772 if constexpr( 0 <
sizeof...(Targs) ) {
1773 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1775 impl::CheckParser::checkOne<impl::no_type_t>(ctx);
1776 return ctx.arg_count;
1789 template <
typename... Targs>
1791 impl::CheckResult ctx(impl::NullOutput(), fmt);
1792 if constexpr( 0 <
sizeof...(Targs) ) {
1793 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1795 impl::CheckParser::checkOne<impl::no_type_t>(ctx);
1810 template <
typename... Targs>
1812 impl::CheckResult ctx(impl::NullOutput(), fmt);
1813 if constexpr( 0 <
sizeof...(Targs) ) {
1814 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1816 impl::CheckParser::checkOne<impl::no_type_t>(ctx);
1830 template <
typename... Targs>
1832 impl::CheckResult ctx(impl::NullOutput(),
format);
1833 if constexpr( 0 <
sizeof...(Targs) ) {
1834 ((impl::CheckParser::checkOne<Targs>(ctx)), ...);
1836 impl::CheckParser::checkOne<impl::no_type_t>(ctx);