ConvTest.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309
  1. /*
  2. * Copyright 2011-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef __STDC_FORMAT_MACROS
  17. #define __STDC_FORMAT_MACROS 1
  18. #endif
  19. #include <boost/lexical_cast.hpp>
  20. #include <folly/Conv.h>
  21. #include <folly/container/Foreach.h>
  22. #include <folly/portability/GTest.h>
  23. #include <algorithm>
  24. #include <cinttypes>
  25. #include <limits>
  26. #include <sstream>
  27. #include <stdexcept>
  28. #include <tuple>
  29. using namespace std;
  30. using namespace folly;
  31. TEST(Conv, digits10) {
  32. char buffer[100];
  33. uint64_t power;
  34. // first, some basic sniff tests
  35. EXPECT_EQ(1, digits10(0));
  36. EXPECT_EQ(1, digits10(1));
  37. EXPECT_EQ(1, digits10(9));
  38. EXPECT_EQ(2, digits10(10));
  39. EXPECT_EQ(2, digits10(99));
  40. EXPECT_EQ(3, digits10(100));
  41. EXPECT_EQ(3, digits10(999));
  42. EXPECT_EQ(4, digits10(1000));
  43. EXPECT_EQ(4, digits10(9999));
  44. EXPECT_EQ(20, digits10(18446744073709551615ULL));
  45. // try the first X nonnegatives.
  46. // Covers some more cases of 2^p, 10^p
  47. for (uint64_t i = 0; i < 100000; i++) {
  48. snprintf(buffer, sizeof(buffer), "%" PRIu64, i);
  49. EXPECT_EQ(strlen(buffer), digits10(i));
  50. }
  51. // try powers of 2
  52. power = 1;
  53. for (int p = 0; p < 64; p++) {
  54. snprintf(buffer, sizeof(buffer), "%" PRIu64, power);
  55. EXPECT_EQ(strlen(buffer), digits10(power));
  56. snprintf(buffer, sizeof(buffer), "%" PRIu64, power - 1);
  57. EXPECT_EQ(strlen(buffer), digits10(power - 1));
  58. snprintf(buffer, sizeof(buffer), "%" PRIu64, power + 1);
  59. EXPECT_EQ(strlen(buffer), digits10(power + 1));
  60. power *= 2;
  61. }
  62. // try powers of 10
  63. power = 1;
  64. for (int p = 0; p < 20; p++) {
  65. snprintf(buffer, sizeof(buffer), "%" PRIu64, power);
  66. EXPECT_EQ(strlen(buffer), digits10(power));
  67. snprintf(buffer, sizeof(buffer), "%" PRIu64, power - 1);
  68. EXPECT_EQ(strlen(buffer), digits10(power - 1));
  69. snprintf(buffer, sizeof(buffer), "%" PRIu64, power + 1);
  70. EXPECT_EQ(strlen(buffer), digits10(power + 1));
  71. power *= 10;
  72. }
  73. }
  74. // Test to<T>(T)
  75. TEST(Conv, Type2Type) {
  76. bool boolV = true;
  77. EXPECT_EQ(to<bool>(boolV), true);
  78. int intV = 42;
  79. EXPECT_EQ(to<int>(intV), 42);
  80. float floatV = 4.2f;
  81. EXPECT_EQ(to<float>(floatV), 4.2f);
  82. double doubleV = 0.42;
  83. EXPECT_EQ(to<double>(doubleV), 0.42);
  84. std::string stringV = "StdString";
  85. EXPECT_EQ(to<std::string>(stringV), "StdString");
  86. folly::fbstring fbStrV = "FBString";
  87. EXPECT_EQ(to<folly::fbstring>(fbStrV), "FBString");
  88. folly::StringPiece spV("StringPiece");
  89. EXPECT_EQ(to<folly::StringPiece>(spV), "StringPiece");
  90. // Rvalues
  91. EXPECT_EQ(to<bool>(true), true);
  92. EXPECT_EQ(to<int>(42), 42);
  93. EXPECT_EQ(to<float>(4.2f), 4.2f);
  94. EXPECT_EQ(to<double>(.42), .42);
  95. EXPECT_EQ(to<std::string>(std::string("Hello")), "Hello");
  96. EXPECT_EQ(to<folly::fbstring>(folly::fbstring("hello")), "hello");
  97. EXPECT_EQ(
  98. to<folly::StringPiece>(folly::StringPiece("Forty Two")), "Forty Two");
  99. }
  100. TEST(Conv, Integral2Integral) {
  101. // Same size, different signs
  102. int64_t s64 = numeric_limits<uint8_t>::max();
  103. EXPECT_EQ(to<uint8_t>(s64), s64);
  104. s64 = numeric_limits<int8_t>::max();
  105. EXPECT_EQ(to<int8_t>(s64), s64);
  106. }
  107. TEST(Conv, Floating2Floating) {
  108. float f1 = 1e3f;
  109. double d1 = to<double>(f1);
  110. EXPECT_EQ(f1, d1);
  111. double d2 = 23.0;
  112. auto f2 = to<float>(d2);
  113. EXPECT_EQ(double(f2), d2);
  114. double invalidFloat = std::numeric_limits<double>::max();
  115. EXPECT_ANY_THROW(to<float>(invalidFloat));
  116. invalidFloat = -std::numeric_limits<double>::max();
  117. EXPECT_ANY_THROW(to<float>(invalidFloat));
  118. try {
  119. auto shouldWork = to<float>(std::numeric_limits<double>::min());
  120. // The value of `shouldWork' is an implementation defined choice
  121. // between the following two alternatives.
  122. EXPECT_TRUE(
  123. shouldWork == std::numeric_limits<float>::min() || shouldWork == 0.f);
  124. } catch (...) {
  125. ADD_FAILURE();
  126. }
  127. }
  128. template <class String>
  129. void testIntegral2String() {}
  130. template <class String, class Int, class... Ints>
  131. void testIntegral2String() {
  132. typedef typename make_unsigned<Int>::type Uint;
  133. typedef typename make_signed<Int>::type Sint;
  134. Uint value = 123;
  135. EXPECT_EQ(to<String>(value), "123");
  136. Sint svalue = 123;
  137. EXPECT_EQ(to<String>(svalue), "123");
  138. svalue = -123;
  139. EXPECT_EQ(to<String>(svalue), "-123");
  140. value = numeric_limits<Uint>::min();
  141. EXPECT_EQ(to<Uint>(to<String>(value)), value);
  142. value = numeric_limits<Uint>::max();
  143. EXPECT_EQ(to<Uint>(to<String>(value)), value);
  144. svalue = numeric_limits<Sint>::min();
  145. EXPECT_EQ(to<Sint>(to<String>(svalue)), svalue);
  146. value = numeric_limits<Sint>::max();
  147. EXPECT_EQ(to<Sint>(to<String>(svalue)), svalue);
  148. testIntegral2String<String, Ints...>();
  149. }
  150. #if FOLLY_HAVE_INT128_T
  151. template <class String>
  152. void test128Bit2String() {
  153. typedef unsigned __int128 Uint;
  154. typedef __int128 Sint;
  155. EXPECT_EQ(detail::digitsEnough<unsigned __int128>(), 39);
  156. Uint value = 123;
  157. EXPECT_EQ(to<String>(value), "123");
  158. Sint svalue = 123;
  159. EXPECT_EQ(to<String>(svalue), "123");
  160. svalue = -123;
  161. EXPECT_EQ(to<String>(svalue), "-123");
  162. value = __int128(1) << 64;
  163. EXPECT_EQ(to<String>(value), "18446744073709551616");
  164. svalue = -(__int128(1) << 64);
  165. EXPECT_EQ(to<String>(svalue), "-18446744073709551616");
  166. value = 0;
  167. EXPECT_EQ(to<String>(value), "0");
  168. svalue = 0;
  169. EXPECT_EQ(to<String>(svalue), "0");
  170. value = ~__int128(0);
  171. EXPECT_EQ(to<String>(value), "340282366920938463463374607431768211455");
  172. svalue = -(Uint(1) << 127);
  173. EXPECT_EQ(to<String>(svalue), "-170141183460469231731687303715884105728");
  174. svalue = (Uint(1) << 127) - 1;
  175. EXPECT_EQ(to<String>(svalue), "170141183460469231731687303715884105727");
  176. // TODO: the following do not compile to<__int128> ...
  177. #if 0
  178. value = numeric_limits<Uint>::min();
  179. EXPECT_EQ(to<Uint>(to<String>(value)), value);
  180. value = numeric_limits<Uint>::max();
  181. EXPECT_EQ(to<Uint>(to<String>(value)), value);
  182. svalue = numeric_limits<Sint>::min();
  183. EXPECT_EQ(to<Sint>(to<String>(svalue)), svalue);
  184. value = numeric_limits<Sint>::max();
  185. EXPECT_EQ(to<Sint>(to<String>(svalue)), svalue);
  186. #endif
  187. }
  188. #endif
  189. TEST(Conv, Integral2String) {
  190. testIntegral2String<std::string, int8_t, int16_t, int32_t, int64_t>();
  191. testIntegral2String<fbstring, int8_t, int16_t, int32_t, int64_t>();
  192. #if FOLLY_HAVE_INT128_T
  193. test128Bit2String<std::string>();
  194. test128Bit2String<fbstring>();
  195. #endif
  196. }
  197. template <class String>
  198. void testString2Integral() {}
  199. template <class String, class Int, class... Ints>
  200. void testString2Integral() {
  201. typedef typename make_unsigned<Int>::type Uint;
  202. typedef typename make_signed<Int>::type Sint;
  203. // Unsigned numbers small enough to fit in a signed type
  204. static const String strings[] = {
  205. "0",
  206. "00",
  207. "2 ",
  208. " 84",
  209. " \n 123 \t\n",
  210. " 127",
  211. "0000000000000000000000000042",
  212. };
  213. static const Uint values[] = {
  214. 0,
  215. 0,
  216. 2,
  217. 84,
  218. 123,
  219. 127,
  220. 42,
  221. };
  222. FOR_EACH_RANGE (i, 0, sizeof(strings) / sizeof(*strings)) {
  223. EXPECT_EQ(to<Uint>(strings[i]), values[i]);
  224. EXPECT_EQ(to<Sint>(strings[i]), values[i]);
  225. }
  226. // Unsigned numbers that won't fit in the signed variation
  227. static const String uStrings[] = {
  228. " 128",
  229. "213",
  230. "255",
  231. };
  232. static const Uint uValues[] = {
  233. 128,
  234. 213,
  235. 255,
  236. };
  237. FOR_EACH_RANGE (i, 0, sizeof(uStrings) / sizeof(*uStrings)) {
  238. EXPECT_EQ(to<Uint>(uStrings[i]), uValues[i]);
  239. if (sizeof(Int) == 1) {
  240. EXPECT_THROW(to<Sint>(uStrings[i]), std::range_error);
  241. }
  242. }
  243. if (sizeof(Int) >= 4) {
  244. static const String strings2[] = {
  245. "256",
  246. "6324 ",
  247. "63245675 ",
  248. "2147483647",
  249. };
  250. static const Uint values2[] = {
  251. (Uint)256,
  252. (Uint)6324,
  253. (Uint)63245675,
  254. (Uint)2147483647,
  255. };
  256. FOR_EACH_RANGE (i, 0, sizeof(strings2) / sizeof(*strings2)) {
  257. EXPECT_EQ(to<Uint>(strings2[i]), values2[i]);
  258. EXPECT_EQ(to<Sint>(strings2[i]), values2[i]);
  259. }
  260. static const String uStrings2[] = {
  261. "2147483648",
  262. "3147483648",
  263. "4147483648",
  264. "4000000000",
  265. };
  266. static const Uint uValues2[] = {
  267. (Uint)2147483648U,
  268. (Uint)3147483648U,
  269. (Uint)4147483648U,
  270. (Uint)4000000000U,
  271. };
  272. FOR_EACH_RANGE (i, 0, sizeof(uStrings2) / sizeof(uStrings2)) {
  273. EXPECT_EQ(to<Uint>(uStrings2[i]), uValues2[i]);
  274. if (sizeof(Int) == 4) {
  275. EXPECT_THROW(to<Sint>(uStrings2[i]), std::range_error);
  276. }
  277. }
  278. }
  279. if (sizeof(Int) >= 8) {
  280. static_assert(sizeof(Int) <= 8, "Now that would be interesting");
  281. static const String strings3[] = {
  282. "2147483648",
  283. "5000000001",
  284. "25687346509278435",
  285. "100000000000000000",
  286. "9223372036854775807",
  287. };
  288. static const Uint values3[] = {
  289. (Uint)2147483648ULL,
  290. (Uint)5000000001ULL,
  291. (Uint)25687346509278435ULL,
  292. (Uint)100000000000000000ULL,
  293. (Uint)9223372036854775807ULL,
  294. };
  295. FOR_EACH_RANGE (i, 0, sizeof(strings3) / sizeof(*strings3)) {
  296. EXPECT_EQ(to<Uint>(strings3[i]), values3[i]);
  297. EXPECT_EQ(to<Sint>(strings3[i]), values3[i]);
  298. }
  299. static const String uStrings3[] = {
  300. "9223372036854775808",
  301. "9987435987394857987",
  302. "17873648761234698740",
  303. "18446744073709551615",
  304. };
  305. static const Uint uValues3[] = {
  306. (Uint)9223372036854775808ULL,
  307. (Uint)9987435987394857987ULL,
  308. (Uint)17873648761234698740ULL,
  309. (Uint)18446744073709551615ULL,
  310. };
  311. FOR_EACH_RANGE (i, 0, sizeof(uStrings3) / sizeof(*uStrings3)) {
  312. EXPECT_EQ(to<Uint>(uStrings3[i]), uValues3[i]);
  313. if (sizeof(Int) == 8) {
  314. EXPECT_THROW(to<Sint>(uStrings3[i]), std::range_error);
  315. }
  316. }
  317. }
  318. // Minimum possible negative values, and negative sign overflow
  319. static const String strings4[] = {
  320. "-128",
  321. "-32768",
  322. "-2147483648",
  323. "-9223372036854775808",
  324. };
  325. static const String strings5[] = {
  326. "-129",
  327. "-32769",
  328. "-2147483649",
  329. "-9223372036854775809",
  330. };
  331. static const Sint values4[] = {
  332. (Sint)-128LL,
  333. (Sint)-32768LL,
  334. (Sint)-2147483648LL,
  335. (Sint)(-9223372036854775807LL - 1),
  336. };
  337. FOR_EACH_RANGE (i, 0, sizeof(strings4) / sizeof(*strings4)) {
  338. if (sizeof(Int) > std::pow(2, i)) {
  339. EXPECT_EQ(values4[i], to<Sint>(strings4[i]));
  340. EXPECT_EQ(values4[i] - 1, to<Sint>(strings5[i]));
  341. } else if (sizeof(Int) == std::pow(2, i)) {
  342. EXPECT_EQ(values4[i], to<Sint>(strings4[i]));
  343. EXPECT_THROW(to<Sint>(strings5[i]), std::range_error);
  344. } else {
  345. EXPECT_THROW(to<Sint>(strings4[i]), std::range_error);
  346. EXPECT_THROW(to<Sint>(strings5[i]), std::range_error);
  347. }
  348. }
  349. // Bogus string values
  350. static const String bogusStrings[] = {
  351. "",
  352. "0x1234",
  353. "123L",
  354. "123a",
  355. "x 123 ",
  356. "234 y",
  357. "- 42", // whitespace is not allowed between the sign and the value
  358. " + 13 ",
  359. "12345678901234567890123456789",
  360. };
  361. for (const auto& str : bogusStrings) {
  362. EXPECT_THROW(to<Sint>(str), std::range_error);
  363. EXPECT_THROW(to<Uint>(str), std::range_error);
  364. }
  365. // A leading '+' character is only allowed when converting to signed types.
  366. String posSign("+42");
  367. EXPECT_EQ(42, to<Sint>(posSign));
  368. EXPECT_THROW(to<Uint>(posSign), std::range_error);
  369. testString2Integral<String, Ints...>();
  370. }
  371. TEST(Conv, String2Integral) {
  372. testString2Integral<const char*, int8_t, int16_t, int32_t, int64_t>();
  373. testString2Integral<std::string, int8_t, int16_t, int32_t, int64_t>();
  374. testString2Integral<fbstring, int8_t, int16_t, int32_t, int64_t>();
  375. // Testing the behavior of the StringPiece* API
  376. // StringPiece* normally parses as much valid data as it can,
  377. // and advances the StringPiece to the end of the valid data.
  378. char buf1[] = "100foo";
  379. StringPiece sp1(buf1);
  380. EXPECT_EQ(100, to<uint8_t>(&sp1));
  381. EXPECT_EQ(buf1 + 3, sp1.begin());
  382. // However, if the next character would cause an overflow it throws a
  383. // range_error rather than consuming only as much as it can without
  384. // overflowing.
  385. char buf2[] = "1002";
  386. StringPiece sp2(buf2);
  387. EXPECT_THROW(to<uint8_t>(&sp2), std::range_error);
  388. EXPECT_EQ(buf2, sp2.begin());
  389. }
  390. TEST(Conv, StringPiece2Integral) {
  391. string s = " +123 hello world ";
  392. StringPiece sp = s;
  393. EXPECT_EQ(to<int>(&sp), 123);
  394. EXPECT_EQ(sp, " hello world ");
  395. }
  396. TEST(Conv, StringPieceAppend) {
  397. string s = "foobar";
  398. {
  399. StringPiece sp(s, 0, 3);
  400. string result = to<string>(s, sp);
  401. EXPECT_EQ(result, "foobarfoo");
  402. }
  403. {
  404. StringPiece sp1(s, 0, 3);
  405. StringPiece sp2(s, 3, 3);
  406. string result = to<string>(sp1, sp2);
  407. EXPECT_EQ(result, s);
  408. }
  409. }
  410. TEST(Conv, BadStringToIntegral) {
  411. // Note that leading spaces (e.g. " 1") are valid.
  412. vector<string> v = {"a", "", " ", "\n", " a0", "abcdef", "1Z", "!#"};
  413. for (auto& s : v) {
  414. EXPECT_THROW(to<int>(s), std::range_error) << "s=" << s;
  415. }
  416. }
  417. template <class String>
  418. void testIdenticalTo() {
  419. String s("Yukkuri shiteitte ne!!!");
  420. String result = to<String>(s);
  421. EXPECT_EQ(result, s);
  422. }
  423. template <class String>
  424. void testVariadicTo() {
  425. String s;
  426. toAppend(&s);
  427. toAppend("Lorem ipsum ", 1234, String(" dolor amet "), 567.89, '!', &s);
  428. EXPECT_EQ(s, "Lorem ipsum 1234 dolor amet 567.89!");
  429. s = to<String>();
  430. EXPECT_TRUE(s.empty());
  431. s = to<String>("Lorem ipsum ", nullptr, 1234, " dolor amet ", 567.89, '.');
  432. EXPECT_EQ(s, "Lorem ipsum 1234 dolor amet 567.89.");
  433. }
  434. template <class String>
  435. void testIdenticalToDelim() {
  436. String s("Yukkuri shiteitte ne!!!");
  437. String charDelim = toDelim<String>('$', s);
  438. EXPECT_EQ(charDelim, s);
  439. String strDelim = toDelim<String>(String(">_<"), s);
  440. EXPECT_EQ(strDelim, s);
  441. }
  442. template <class String>
  443. void testVariadicToDelim() {
  444. String s;
  445. toAppendDelim(":", &s);
  446. toAppendDelim(
  447. ":", "Lorem ipsum ", 1234, String(" dolor amet "), 567.89, '!', &s);
  448. EXPECT_EQ(s, "Lorem ipsum :1234: dolor amet :567.89:!");
  449. s = toDelim<String>(':');
  450. EXPECT_TRUE(s.empty());
  451. s = toDelim<String>(
  452. ":", "Lorem ipsum ", nullptr, 1234, " dolor amet ", 567.89, '.');
  453. EXPECT_EQ(s, "Lorem ipsum ::1234: dolor amet :567.89:.");
  454. }
  455. TEST(Conv, NullString) {
  456. string s1 = to<string>((char*)nullptr);
  457. EXPECT_TRUE(s1.empty());
  458. fbstring s2 = to<fbstring>((char*)nullptr);
  459. EXPECT_TRUE(s2.empty());
  460. }
  461. TEST(Conv, VariadicTo) {
  462. testIdenticalTo<string>();
  463. testIdenticalTo<fbstring>();
  464. testVariadicTo<string>();
  465. testVariadicTo<fbstring>();
  466. }
  467. TEST(Conv, VariadicToDelim) {
  468. testIdenticalToDelim<string>();
  469. testIdenticalToDelim<fbstring>();
  470. testVariadicToDelim<string>();
  471. testVariadicToDelim<fbstring>();
  472. }
  473. template <class String>
  474. void testDoubleToString() {
  475. EXPECT_EQ(to<string>(0.0), "0");
  476. EXPECT_EQ(to<string>(0.5), "0.5");
  477. EXPECT_EQ(to<string>(10.25), "10.25");
  478. EXPECT_EQ(to<string>(1.123e10), "11230000000");
  479. }
  480. TEST(Conv, DoubleToString) {
  481. testDoubleToString<string>();
  482. testDoubleToString<fbstring>();
  483. }
  484. TEST(Conv, FBStringToString) {
  485. fbstring foo("foo");
  486. string ret = to<string>(foo);
  487. EXPECT_EQ(ret, "foo");
  488. string ret2 = to<string>(foo, 2);
  489. EXPECT_EQ(ret2, "foo2");
  490. }
  491. TEST(Conv, StringPieceToDouble) {
  492. vector<tuple<const char*, const char*, double>> strs{
  493. make_tuple("2134123.125 zorro", " zorro", 2134123.125),
  494. make_tuple(" 2134123.125 zorro", " zorro", 2134123.125),
  495. make_tuple(" 2134123.125 zorro", " zorro", 2134123.125),
  496. make_tuple(" 2134123.125 zorro ", " zorro ", 2134123.125),
  497. make_tuple("2134123.125zorro", "zorro", 2134123.125),
  498. make_tuple("0 zorro", " zorro", 0.0),
  499. make_tuple(" 0 zorro", " zorro", 0.0),
  500. make_tuple(" 0 zorro", " zorro", 0.0),
  501. make_tuple(" 0 zorro ", " zorro ", 0.0),
  502. make_tuple("0zorro", "zorro", 0.0),
  503. make_tuple("0.0 zorro", " zorro", 0.0),
  504. make_tuple(" 0.0 zorro", " zorro", 0.0),
  505. make_tuple(" 0.0 zorro", " zorro", 0.0),
  506. make_tuple(" 0.0 zorro ", " zorro ", 0.0),
  507. make_tuple("0.0zorro", "zorro", 0.0),
  508. make_tuple("0.0eb", "eb", 0.0),
  509. make_tuple("0.0EB", "EB", 0.0),
  510. make_tuple("0eb", "eb", 0.0),
  511. make_tuple("0EB", "EB", 0.0),
  512. make_tuple("12e", "e", 12.0),
  513. make_tuple("12e-", "e-", 12.0),
  514. make_tuple("12e+", "e+", 12.0),
  515. make_tuple("12e-f-g", "e-f-g", 12.0),
  516. make_tuple("12e+f+g", "e+f+g", 12.0),
  517. make_tuple("12euro", "euro", 12.0),
  518. };
  519. for (const auto& s : strs) {
  520. StringPiece pc(get<0>(s));
  521. EXPECT_EQ(get<2>(s), to<double>(&pc)) << "\"" << get<0>(s) << "\"";
  522. EXPECT_EQ(get<1>(s), pc);
  523. EXPECT_THROW(to<double>(StringPiece(get<0>(s))), std::range_error);
  524. EXPECT_EQ(get<2>(s), to<double>(StringPiece(get<0>(s), pc.data())));
  525. }
  526. // Test NaN conversion
  527. try {
  528. to<double>("not a number");
  529. ADD_FAILURE();
  530. } catch (const std::range_error&) {
  531. }
  532. EXPECT_TRUE(std::isnan(to<double>("nan")));
  533. EXPECT_TRUE(std::isnan(to<double>("NaN")));
  534. EXPECT_TRUE(std::isnan(to<double>("NAN")));
  535. EXPECT_TRUE(std::isnan(to<double>("-nan")));
  536. EXPECT_TRUE(std::isnan(to<double>("-NaN")));
  537. EXPECT_TRUE(std::isnan(to<double>("-NAN")));
  538. EXPECT_EQ(to<double>("inf"), numeric_limits<double>::infinity());
  539. EXPECT_EQ(to<double>("Inf"), numeric_limits<double>::infinity());
  540. EXPECT_EQ(to<double>("INF"), numeric_limits<double>::infinity());
  541. EXPECT_EQ(to<double>("inF"), numeric_limits<double>::infinity());
  542. EXPECT_EQ(to<double>("infinity"), numeric_limits<double>::infinity());
  543. EXPECT_EQ(to<double>("Infinity"), numeric_limits<double>::infinity());
  544. EXPECT_EQ(to<double>("INFINITY"), numeric_limits<double>::infinity());
  545. EXPECT_EQ(to<double>("iNfInItY"), numeric_limits<double>::infinity());
  546. EXPECT_THROW(to<double>("infinitX"), std::range_error);
  547. EXPECT_EQ(to<double>("-inf"), -numeric_limits<double>::infinity());
  548. EXPECT_EQ(to<double>("-Inf"), -numeric_limits<double>::infinity());
  549. EXPECT_EQ(to<double>("-INF"), -numeric_limits<double>::infinity());
  550. EXPECT_EQ(to<double>("-inF"), -numeric_limits<double>::infinity());
  551. EXPECT_EQ(to<double>("-infinity"), -numeric_limits<double>::infinity());
  552. EXPECT_EQ(to<double>("-Infinity"), -numeric_limits<double>::infinity());
  553. EXPECT_EQ(to<double>("-INFINITY"), -numeric_limits<double>::infinity());
  554. EXPECT_EQ(to<double>("-iNfInItY"), -numeric_limits<double>::infinity());
  555. EXPECT_THROW(to<double>("-infinitX"), std::range_error);
  556. }
  557. TEST(Conv, EmptyStringToInt) {
  558. string s = "";
  559. StringPiece pc(s);
  560. try {
  561. to<int>(pc);
  562. ADD_FAILURE();
  563. } catch (const std::range_error&) {
  564. }
  565. }
  566. TEST(Conv, CorruptedStringToInt) {
  567. string s = "-1";
  568. StringPiece pc(s.data(), s.data() + 1); // Only "-"
  569. try {
  570. to<int64_t>(&pc);
  571. ADD_FAILURE();
  572. } catch (const std::range_error&) {
  573. }
  574. }
  575. TEST(Conv, EmptyStringToDouble) {
  576. string s = "";
  577. StringPiece pc(s);
  578. try {
  579. to<double>(pc);
  580. ADD_FAILURE();
  581. } catch (const std::range_error&) {
  582. }
  583. }
  584. TEST(Conv, IntToDouble) {
  585. auto d = to<double>(42);
  586. EXPECT_EQ(d, 42);
  587. /* This seems not work in ubuntu11.10, gcc 4.6.1
  588. try {
  589. auto f = to<float>(957837589847);
  590. ADD_FAILURE();
  591. } catch (std::range_error& e) {
  592. //LOG(INFO) << e.what();
  593. }
  594. */
  595. }
  596. TEST(Conv, DoubleToInt) {
  597. auto i = to<int>(42.0);
  598. EXPECT_EQ(i, 42);
  599. try {
  600. auto i2 = to<int>(42.1);
  601. LOG(ERROR) << "to<int> returned " << i2 << " instead of throwing";
  602. ADD_FAILURE();
  603. } catch (std::range_error&) {
  604. // LOG(INFO) << e.what();
  605. }
  606. }
  607. TEST(Conv, EnumToInt) {
  608. enum A { x = 42, y = 420, z = 65 };
  609. auto i = to<int>(x);
  610. EXPECT_EQ(i, 42);
  611. auto j = to<char>(x);
  612. EXPECT_EQ(j, 42);
  613. try {
  614. auto i2 = to<char>(y);
  615. LOG(ERROR) << "to<char> returned " << static_cast<unsigned int>(i2)
  616. << " instead of throwing";
  617. ADD_FAILURE();
  618. } catch (std::range_error&) {
  619. // LOG(INFO) << e.what();
  620. }
  621. }
  622. TEST(Conv, EnumToString) {
  623. // task 813959
  624. enum A { x = 4, y = 420, z = 65 };
  625. EXPECT_EQ("foo.4", to<string>("foo.", x));
  626. EXPECT_EQ("foo.420", to<string>("foo.", y));
  627. EXPECT_EQ("foo.65", to<string>("foo.", z));
  628. }
  629. TEST(Conv, IntToEnum) {
  630. enum A { x = 42, y = 420 };
  631. auto i = to<A>(42);
  632. EXPECT_EQ(i, x);
  633. auto j = to<A>(100);
  634. EXPECT_EQ(j, 100);
  635. try {
  636. auto i2 = to<A>(5000000000L);
  637. LOG(ERROR) << "to<A> returned " << static_cast<unsigned int>(i2)
  638. << " instead of throwing";
  639. ADD_FAILURE();
  640. } catch (std::range_error&) {
  641. // LOG(INFO) << e.what();
  642. }
  643. }
  644. TEST(Conv, UnsignedEnum) {
  645. enum E : uint32_t { x = 3000000000U };
  646. auto u = to<uint32_t>(x);
  647. EXPECT_EQ(u, 3000000000U);
  648. auto s = to<string>(x);
  649. EXPECT_EQ("3000000000", s);
  650. auto e = to<E>(3000000000U);
  651. EXPECT_EQ(e, x);
  652. try {
  653. auto i = to<int32_t>(x);
  654. LOG(ERROR) << "to<int32_t> returned " << i << " instead of throwing";
  655. ADD_FAILURE();
  656. } catch (std::range_error&) {
  657. }
  658. }
  659. TEST(Conv, UnsignedEnumClass) {
  660. enum class E : uint32_t { x = 3000000000U };
  661. auto u = to<uint32_t>(E::x);
  662. EXPECT_GT(u, 0);
  663. EXPECT_EQ(u, 3000000000U);
  664. EXPECT_EQ("3000000000", to<string>(E::x));
  665. EXPECT_EQ(E::x, to<E>(3000000000U));
  666. EXPECT_EQ(E::x, to<E>("3000000000"));
  667. E e;
  668. EXPECT_TRUE(parseTo("3000000000", e).hasValue());
  669. EXPECT_EQ(E::x, e);
  670. EXPECT_THROW(to<int32_t>(E::x), std::range_error);
  671. }
  672. // Multi-argument to<string> uses toAppend, a different code path than
  673. // to<string>(enum).
  674. TEST(Conv, EnumClassToString) {
  675. enum class A { x = 4, y = 420, z = 65 };
  676. EXPECT_EQ("foo.4", to<string>("foo.", A::x));
  677. EXPECT_EQ("foo.420", to<string>("foo.", A::y));
  678. EXPECT_EQ("foo.65", to<string>("foo.", A::z));
  679. }
  680. TEST(Conv, IntegralToBool) {
  681. EXPECT_FALSE(to<bool>(0));
  682. EXPECT_FALSE(to<bool>(0ul));
  683. EXPECT_TRUE(to<bool>(1));
  684. EXPECT_TRUE(to<bool>(1ul));
  685. EXPECT_TRUE(to<bool>(-42));
  686. EXPECT_TRUE(to<bool>(42ul));
  687. }
  688. template <typename Src>
  689. void testStr2Bool() {
  690. EXPECT_FALSE(to<bool>(Src("0")));
  691. EXPECT_FALSE(to<bool>(Src(" 000 ")));
  692. EXPECT_FALSE(to<bool>(Src("n")));
  693. EXPECT_FALSE(to<bool>(Src("no")));
  694. EXPECT_FALSE(to<bool>(Src("false")));
  695. EXPECT_FALSE(to<bool>(Src("False")));
  696. EXPECT_FALSE(to<bool>(Src(" fAlSe ")));
  697. EXPECT_FALSE(to<bool>(Src("F")));
  698. EXPECT_FALSE(to<bool>(Src("off")));
  699. EXPECT_TRUE(to<bool>(Src("1")));
  700. EXPECT_TRUE(to<bool>(Src(" 001 ")));
  701. EXPECT_TRUE(to<bool>(Src("y")));
  702. EXPECT_TRUE(to<bool>(Src("yes")));
  703. EXPECT_TRUE(to<bool>(Src("\nyEs\t")));
  704. EXPECT_TRUE(to<bool>(Src("true")));
  705. EXPECT_TRUE(to<bool>(Src("True")));
  706. EXPECT_TRUE(to<bool>(Src("T")));
  707. EXPECT_TRUE(to<bool>(Src("on")));
  708. EXPECT_THROW(to<bool>(Src("")), std::range_error);
  709. EXPECT_THROW(to<bool>(Src("2")), std::range_error);
  710. EXPECT_THROW(to<bool>(Src("11")), std::range_error);
  711. EXPECT_THROW(to<bool>(Src("19")), std::range_error);
  712. EXPECT_THROW(to<bool>(Src("o")), std::range_error);
  713. EXPECT_THROW(to<bool>(Src("fal")), std::range_error);
  714. EXPECT_THROW(to<bool>(Src("tru")), std::range_error);
  715. EXPECT_THROW(to<bool>(Src("ye")), std::range_error);
  716. EXPECT_THROW(to<bool>(Src("yes foo")), std::range_error);
  717. EXPECT_THROW(to<bool>(Src("bar no")), std::range_error);
  718. EXPECT_THROW(to<bool>(Src("one")), std::range_error);
  719. EXPECT_THROW(to<bool>(Src("true_")), std::range_error);
  720. EXPECT_THROW(to<bool>(Src("bogus_token_that_is_too_long")), std::range_error);
  721. }
  722. TEST(Conv, StringToBool) {
  723. // testStr2Bool<const char *>();
  724. testStr2Bool<std::string>();
  725. // Test with strings that are not NUL terminated.
  726. const char buf[] = "01234";
  727. EXPECT_FALSE(to<bool>(StringPiece(buf, buf + 1))); // "0"
  728. EXPECT_TRUE(to<bool>(StringPiece(buf + 1, buf + 2))); // "1"
  729. const char buf2[] = "one two three";
  730. EXPECT_TRUE(to<bool>(StringPiece(buf2, buf2 + 2))); // "on"
  731. const char buf3[] = "false";
  732. EXPECT_THROW(
  733. to<bool>(StringPiece(buf3, buf3 + 3)), // "fal"
  734. std::range_error);
  735. // Test the StringPiece* API
  736. const char buf4[] = "001foo";
  737. StringPiece sp4(buf4);
  738. EXPECT_TRUE(to<bool>(&sp4));
  739. EXPECT_EQ(buf4 + 3, sp4.begin());
  740. const char buf5[] = "0012";
  741. StringPiece sp5(buf5);
  742. EXPECT_THROW(to<bool>(&sp5), std::range_error);
  743. EXPECT_EQ(buf5, sp5.begin());
  744. }
  745. TEST(Conv, Transform) {
  746. const std::vector<int64_t> in{1, 2, 3};
  747. std::vector<std::string> out(in.size());
  748. std::transform(in.begin(), in.end(), out.begin(), to<std::string, int64_t>);
  749. const std::vector<std::string> ref{"1", "2", "3"};
  750. EXPECT_EQ(ref, out);
  751. }
  752. TEST(Conv, FloatToInt) {
  753. EXPECT_EQ(to<int>(42.0f), 42);
  754. EXPECT_EQ(to<int8_t>(-128.0f), int8_t(-128));
  755. EXPECT_THROW(to<int8_t>(-129.0), std::range_error);
  756. EXPECT_THROW(to<int8_t>(127.001), std::range_error);
  757. EXPECT_THROW(to<uint8_t>(-0.0001), std::range_error);
  758. EXPECT_THROW(
  759. to<uint64_t>(static_cast<float>(std::numeric_limits<uint64_t>::max())),
  760. std::range_error);
  761. }
  762. TEST(Conv, IntToFloat) {
  763. EXPECT_EQ(to<float>(42ULL), 42.0);
  764. EXPECT_EQ(to<float>(int8_t(-128)), -128.0);
  765. EXPECT_THROW(
  766. to<float>(std::numeric_limits<uint64_t>::max()), std::range_error);
  767. EXPECT_THROW(
  768. to<float>(std::numeric_limits<int64_t>::max()), std::range_error);
  769. EXPECT_THROW(
  770. to<float>(std::numeric_limits<int64_t>::min() + 1), std::range_error);
  771. #if FOLLY_HAVE_INT128_T
  772. EXPECT_THROW(
  773. to<double>(std::numeric_limits<unsigned __int128>::max()),
  774. std::range_error);
  775. EXPECT_THROW(
  776. to<double>(std::numeric_limits<__int128>::max()), std::range_error);
  777. EXPECT_THROW(
  778. to<double>(std::numeric_limits<__int128>::min() + 1), std::range_error);
  779. #endif
  780. }
  781. TEST(Conv, BoolToFloat) {
  782. EXPECT_EQ(to<double>(true), 1.0);
  783. EXPECT_EQ(to<double>(false), 0.0);
  784. }
  785. TEST(Conv, FloatToBool) {
  786. EXPECT_EQ(to<bool>(1.0), true);
  787. EXPECT_EQ(to<bool>(0.0), false);
  788. EXPECT_EQ(to<bool>(2.7), true);
  789. EXPECT_EQ(to<bool>(std::numeric_limits<double>::max()), true);
  790. EXPECT_EQ(to<bool>(std::numeric_limits<double>::min()), true);
  791. EXPECT_EQ(to<bool>(std::numeric_limits<double>::lowest()), true);
  792. EXPECT_EQ(to<bool>(std::numeric_limits<double>::quiet_NaN()), true);
  793. EXPECT_EQ(to<bool>(std::numeric_limits<double>::infinity()), true);
  794. EXPECT_EQ(to<bool>(-std::numeric_limits<double>::infinity()), true);
  795. }
  796. namespace {
  797. template <typename F>
  798. void testConvError(
  799. F&& expr,
  800. const char* exprStr,
  801. ConversionCode code,
  802. const char* value,
  803. bool quotedValue,
  804. int line) {
  805. std::string where = to<std::string>(__FILE__, "(", line, "): ");
  806. try {
  807. auto res = expr();
  808. ADD_FAILURE() << where << exprStr << " -> " << res;
  809. } catch (const ConversionError& e) {
  810. EXPECT_EQ(code, e.errorCode()) << where << exprStr;
  811. std::string str(e.what());
  812. EXPECT_FALSE(str.empty()) << where << exprStr << " -> " << str;
  813. auto pos = str.find(':');
  814. if (value) {
  815. std::ostringstream exp;
  816. exp << str.substr(0, pos) + ": ";
  817. if (quotedValue) {
  818. exp << "\"" << value << "\"";
  819. } else {
  820. exp << value;
  821. }
  822. EXPECT_EQ(exp.str(), str) << where << exprStr << " -> " << str;
  823. } else {
  824. EXPECT_EQ(pos, std::string::npos) << where << exprStr << " -> " << str;
  825. }
  826. }
  827. }
  828. } // namespace
  829. #define EXPECT_CONV_ERROR_QUOTE(expr, code, value, quoted) \
  830. testConvError( \
  831. [&] { return expr; }, \
  832. #expr, \
  833. ConversionCode::code, \
  834. value, \
  835. quoted, \
  836. __LINE__)
  837. #define EXPECT_CONV_ERROR(expr, code, value) \
  838. EXPECT_CONV_ERROR_QUOTE(expr, code, value, true)
  839. #define EXPECT_CONV_ERROR_STR(type, str, code) \
  840. EXPECT_CONV_ERROR(to<type>(str), code, str)
  841. #define EXPECT_CONV_ERROR_STR_NOVAL(type, str, code) \
  842. EXPECT_CONV_ERROR(to<type>(str), code, nullptr)
  843. TEST(Conv, ConversionErrorStrToBool) {
  844. EXPECT_CONV_ERROR_STR_NOVAL(bool, StringPiece(), EMPTY_INPUT_STRING);
  845. EXPECT_CONV_ERROR_STR_NOVAL(bool, "", EMPTY_INPUT_STRING);
  846. EXPECT_CONV_ERROR_STR(bool, " ", EMPTY_INPUT_STRING);
  847. EXPECT_CONV_ERROR_STR(bool, " 11 ", BOOL_OVERFLOW);
  848. EXPECT_CONV_ERROR_STR(bool, "other ", BOOL_INVALID_VALUE);
  849. EXPECT_CONV_ERROR_STR(bool, " bla", BOOL_INVALID_VALUE);
  850. EXPECT_CONV_ERROR(to<bool>(" offbla"), NON_WHITESPACE_AFTER_END, "bla");
  851. }
  852. TEST(Conv, ConversionErrorStrToFloat) {
  853. EXPECT_CONV_ERROR_STR_NOVAL(float, StringPiece(), EMPTY_INPUT_STRING);
  854. EXPECT_CONV_ERROR_STR_NOVAL(float, "", EMPTY_INPUT_STRING);
  855. EXPECT_CONV_ERROR_STR(float, " ", EMPTY_INPUT_STRING);
  856. EXPECT_CONV_ERROR_STR(float, " junk", STRING_TO_FLOAT_ERROR);
  857. EXPECT_CONV_ERROR(to<float>(" 1bla"), NON_WHITESPACE_AFTER_END, "bla");
  858. }
  859. TEST(Conv, ConversionErrorStrToInt) {
  860. // empty string handling
  861. EXPECT_CONV_ERROR_STR_NOVAL(int, StringPiece(), EMPTY_INPUT_STRING);
  862. EXPECT_CONV_ERROR_STR_NOVAL(int, "", EMPTY_INPUT_STRING);
  863. EXPECT_CONV_ERROR_STR(int, " ", EMPTY_INPUT_STRING);
  864. // signed integers
  865. EXPECT_CONV_ERROR_STR(int, " *", INVALID_LEADING_CHAR);
  866. EXPECT_CONV_ERROR_STR(int, " +", NO_DIGITS);
  867. EXPECT_CONV_ERROR_STR(int, " +*", NON_DIGIT_CHAR);
  868. EXPECT_CONV_ERROR_STR(int8_t, " 128", POSITIVE_OVERFLOW);
  869. EXPECT_CONV_ERROR_STR(int8_t, " -129", NEGATIVE_OVERFLOW);
  870. EXPECT_CONV_ERROR_STR(int8_t, " 1000", POSITIVE_OVERFLOW);
  871. EXPECT_CONV_ERROR_STR(int8_t, "-1000", NEGATIVE_OVERFLOW);
  872. EXPECT_CONV_ERROR(to<int>(" -13bla"), NON_WHITESPACE_AFTER_END, "bla");
  873. // unsigned integers
  874. EXPECT_CONV_ERROR_STR(unsigned, " -", NON_DIGIT_CHAR);
  875. EXPECT_CONV_ERROR_STR(uint8_t, " 256", POSITIVE_OVERFLOW);
  876. EXPECT_CONV_ERROR(to<unsigned>("42bla"), NON_WHITESPACE_AFTER_END, "bla");
  877. }
  878. #define EXPECT_CONV_ERROR_PP_VAL(type, str, code, val) \
  879. do { \
  880. StringPiece input(str); \
  881. EXPECT_CONV_ERROR(to<type>(input.begin(), input.end()), code, val); \
  882. } while (0)
  883. #define EXPECT_CONV_ERROR_PP(type, str, code) \
  884. EXPECT_CONV_ERROR_PP_VAL(type, str, code, str)
  885. TEST(Conv, ConversionErrorPtrPairToInt) {
  886. // signed integers
  887. EXPECT_CONV_ERROR_PP(int, "", INVALID_LEADING_CHAR);
  888. EXPECT_CONV_ERROR_PP(int, " ", INVALID_LEADING_CHAR);
  889. EXPECT_CONV_ERROR_PP(int, "*", INVALID_LEADING_CHAR);
  890. EXPECT_CONV_ERROR_PP(int, "+", NO_DIGITS);
  891. EXPECT_CONV_ERROR_PP(int8_t, "128", POSITIVE_OVERFLOW);
  892. EXPECT_CONV_ERROR_PP(int8_t, "-129", NEGATIVE_OVERFLOW);
  893. EXPECT_CONV_ERROR_PP(int8_t, "1000", POSITIVE_OVERFLOW);
  894. EXPECT_CONV_ERROR_PP(int8_t, "-1000", NEGATIVE_OVERFLOW);
  895. EXPECT_CONV_ERROR_PP(int, "-junk", NON_DIGIT_CHAR);
  896. // unsigned integers
  897. EXPECT_CONV_ERROR_PP(unsigned, "", NO_DIGITS);
  898. EXPECT_CONV_ERROR_PP(uint8_t, "256", POSITIVE_OVERFLOW);
  899. EXPECT_CONV_ERROR_PP(unsigned, "junk", NON_DIGIT_CHAR);
  900. }
  901. namespace {
  902. template <typename T, typename V>
  903. std::string prefixWithType(V value) {
  904. std::ostringstream oss;
  905. #ifdef FOLLY_HAS_RTTI
  906. oss << "(" << demangle(typeid(T)) << ") ";
  907. #endif
  908. oss << to<std::string>(value);
  909. return oss.str();
  910. }
  911. } // namespace
  912. #define EXPECT_CONV_ERROR_ARITH(type, val, code) \
  913. EXPECT_CONV_ERROR_QUOTE( \
  914. to<type>(val), code, prefixWithType<type>(val).c_str(), false)
  915. TEST(Conv, ConversionErrorIntToInt) {
  916. EXPECT_CONV_ERROR_ARITH(signed char, 128, ARITH_POSITIVE_OVERFLOW);
  917. EXPECT_CONV_ERROR_ARITH(unsigned char, -1, ARITH_NEGATIVE_OVERFLOW);
  918. }
  919. TEST(Conv, ConversionErrorFloatToFloat) {
  920. EXPECT_CONV_ERROR_ARITH(
  921. float, std::numeric_limits<double>::max(), ARITH_POSITIVE_OVERFLOW);
  922. EXPECT_CONV_ERROR_ARITH(
  923. float, std::numeric_limits<double>::lowest(), ARITH_NEGATIVE_OVERFLOW);
  924. }
  925. TEST(Conv, ConversionErrorIntToFloat) {
  926. EXPECT_CONV_ERROR_ARITH(
  927. float, std::numeric_limits<long long>::max(), ARITH_LOSS_OF_PRECISION);
  928. }
  929. TEST(Conv, ConversionErrorFloatToInt) {
  930. EXPECT_CONV_ERROR_ARITH(int8_t, 65.5, ARITH_LOSS_OF_PRECISION);
  931. }
  932. TEST(Conv, TryStringToBool) {
  933. auto rv1 = folly::tryTo<bool>("xxxx");
  934. EXPECT_FALSE(rv1.hasValue());
  935. auto rv2 = folly::tryTo<bool>("false");
  936. EXPECT_TRUE(rv2.hasValue());
  937. EXPECT_FALSE(rv2.value());
  938. auto rv3 = folly::tryTo<bool>("yes");
  939. EXPECT_TRUE(rv3.hasValue());
  940. EXPECT_TRUE(rv3.value());
  941. }
  942. TEST(Conv, TryStringToInt) {
  943. auto rv1 = folly::tryTo<int>("1000000000000000000000000000000");
  944. EXPECT_FALSE(rv1.hasValue());
  945. auto rv2 = folly::tryTo<int>("4711");
  946. EXPECT_TRUE(rv2.hasValue());
  947. EXPECT_EQ(rv2.value(), 4711);
  948. }
  949. TEST(Conv, TryStringToEnum) {
  950. enum class A { x = 42, y = 420, z = 65 };
  951. auto rv1 = folly::tryTo<A>("1000000000000000000000000000000");
  952. EXPECT_FALSE(rv1.hasValue());
  953. auto rv2 = folly::tryTo<A>("42");
  954. EXPECT_TRUE(rv2.hasValue());
  955. EXPECT_EQ(A::x, rv2.value());
  956. auto rv3 = folly::tryTo<A>("50");
  957. EXPECT_TRUE(rv3.hasValue());
  958. EXPECT_EQ(static_cast<A>(50), rv3.value());
  959. }
  960. TEST(Conv, TryStringToFloat) {
  961. auto rv1 = folly::tryTo<float>("");
  962. EXPECT_FALSE(rv1.hasValue());
  963. auto rv2 = folly::tryTo<float>("3.14");
  964. EXPECT_TRUE(rv2.hasValue());
  965. EXPECT_NEAR(rv2.value(), 3.14, 1e-5);
  966. }
  967. TEST(Conv, TryStringToDouble) {
  968. auto rv1 = folly::tryTo<double>("");
  969. EXPECT_FALSE(rv1.hasValue());
  970. auto rv2 = folly::tryTo<double>("3.14");
  971. EXPECT_TRUE(rv2.hasValue());
  972. EXPECT_NEAR(rv2.value(), 3.14, 1e-10);
  973. }
  974. TEST(Conv, TryIntToInt) {
  975. auto rv1 = folly::tryTo<uint8_t>(256);
  976. EXPECT_FALSE(rv1.hasValue());
  977. auto rv2 = folly::tryTo<uint8_t>(255);
  978. EXPECT_TRUE(rv2.hasValue());
  979. EXPECT_EQ(rv2.value(), 255);
  980. }
  981. TEST(Conv, TryFloatToFloat) {
  982. auto rv1 = folly::tryTo<float>(1e100);
  983. EXPECT_FALSE(rv1.hasValue());
  984. auto rv2 = folly::tryTo<double>(25.5f);
  985. EXPECT_TRUE(rv2.hasValue());
  986. EXPECT_NEAR(rv2.value(), 25.5, 1e-10);
  987. }
  988. TEST(Conv, TryFloatToInt) {
  989. auto rv1 = folly::tryTo<int>(100.001);
  990. EXPECT_FALSE(rv1.hasValue());
  991. auto rv2 = folly::tryTo<int>(100.0);
  992. EXPECT_TRUE(rv2.hasValue());
  993. EXPECT_EQ(rv2.value(), 100);
  994. }
  995. TEST(Conv, TryIntToFloat) {
  996. auto rv1 = folly::tryTo<float>(std::numeric_limits<uint64_t>::max());
  997. EXPECT_FALSE(rv1.hasValue());
  998. auto rv2 = folly::tryTo<float>(1000ULL);
  999. EXPECT_TRUE(rv2.hasValue());
  1000. EXPECT_EQ(rv2.value(), 1000.0f);
  1001. }
  1002. TEST(Conv, TryPtrPairToInt) {
  1003. StringPiece sp1("1000000000000000000000000000000");
  1004. auto rv1 = folly::tryTo<int>(sp1.begin(), sp1.end());
  1005. EXPECT_FALSE(rv1.hasValue());
  1006. StringPiece sp2("4711");
  1007. auto rv2 = folly::tryTo<int>(sp2.begin(), sp2.end());
  1008. EXPECT_TRUE(rv2.hasValue());
  1009. EXPECT_EQ(rv2.value(), 4711);
  1010. StringPiece sp3("-4711");
  1011. auto rv3 = folly::tryTo<int>(sp3.begin(), sp3.end());
  1012. EXPECT_TRUE(rv3.hasValue());
  1013. EXPECT_EQ(rv3.value(), -4711);
  1014. StringPiece sp4("4711");
  1015. auto rv4 = folly::tryTo<uint16_t>(sp4.begin(), sp4.end());
  1016. EXPECT_TRUE(rv4.hasValue());
  1017. EXPECT_EQ(rv4.value(), 4711);
  1018. }
  1019. TEST(Conv, NewUint64ToString) {
  1020. char buf[21];
  1021. #define THE_GREAT_EXPECTATIONS(n, len) \
  1022. do { \
  1023. EXPECT_EQ((len), uint64ToBufferUnsafe((n), buf)); \
  1024. buf[(len)] = 0; \
  1025. auto s = string(#n); \
  1026. s = s.substr(0, s.size() - 2); \
  1027. EXPECT_EQ(s, buf); \
  1028. } while (0)
  1029. THE_GREAT_EXPECTATIONS(0UL, 1);
  1030. THE_GREAT_EXPECTATIONS(1UL, 1);
  1031. THE_GREAT_EXPECTATIONS(12UL, 2);
  1032. THE_GREAT_EXPECTATIONS(123UL, 3);
  1033. THE_GREAT_EXPECTATIONS(1234UL, 4);
  1034. THE_GREAT_EXPECTATIONS(12345UL, 5);
  1035. THE_GREAT_EXPECTATIONS(123456UL, 6);
  1036. THE_GREAT_EXPECTATIONS(1234567UL, 7);
  1037. THE_GREAT_EXPECTATIONS(12345678UL, 8);
  1038. THE_GREAT_EXPECTATIONS(123456789UL, 9);
  1039. THE_GREAT_EXPECTATIONS(1234567890UL, 10);
  1040. THE_GREAT_EXPECTATIONS(12345678901UL, 11);
  1041. THE_GREAT_EXPECTATIONS(123456789012UL, 12);
  1042. THE_GREAT_EXPECTATIONS(1234567890123UL, 13);
  1043. THE_GREAT_EXPECTATIONS(12345678901234UL, 14);
  1044. THE_GREAT_EXPECTATIONS(123456789012345UL, 15);
  1045. THE_GREAT_EXPECTATIONS(1234567890123456UL, 16);
  1046. THE_GREAT_EXPECTATIONS(12345678901234567UL, 17);
  1047. THE_GREAT_EXPECTATIONS(123456789012345678UL, 18);
  1048. THE_GREAT_EXPECTATIONS(1234567890123456789UL, 19);
  1049. THE_GREAT_EXPECTATIONS(18446744073709551614UL, 20);
  1050. THE_GREAT_EXPECTATIONS(18446744073709551615UL, 20);
  1051. #undef THE_GREAT_EXPECTATIONS
  1052. }
  1053. TEST(Conv, allocate_size) {
  1054. std::string str1 = "meh meh meh";
  1055. std::string str2 = "zdech zdech zdech";
  1056. auto res1 = folly::to<std::string>(str1, ".", str2);
  1057. EXPECT_EQ(res1, str1 + "." + str2);
  1058. std::string res2; // empty
  1059. toAppendFit(str1, str2, 1, &res2);
  1060. EXPECT_EQ(res2, str1 + str2 + "1");
  1061. std::string res3;
  1062. toAppendDelimFit(",", str1, str2, &res3);
  1063. EXPECT_EQ(res3, str1 + "," + str2);
  1064. }
  1065. namespace my {
  1066. struct Dimensions {
  1067. int w, h;
  1068. std::tuple<const int&, const int&> tuple_view() const {
  1069. return tie(w, h);
  1070. }
  1071. bool operator==(const Dimensions& other) const {
  1072. return this->tuple_view() == other.tuple_view();
  1073. }
  1074. };
  1075. Expected<StringPiece, ConversionCode> parseTo(
  1076. folly::StringPiece in,
  1077. Dimensions& out) {
  1078. return parseTo(in, out.w)
  1079. .then([](StringPiece sp) { return sp.removePrefix("x"), sp; })
  1080. .then([&](StringPiece sp) { return parseTo(sp, out.h); });
  1081. }
  1082. template <class String>
  1083. void toAppend(const Dimensions& in, String* result) {
  1084. folly::toAppend(in.w, 'x', in.h, result);
  1085. }
  1086. size_t estimateSpaceNeeded(const Dimensions& in) {
  1087. return 2000 + folly::estimateSpaceNeeded(in.w) +
  1088. folly::estimateSpaceNeeded(in.h);
  1089. }
  1090. enum class SmallEnum {};
  1091. Expected<StringPiece, ConversionCode> parseTo(StringPiece in, SmallEnum& out) {
  1092. out = {};
  1093. if (in == "SmallEnum") {
  1094. return in.removePrefix(in), in;
  1095. } else {
  1096. return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR);
  1097. }
  1098. }
  1099. template <class String>
  1100. void toAppend(SmallEnum, String* result) {
  1101. folly::toAppend("SmallEnum", result);
  1102. }
  1103. } // namespace my
  1104. TEST(Conv, custom_kkproviders) {
  1105. my::Dimensions expected{7, 8};
  1106. EXPECT_EQ(expected, folly::to<my::Dimensions>("7x8"));
  1107. auto str = folly::to<std::string>(expected);
  1108. EXPECT_EQ("7x8", str);
  1109. // make sure above implementation of estimateSpaceNeeded() is used.
  1110. EXPECT_GT(str.capacity(), 2000);
  1111. EXPECT_LT(str.capacity(), 2500);
  1112. // toAppend with other arguments
  1113. toAppend("|", expected, &str);
  1114. EXPECT_EQ("7x8|7x8", str);
  1115. }
  1116. TEST(conv, custom_enumclass) {
  1117. EXPECT_EQ(my::SmallEnum{}, folly::to<my::SmallEnum>("SmallEnum"));
  1118. EXPECT_EQ(my::SmallEnum{}, folly::tryTo<my::SmallEnum>("SmallEnum").value());
  1119. auto str = to<string>(my::SmallEnum{});
  1120. toAppend("|", my::SmallEnum{}, &str);
  1121. EXPECT_EQ("SmallEnum|SmallEnum", str);
  1122. }
  1123. TEST(Conv, TryToThenWithVoid) {
  1124. auto x = tryTo<int>("42").then([](int) {});
  1125. EXPECT_TRUE(x.hasValue());
  1126. Unit u = x.value();
  1127. (void)u;
  1128. }
  1129. TEST(conv, TryIntToUnscopedEnumAndBack) {
  1130. enum UnscopedEnum {
  1131. First = 0,
  1132. Second = 1,
  1133. };
  1134. EXPECT_EQ(UnscopedEnum::Second, folly::tryTo<UnscopedEnum>(1).value());
  1135. EXPECT_EQ(1, folly::tryTo<int>(UnscopedEnum::Second).value());
  1136. }
  1137. TEST(conv, TryIntToScopedEnumAndBack) {
  1138. enum class ScopedEnum {
  1139. First = 0,
  1140. Second = 1,
  1141. };
  1142. EXPECT_EQ(ScopedEnum::Second, folly::tryTo<ScopedEnum>(1).value());
  1143. EXPECT_EQ(1, folly::tryTo<int>(ScopedEnum::Second).value());
  1144. }