Skip to content

Commit 5f898aa

Browse files
Fallback to std::format for c++20, fixed some warns
1 parent 7b15e65 commit 5f898aa

File tree

1 file changed

+67
-45
lines changed

1 file changed

+67
-45
lines changed

testlib.h

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* Copyright (c) 2005-2024
2626
*/
2727

28-
#define VERSION "0.9.43"
28+
#define VERSION "0.9.44-SNAPSHOT"
2929

3030
/*
3131
* Mike Mirzayanov
@@ -63,6 +63,7 @@
6363
*/
6464

6565
const char *latestFeatures[] = {
66+
"Fallback to std::format for c++20, fixed some warns",
6667
"Added ConstantBoundsLog, VariablesLog to validator testOverviewLogFile",
6768
"Use setAppesModeEncoding to change xml encoding from windows-1251 to other",
6869
"rnd.any/wany use distance/advance instead of -/+: now they support sets/multisets",
@@ -330,6 +331,12 @@ static int __testlib_format_buffer_usage_count = 0;
330331
result = std::string(__testlib_format_buffer); \
331332
__testlib_format_buffer_usage_count--; \
332333

334+
#ifdef __GNUC__
335+
__attribute__ ((format (printf, 1, 2)))
336+
#endif
337+
std::string testlib_format_(const char *fmt, ...);
338+
std::string testlib_format_(const std::string fmt, ...);
339+
333340
const long long __TESTLIB_LONGLONG_MAX = 9223372036854775807LL;
334341
const int __TESTLIB_MAX_TEST_CASE = 1073741823;
335342

@@ -430,19 +437,6 @@ inline std::string lowerCase(std::string s) {
430437
return s;
431438
}
432439

433-
#ifdef __GNUC__
434-
__attribute__ ((format (printf, 1, 2)))
435-
#endif
436-
std::string format(const char *fmt, ...) {
437-
FMT_TO_RESULT(fmt, fmt, result);
438-
return result;
439-
}
440-
441-
std::string format(const std::string fmt, ...) {
442-
FMT_TO_RESULT(fmt, fmt.c_str(), result);
443-
return result;
444-
}
445-
446440
#ifdef __GNUC__
447441
__attribute__((const))
448442
#endif
@@ -1805,7 +1799,7 @@ class FileInputStreamReader : public InputStreamReader {
18051799

18061800
void setTestCase(int testCase) {
18071801
if (testCase < 0 || testCase > __TESTLIB_MAX_TEST_CASE)
1808-
__testlib_fail(format("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase));
1802+
__testlib_fail(testlib_format_("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase));
18091803
readChars.push_back(testCase + 256);
18101804
}
18111805

@@ -3127,7 +3121,7 @@ NORETURN void InStream::quit(TResult result, const char *msg) {
31273121
break;
31283122
default:
31293123
if (result >= _partially) {
3130-
errorName = format("partially correct (%d) ", pctype);
3124+
errorName = testlib_format_("partially correct (%d) ", pctype);
31313125
isPartial = true;
31323126
quitscrS(LightYellow, errorName);
31333127
} else
@@ -3151,7 +3145,7 @@ NORETURN void InStream::quit(TResult result, const char *msg) {
31513145
else {
31523146
if (__testlib_points == std::numeric_limits<float>::infinity())
31533147
quit(_fail, "Expected points, but infinity found");
3154-
std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", __testlib_points));
3148+
std::string stringPoints = removeDoubleTrailingZeroes(testlib_format_("%.10f", __testlib_points));
31553149
std::fprintf(resultFile, "<result outcome = \"%s\" points = \"%s\">",
31563150
outcomes[(int) result].c_str(), stringPoints.c_str());
31573151
}
@@ -3483,9 +3477,9 @@ std::string InStream::readWord(const pattern &p, const std::string &variableName
34833477

34843478
std::vector<std::string>
34853479
InStream::readWords(int size, const pattern &p, const std::string &variablesName, int indexBase) {
3486-
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
34873480
if (strict && !variablesName.empty())
34883481
validator.addVariable(variablesName);
3482+
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
34893483
}
34903484

34913485
std::vector<std::string> InStream::readWords(int size, int indexBase) {
@@ -3499,9 +3493,9 @@ std::string InStream::readWord(const std::string &ptrn, const std::string &varia
34993493
std::vector<std::string>
35003494
InStream::readWords(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
35013495
pattern p(ptrn);
3502-
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
35033496
if (strict && !variablesName.empty())
35043497
validator.addVariable(variablesName);
3498+
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
35053499
}
35063500

35073501
std::string InStream::readToken(const pattern &p, const std::string &variableName) {
@@ -3510,9 +3504,9 @@ std::string InStream::readToken(const pattern &p, const std::string &variableNam
35103504

35113505
std::vector<std::string>
35123506
InStream::readTokens(int size, const pattern &p, const std::string &variablesName, int indexBase) {
3513-
__testlib_readMany(readTokens, readToken(p, variablesName), std::string, true);
35143507
if (strict && !variablesName.empty())
35153508
validator.addVariable(variablesName);
3509+
__testlib_readMany(readTokens, readToken(p, variablesName), std::string, true);
35163510
}
35173511

35183512
std::vector<std::string> InStream::readTokens(int size, int indexBase) {
@@ -3526,9 +3520,9 @@ std::string InStream::readToken(const std::string &ptrn, const std::string &vari
35263520
std::vector<std::string>
35273521
InStream::readTokens(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
35283522
pattern p(ptrn);
3529-
__testlib_readMany(readTokens, readWord(p, variablesName), std::string, true);
35303523
if (strict && !variablesName.empty())
35313524
validator.addVariable(variablesName);
3525+
__testlib_readMany(readTokens, readWord(p, variablesName), std::string, true);
35323526
}
35333527

35343528
void InStream::readWordTo(std::string &result, const pattern &p, const std::string &variableName) {
@@ -3893,9 +3887,9 @@ long long InStream::readLong(long long minv, long long maxv, const std::string &
38933887

38943888
std::vector<long long>
38953889
InStream::readLongs(int size, long long minv, long long maxv, const std::string &variablesName, int indexBase) {
3896-
__testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true)
38973890
if (strict && !variablesName.empty())
38983891
validator.addVariable(variablesName);
3892+
__testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true)
38993893
}
39003894

39013895
std::vector<long long> InStream::readLongs(int size, int indexBase) {
@@ -3939,9 +3933,9 @@ InStream::readUnsignedLong(unsigned long long minv, unsigned long long maxv, con
39393933

39403934
std::vector<unsigned long long> InStream::readUnsignedLongs(int size, unsigned long long minv, unsigned long long maxv,
39413935
const std::string &variablesName, int indexBase) {
3942-
__testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true)
39433936
if (strict && !variablesName.empty())
39443937
validator.addVariable(variablesName);
3938+
__testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true)
39453939
}
39463940

39473941
std::vector<unsigned long long> InStream::readUnsignedLongs(int size, int indexBase) {
@@ -3993,19 +3987,19 @@ int InStream::readInteger(int minv, int maxv, const std::string &variableName) {
39933987
}
39943988

39953989
std::vector<int> InStream::readInts(int size, int minv, int maxv, const std::string &variablesName, int indexBase) {
3996-
__testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true)
39973990
if (strict && !variablesName.empty())
39983991
validator.addVariable(variablesName);
3992+
__testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true)
39993993
}
40003994

40013995
std::vector<int> InStream::readInts(int size, int indexBase) {
40023996
__testlib_readMany(readInts, readInt(), int, true)
40033997
}
40043998

40053999
std::vector<int> InStream::readIntegers(int size, int minv, int maxv, const std::string &variablesName, int indexBase) {
4006-
__testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true)
40074000
if (strict && !variablesName.empty())
40084001
validator.addVariable(variablesName);
4002+
__testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true)
40094003
}
40104004

40114005
std::vector<int> InStream::readIntegers(int size, int indexBase) {
@@ -4059,9 +4053,9 @@ double InStream::readReal(double minv, double maxv, const std::string &variableN
40594053

40604054
std::vector<double>
40614055
InStream::readReals(int size, double minv, double maxv, const std::string &variablesName, int indexBase) {
4062-
__testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true)
40634056
if (strict && !variablesName.empty())
40644057
validator.addVariable(variablesName);
4058+
__testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true)
40654059
}
40664060

40674061
std::vector<double> InStream::readReals(int size, int indexBase) {
@@ -4074,9 +4068,9 @@ double InStream::readDouble(double minv, double maxv, const std::string &variabl
40744068

40754069
std::vector<double>
40764070
InStream::readDoubles(int size, double minv, double maxv, const std::string &variablesName, int indexBase) {
4077-
__testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true)
40784071
if (strict && !variablesName.empty())
40794072
validator.addVariable(variablesName);
4073+
__testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true)
40804074
}
40814075

40824076
std::vector<double> InStream::readDoubles(int size, int indexBase) {
@@ -4126,11 +4120,11 @@ double InStream::readStrictReal(double minv, double maxv,
41264120
std::vector<double> InStream::readStrictReals(int size, double minv, double maxv,
41274121
int minAfterPointDigitCount, int maxAfterPointDigitCount,
41284122
const std::string &variablesName, int indexBase) {
4123+
if (strict && !variablesName.empty())
4124+
validator.addVariable(variablesName);
41294125
__testlib_readMany(readStrictReals,
41304126
readStrictReal(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName),
41314127
double, true)
4132-
if (strict && !variablesName.empty())
4133-
validator.addVariable(variablesName);
41344128
}
41354129

41364130
double InStream::readStrictDouble(double minv, double maxv,
@@ -4144,11 +4138,11 @@ double InStream::readStrictDouble(double minv, double maxv,
41444138
std::vector<double> InStream::readStrictDoubles(int size, double minv, double maxv,
41454139
int minAfterPointDigitCount, int maxAfterPointDigitCount,
41464140
const std::string &variablesName, int indexBase) {
4141+
if (strict && !variablesName.empty())
4142+
validator.addVariable(variablesName);
41474143
__testlib_readMany(readStrictDoubles,
41484144
readStrictDouble(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName),
41494145
double, true)
4150-
if (strict && !variablesName.empty())
4151-
validator.addVariable(variablesName);
41524146
}
41534147

41544148
bool InStream::eof() {
@@ -4322,9 +4316,9 @@ std::string InStream::readString(const pattern &p, const std::string &variableNa
43224316

43234317
std::vector<std::string>
43244318
InStream::readStrings(int size, const pattern &p, const std::string &variablesName, int indexBase) {
4325-
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
43264319
if (strict && !variablesName.empty())
43274320
validator.addVariable(variablesName);
4321+
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
43284322
}
43294323

43304324
std::string InStream::readString(const std::string &ptrn, const std::string &variableName) {
@@ -4335,9 +4329,9 @@ std::string InStream::readString(const std::string &ptrn, const std::string &var
43354329
std::vector<std::string>
43364330
InStream::readStrings(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
43374331
pattern p(ptrn);
4338-
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
43394332
if (strict && !variablesName.empty())
43404333
validator.addVariable(variablesName);
4334+
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
43414335
}
43424336

43434337
void InStream::readLineTo(std::string &result) {
@@ -4366,9 +4360,9 @@ std::string InStream::readLine(const pattern &p, const std::string &variableName
43664360

43674361
std::vector<std::string>
43684362
InStream::readLines(int size, const pattern &p, const std::string &variablesName, int indexBase) {
4369-
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
43704363
if (strict && !variablesName.empty())
43714364
validator.addVariable(variablesName);
4365+
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
43724366
}
43734367

43744368
std::string InStream::readLine(const std::string &ptrn, const std::string &variableName) {
@@ -4378,9 +4372,9 @@ std::string InStream::readLine(const std::string &ptrn, const std::string &varia
43784372
std::vector<std::string>
43794373
InStream::readLines(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
43804374
pattern p(ptrn);
4381-
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
43824375
if (strict && !variablesName.empty())
43834376
validator.addVariable(variablesName);
4377+
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
43844378
}
43854379

43864380
#ifdef __GNUC__
@@ -4435,7 +4429,7 @@ double __testlib_preparePoints(double points_) {
44354429

44364430
NORETURN void __testlib_quitp(double points, const char *message) {
44374431
__testlib_points = __testlib_preparePoints(points);
4438-
std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", __testlib_points));
4432+
std::string stringPoints = removeDoubleTrailingZeroes(testlib_format_("%.10f", __testlib_points));
44394433

44404434
std::string quitMessage;
44414435
if (NULL == message || 0 == strlen(message))
@@ -4448,7 +4442,7 @@ NORETURN void __testlib_quitp(double points, const char *message) {
44484442

44494443
NORETURN void __testlib_quitp(int points, const char *message) {
44504444
__testlib_points = __testlib_preparePoints(points);
4451-
std::string stringPoints = format("%d", points);
4445+
std::string stringPoints = testlib_format_("%d", points);
44524446

44534447
std::string quitMessage;
44544448
if (NULL == message || 0 == strlen(message))
@@ -4764,7 +4758,7 @@ void registerValidation(int argc, char *argv[]) {
47644758
if (i + 1 < argc) {
47654759
long long testCase = stringToLongLong(inf, argv[++i]);
47664760
if (testCase < 1 || testCase >= __TESTLIB_MAX_TEST_CASE)
4767-
quit(_fail, format("Argument testCase should be between 1 and %d, but ", __TESTLIB_MAX_TEST_CASE)
4761+
quit(_fail, testlib_format_("Argument testCase should be between 1 and %d, but ", __TESTLIB_MAX_TEST_CASE)
47684762
+ toString(testCase) + " found");
47694763
validator.setTestCase(int(testCase));
47704764
} else
@@ -5182,17 +5176,17 @@ std::vector<std::string> tokenize(const std::string &s, const std::string &separ
51825176
NORETURN void __testlib_expectedButFound(TResult result, std::string expected, std::string found, const char *prepend) {
51835177
std::string message;
51845178
if (strlen(prepend) != 0)
5185-
message = format("%s: expected '%s', but found '%s'",
5179+
message = testlib_format_("%s: expected '%s', but found '%s'",
51865180
compress(prepend).c_str(), compress(expected).c_str(), compress(found).c_str());
51875181
else
5188-
message = format("expected '%s', but found '%s'",
5182+
message = testlib_format_("expected '%s', but found '%s'",
51895183
compress(expected).c_str(), compress(found).c_str());
51905184
quit(result, message);
51915185
}
51925186

51935187
NORETURN void __testlib_expectedButFound(TResult result, double expected, double found, const char *prepend) {
5194-
std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected));
5195-
std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found));
5188+
std::string expectedString = removeDoubleTrailingZeroes(testlib_format_("%.12f", expected));
5189+
std::string foundString = removeDoubleTrailingZeroes(testlib_format_("%.12f", found));
51965190
__testlib_expectedButFound(result, expectedString, foundString, prepend);
51975191
}
51985192

@@ -5223,8 +5217,8 @@ __attribute__ ((format (printf, 4, 5)))
52235217
#endif
52245218
NORETURN void expectedButFound<double>(TResult result, double expected, double found, const char *prependFormat, ...) {
52255219
FMT_TO_RESULT(prependFormat, prependFormat, prepend);
5226-
std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected));
5227-
std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found));
5220+
std::string expectedString = removeDoubleTrailingZeroes(testlib_format_("%.12f", expected));
5221+
std::string foundString = removeDoubleTrailingZeroes(testlib_format_("%.12f", found));
52285222
__testlib_expectedButFound(result, expectedString, foundString, prepend.c_str());
52295223
}
52305224

@@ -6199,7 +6193,7 @@ std::string opt(const std::string &key, const std::string &default_value) {
61996193
void ensureNoUnusedOpts() {
62006194
for (const auto &opt: __testlib_opts) {
62016195
if (!opt.second.used) {
6202-
__testlib_fail(format("Opts: unused key '%s'", compress(opt.first).c_str()));
6196+
__testlib_fail(testlib_format_("Opts: unused key '%s'", compress(opt.first).c_str()));
62036197
}
62046198
}
62056199
}
@@ -6217,4 +6211,32 @@ void TestlibFinalizeGuard::autoEnsureNoUnusedOpts() {
62176211
TestlibFinalizeGuard testlibFinalizeGuard;
62186212

62196213
#endif
6214+
6215+
#ifdef __GNUC__
6216+
__attribute__ ((format (printf, 1, 2)))
6217+
#endif
6218+
std::string testlib_format_(const char *fmt, ...) {
6219+
FMT_TO_RESULT(fmt, fmt, result);
6220+
return result;
6221+
}
6222+
6223+
std::string testlib_format_(const std::string fmt, ...) {
6224+
FMT_TO_RESULT(fmt, fmt.c_str(), result);
6225+
return result;
6226+
}
6227+
6228+
#if __cplusplus >= 202002L && __has_include(<format>)
6229+
# include <format>
6230+
#else
6231+
std::string format(const char *fmt, ...) {
6232+
FMT_TO_RESULT(fmt, fmt, result);
6233+
return result;
6234+
}
6235+
6236+
std::string format(const std::string fmt, ...) {
6237+
FMT_TO_RESULT(fmt, fmt.c_str(), result);
6238+
return result;
6239+
}
6240+
#endif
6241+
62206242
#endif

0 commit comments

Comments
 (0)