base-test.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. // Formatting library for C++ - core tests
  2. //
  3. // Copyright (c) 2012 - present, Victor Zverovich
  4. // All rights reserved.
  5. //
  6. // For the license information refer to format.h.
  7. // clang-format off
  8. #include "test-assert.h"
  9. // clang-format on
  10. #include "fmt/base.h"
  11. #include <climits> // INT_MAX
  12. #include <cstring> // std::strlen
  13. #include <functional> // std::equal_to
  14. #include <iterator> // std::back_insert_iterator, std::distance
  15. #include <limits> // std::numeric_limits
  16. #include <string> // std::string
  17. #include <type_traits> // std::is_same
  18. #include "gmock/gmock.h"
  19. using fmt::string_view;
  20. using fmt::detail::buffer;
  21. using testing::_;
  22. using testing::Invoke;
  23. using testing::Return;
  24. #ifdef FMT_FORMAT_H_
  25. # error core-test includes format.h
  26. #endif
  27. fmt::appender copy(fmt::string_view s, fmt::appender out) {
  28. for (char c : s) *out++ = c;
  29. return out;
  30. }
  31. TEST(string_view_test, value_type) {
  32. static_assert(std::is_same<string_view::value_type, char>::value, "");
  33. }
  34. TEST(string_view_test, ctor) {
  35. EXPECT_STREQ("abc", fmt::string_view("abc").data());
  36. EXPECT_EQ(3u, fmt::string_view("abc").size());
  37. EXPECT_STREQ("defg", fmt::string_view(std::string("defg")).data());
  38. EXPECT_EQ(4u, fmt::string_view(std::string("defg")).size());
  39. }
  40. TEST(string_view_test, length) {
  41. // Test that string_view::size() returns string length, not buffer size.
  42. char str[100] = "some string";
  43. EXPECT_EQ(std::strlen(str), string_view(str).size());
  44. EXPECT_LT(std::strlen(str), sizeof(str));
  45. }
  46. // Check string_view's comparison operator.
  47. template <template <typename> class Op> void check_op() {
  48. const char* inputs[] = {"foo", "fop", "fo"};
  49. size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
  50. for (size_t i = 0; i < num_inputs; ++i) {
  51. for (size_t j = 0; j < num_inputs; ++j) {
  52. string_view lhs(inputs[i]), rhs(inputs[j]);
  53. EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs));
  54. }
  55. }
  56. }
  57. TEST(string_view_test, compare) {
  58. EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0);
  59. EXPECT_GT(string_view("fop").compare(string_view("foo")), 0);
  60. EXPECT_LT(string_view("foo").compare(string_view("fop")), 0);
  61. EXPECT_GT(string_view("foo").compare(string_view("fo")), 0);
  62. EXPECT_LT(string_view("fo").compare(string_view("foo")), 0);
  63. EXPECT_TRUE(string_view("foo").starts_with('f'));
  64. EXPECT_FALSE(string_view("foo").starts_with('o'));
  65. EXPECT_FALSE(string_view().starts_with('o'));
  66. EXPECT_TRUE(string_view("foo").starts_with("fo"));
  67. EXPECT_TRUE(string_view("foo").starts_with("foo"));
  68. EXPECT_FALSE(string_view("foo").starts_with("fooo"));
  69. EXPECT_FALSE(string_view().starts_with("fooo"));
  70. check_op<std::equal_to>();
  71. check_op<std::not_equal_to>();
  72. check_op<std::less>();
  73. check_op<std::less_equal>();
  74. check_op<std::greater>();
  75. check_op<std::greater_equal>();
  76. }
  77. TEST(base_test, is_locking) {
  78. EXPECT_FALSE(fmt::detail::is_locking<const char(&)[3]>());
  79. }
  80. TEST(base_test, is_output_iterator) {
  81. EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value));
  82. EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value));
  83. EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value));
  84. EXPECT_TRUE(
  85. (fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>,
  86. char>::value));
  87. EXPECT_TRUE(
  88. (fmt::detail::is_output_iterator<std::string::iterator, char>::value));
  89. EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator,
  90. char>::value));
  91. }
  92. TEST(base_test, is_back_insert_iterator) {
  93. EXPECT_TRUE(fmt::detail::is_back_insert_iterator<
  94. std::back_insert_iterator<std::string>>::value);
  95. EXPECT_FALSE(fmt::detail::is_back_insert_iterator<
  96. std::front_insert_iterator<std::string>>::value);
  97. }
  98. #if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
  99. TEST(buffer_test, noncopyable) {
  100. EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value);
  101. # if !FMT_MSC_VERSION
  102. // std::is_copy_assignable is broken in MSVC2013.
  103. EXPECT_FALSE(std::is_copy_assignable<buffer<char>>::value);
  104. # endif
  105. }
  106. TEST(buffer_test, nonmoveable) {
  107. EXPECT_FALSE(std::is_move_constructible<buffer<char>>::value);
  108. # if !FMT_MSC_VERSION
  109. // std::is_move_assignable is broken in MSVC2013.
  110. EXPECT_FALSE(std::is_move_assignable<buffer<char>>::value);
  111. # endif
  112. }
  113. #endif
  114. TEST(buffer_test, indestructible) {
  115. static_assert(!std::is_destructible<fmt::detail::buffer<int>>(),
  116. "buffer's destructor is protected");
  117. }
  118. template <typename T> struct mock_buffer final : buffer<T> {
  119. MOCK_METHOD(size_t, do_grow, (size_t));
  120. static void grow(buffer<T>& buf, size_t capacity) {
  121. auto& self = static_cast<mock_buffer&>(buf);
  122. self.set(buf.data(), self.do_grow(capacity));
  123. }
  124. mock_buffer(T* data = nullptr, size_t buf_capacity = 0) : buffer<T>(grow) {
  125. this->set(data, buf_capacity);
  126. ON_CALL(*this, do_grow(_)).WillByDefault(Invoke([](size_t capacity) {
  127. return capacity;
  128. }));
  129. }
  130. };
  131. TEST(buffer_test, ctor) {
  132. {
  133. mock_buffer<int> buffer;
  134. EXPECT_EQ(nullptr, buffer.data());
  135. EXPECT_EQ(static_cast<size_t>(0), buffer.size());
  136. EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
  137. }
  138. {
  139. int dummy;
  140. mock_buffer<int> buffer(&dummy);
  141. EXPECT_EQ(&dummy, &buffer[0]);
  142. EXPECT_EQ(static_cast<size_t>(0), buffer.size());
  143. EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
  144. }
  145. {
  146. int dummy;
  147. size_t capacity = std::numeric_limits<size_t>::max();
  148. mock_buffer<int> buffer(&dummy, capacity);
  149. EXPECT_EQ(&dummy, &buffer[0]);
  150. EXPECT_EQ(static_cast<size_t>(0), buffer.size());
  151. EXPECT_EQ(capacity, buffer.capacity());
  152. }
  153. }
  154. TEST(buffer_test, access) {
  155. char data[10];
  156. mock_buffer<char> buffer(data, sizeof(data));
  157. buffer[0] = 11;
  158. EXPECT_EQ(11, buffer[0]);
  159. buffer[3] = 42;
  160. EXPECT_EQ(42, *(&buffer[0] + 3));
  161. const fmt::detail::buffer<char>& const_buffer = buffer;
  162. EXPECT_EQ(42, const_buffer[3]);
  163. }
  164. TEST(buffer_test, try_resize) {
  165. char data[123];
  166. mock_buffer<char> buffer(data, sizeof(data));
  167. buffer[10] = 42;
  168. EXPECT_EQ(42, buffer[10]);
  169. buffer.try_resize(20);
  170. EXPECT_EQ(20u, buffer.size());
  171. EXPECT_EQ(123u, buffer.capacity());
  172. EXPECT_EQ(42, buffer[10]);
  173. buffer.try_resize(5);
  174. EXPECT_EQ(5u, buffer.size());
  175. EXPECT_EQ(123u, buffer.capacity());
  176. EXPECT_EQ(42, buffer[10]);
  177. // Check if try_resize calls grow.
  178. EXPECT_CALL(buffer, do_grow(124));
  179. buffer.try_resize(124);
  180. EXPECT_CALL(buffer, do_grow(200));
  181. buffer.try_resize(200);
  182. }
  183. TEST(buffer_test, try_resize_partial) {
  184. char data[10];
  185. mock_buffer<char> buffer(data, sizeof(data));
  186. EXPECT_CALL(buffer, do_grow(20)).WillOnce(Return(15));
  187. buffer.try_resize(20);
  188. EXPECT_EQ(buffer.capacity(), 15);
  189. EXPECT_EQ(buffer.size(), 15);
  190. }
  191. TEST(buffer_test, clear) {
  192. mock_buffer<char> buffer;
  193. EXPECT_CALL(buffer, do_grow(20));
  194. buffer.try_resize(20);
  195. buffer.try_resize(0);
  196. EXPECT_EQ(static_cast<size_t>(0), buffer.size());
  197. EXPECT_EQ(20u, buffer.capacity());
  198. }
  199. TEST(buffer_test, append) {
  200. char data[15];
  201. mock_buffer<char> buffer(data, 10);
  202. auto test = "test";
  203. buffer.append(test, test + 5);
  204. EXPECT_STREQ(test, &buffer[0]);
  205. EXPECT_EQ(5u, buffer.size());
  206. buffer.try_resize(10);
  207. EXPECT_CALL(buffer, do_grow(12));
  208. buffer.append(test, test + 2);
  209. EXPECT_EQ('t', buffer[10]);
  210. EXPECT_EQ('e', buffer[11]);
  211. EXPECT_EQ(12u, buffer.size());
  212. }
  213. TEST(buffer_test, append_partial) {
  214. char data[10];
  215. mock_buffer<char> buffer(data, sizeof(data));
  216. testing::InSequence seq;
  217. EXPECT_CALL(buffer, do_grow(15)).WillOnce(Return(10));
  218. EXPECT_CALL(buffer, do_grow(15)).WillOnce(Invoke([&buffer](size_t) {
  219. EXPECT_EQ(fmt::string_view(buffer.data(), buffer.size()), "0123456789");
  220. buffer.clear();
  221. return 10;
  222. }));
  223. auto test = "0123456789abcde";
  224. buffer.append(test, test + 15);
  225. }
  226. TEST(buffer_test, append_allocates_enough_storage) {
  227. char data[19];
  228. mock_buffer<char> buffer(data, 10);
  229. auto test = "abcdefgh";
  230. buffer.try_resize(10);
  231. EXPECT_CALL(buffer, do_grow(19));
  232. buffer.append(test, test + 9);
  233. }
  234. TEST(base_test, get_buffer) {
  235. mock_buffer<char> buffer;
  236. void* buffer_ptr = &buffer;
  237. auto&& appender_result = fmt::detail::get_buffer<char>(fmt::appender(buffer));
  238. EXPECT_EQ(&appender_result, buffer_ptr);
  239. auto&& back_inserter_result =
  240. fmt::detail::get_buffer<char>(std::back_inserter(buffer));
  241. EXPECT_EQ(&back_inserter_result, buffer_ptr);
  242. }
  243. struct test_struct {};
  244. FMT_BEGIN_NAMESPACE
  245. template <typename Char> struct formatter<test_struct, Char> {
  246. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  247. return ctx.begin();
  248. }
  249. auto format(test_struct, format_context& ctx) const -> decltype(ctx.out()) {
  250. return copy("test", ctx.out());
  251. }
  252. };
  253. FMT_END_NAMESPACE
  254. TEST(arg_test, format_args) {
  255. auto args = fmt::format_args();
  256. EXPECT_FALSE(args.get(1));
  257. }
  258. // Use a unique result type to make sure that there are no undesirable
  259. // conversions.
  260. struct test_result {};
  261. template <typename T> struct mock_visitor {
  262. template <typename U> struct result {
  263. using type = test_result;
  264. };
  265. mock_visitor() {
  266. ON_CALL(*this, visit(_)).WillByDefault(Return(test_result()));
  267. }
  268. MOCK_METHOD(test_result, visit, (T));
  269. MOCK_METHOD(void, unexpected, ());
  270. auto operator()(T value) -> test_result { return visit(value); }
  271. template <typename U> auto operator()(U) -> test_result {
  272. unexpected();
  273. return test_result();
  274. }
  275. };
  276. template <typename T> struct visit_type {
  277. using type = T;
  278. };
  279. #define VISIT_TYPE(type_, visit_type_) \
  280. template <> struct visit_type<type_> { \
  281. using type = visit_type_; \
  282. }
  283. VISIT_TYPE(signed char, int);
  284. VISIT_TYPE(unsigned char, unsigned);
  285. VISIT_TYPE(short, int);
  286. VISIT_TYPE(unsigned short, unsigned);
  287. #if LONG_MAX == INT_MAX
  288. VISIT_TYPE(long, int);
  289. VISIT_TYPE(unsigned long, unsigned);
  290. #else
  291. VISIT_TYPE(long, long long);
  292. VISIT_TYPE(unsigned long, unsigned long long);
  293. #endif
  294. #if FMT_BUILTIN_TYPES
  295. # define CHECK_ARG(expected, value) \
  296. { \
  297. testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \
  298. EXPECT_CALL(visitor, visit(expected)); \
  299. auto var = value; \
  300. fmt::basic_format_arg<fmt::format_context>(var).visit(visitor); \
  301. }
  302. #else
  303. # define CHECK_ARG(expected, value)
  304. #endif
  305. #define CHECK_ARG_SIMPLE(value) \
  306. { \
  307. using value_type = decltype(value); \
  308. typename visit_type<value_type>::type expected = value; \
  309. CHECK_ARG(expected, value) \
  310. }
  311. template <typename T> class numeric_arg_test : public testing::Test {};
  312. #if FMT_BUILTIN_TYPES
  313. using test_types =
  314. testing::Types<bool, signed char, unsigned char, short, unsigned short, int,
  315. unsigned, long, unsigned long, long long, unsigned long long,
  316. float, double, long double>;
  317. #else
  318. using test_types = testing::Types<int>;
  319. #endif
  320. TYPED_TEST_SUITE(numeric_arg_test, test_types);
  321. template <typename T, fmt::enable_if_t<std::is_integral<T>::value, int> = 0>
  322. auto test_value() -> T {
  323. return static_cast<T>(42);
  324. }
  325. template <typename T,
  326. fmt::enable_if_t<std::is_floating_point<T>::value, int> = 0>
  327. auto test_value() -> T {
  328. return static_cast<T>(4.2);
  329. }
  330. TYPED_TEST(numeric_arg_test, make_and_visit) {
  331. CHECK_ARG_SIMPLE(test_value<TypeParam>());
  332. CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::min());
  333. CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::max());
  334. }
  335. TEST(arg_test, char_arg) { CHECK_ARG('a', 'a'); }
  336. TEST(arg_test, string_arg) {
  337. char str_data[] = "test";
  338. char* str = str_data;
  339. const char* cstr = str;
  340. CHECK_ARG(cstr, str);
  341. auto sv = fmt::string_view(str);
  342. CHECK_ARG(sv, std::string(str));
  343. }
  344. TEST(arg_test, pointer_arg) {
  345. void* p = nullptr;
  346. const void* cp = nullptr;
  347. CHECK_ARG(cp, p);
  348. CHECK_ARG_SIMPLE(cp);
  349. }
  350. TEST(arg_test, volatile_pointer_arg) {
  351. const void* p = nullptr;
  352. volatile int* vip = nullptr;
  353. const volatile int* cvip = nullptr;
  354. CHECK_ARG(p, static_cast<volatile void*>(vip));
  355. CHECK_ARG(p, static_cast<const volatile void*>(cvip));
  356. }
  357. struct check_custom {
  358. auto operator()(fmt::basic_format_arg<fmt::format_context>::handle h) const
  359. -> test_result {
  360. struct test_buffer final : fmt::detail::buffer<char> {
  361. char data[10];
  362. test_buffer()
  363. : fmt::detail::buffer<char>([](buffer<char>&, size_t) {}, data, 0,
  364. 10) {}
  365. } buffer;
  366. auto parse_ctx = fmt::format_parse_context("");
  367. auto ctx = fmt::format_context(fmt::appender(buffer), fmt::format_args());
  368. h.format(parse_ctx, ctx);
  369. EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
  370. return test_result();
  371. }
  372. };
  373. TEST(arg_test, custom_arg) {
  374. auto test = test_struct();
  375. using visitor =
  376. mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>;
  377. auto&& v = testing::StrictMock<visitor>();
  378. EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom()));
  379. fmt::basic_format_arg<fmt::format_context>(test).visit(v);
  380. }
  381. TEST(arg_test, visit_invalid_arg) {
  382. auto&& visitor = testing::StrictMock<mock_visitor<fmt::monostate>>();
  383. EXPECT_CALL(visitor, visit(_));
  384. fmt::basic_format_arg<fmt::format_context>().visit(visitor);
  385. }
  386. #if FMT_USE_CONSTEXPR
  387. enum class arg_id_result { none, index, name };
  388. struct test_arg_id_handler {
  389. arg_id_result res = arg_id_result::none;
  390. int index = 0;
  391. string_view name;
  392. constexpr void on_index(int i) {
  393. res = arg_id_result::index;
  394. index = i;
  395. }
  396. constexpr void on_name(string_view n) {
  397. res = arg_id_result::name;
  398. name = n;
  399. }
  400. };
  401. template <size_t N>
  402. constexpr test_arg_id_handler parse_arg_id(const char (&s)[N]) {
  403. auto h = test_arg_id_handler();
  404. fmt::detail::parse_arg_id(s, s + N, h);
  405. return h;
  406. }
  407. TEST(base_test, constexpr_parse_arg_id) {
  408. static_assert(parse_arg_id("42:").res == arg_id_result::index, "");
  409. static_assert(parse_arg_id("42:").index == 42, "");
  410. static_assert(parse_arg_id("foo:").res == arg_id_result::name, "");
  411. static_assert(parse_arg_id("foo:").name.size() == 3, "");
  412. }
  413. template <size_t N> constexpr auto parse_test_specs(const char (&s)[N]) {
  414. auto ctx = fmt::detail::compile_parse_context<char>(fmt::string_view(s, N),
  415. 43, nullptr);
  416. auto specs = fmt::detail::dynamic_format_specs<>();
  417. fmt::detail::parse_format_specs(s, s + N - 1, specs, ctx,
  418. fmt::detail::type::float_type);
  419. return specs;
  420. }
  421. TEST(base_test, constexpr_parse_format_specs) {
  422. static_assert(parse_test_specs("<").align() == fmt::align::left, "");
  423. static_assert(parse_test_specs("*^").fill_unit<char>() == '*', "");
  424. static_assert(parse_test_specs("+").sign() == fmt::sign::plus, "");
  425. static_assert(parse_test_specs("-").sign() == fmt::sign::none, "");
  426. static_assert(parse_test_specs(" ").sign() == fmt::sign::space, "");
  427. static_assert(parse_test_specs("#").alt(), "");
  428. static_assert(parse_test_specs("0").align() == fmt::align::numeric, "");
  429. static_assert(parse_test_specs("L").localized(), "");
  430. static_assert(parse_test_specs("42").width == 42, "");
  431. static_assert(parse_test_specs("{42}").width_ref.index == 42, "");
  432. static_assert(parse_test_specs(".42").precision == 42, "");
  433. static_assert(parse_test_specs(".{42}").precision_ref.index == 42, "");
  434. static_assert(parse_test_specs("f").type() == fmt::presentation_type::fixed,
  435. "");
  436. }
  437. struct test_format_string_handler {
  438. constexpr void on_text(const char*, const char*) {}
  439. constexpr auto on_arg_id() -> int { return 0; }
  440. template <typename T> constexpr auto on_arg_id(T) -> int { return 0; }
  441. constexpr void on_replacement_field(int, const char*) {}
  442. constexpr auto on_format_specs(int, const char* begin, const char*) -> const
  443. char* {
  444. return begin;
  445. }
  446. constexpr void on_error(const char*) { error = true; }
  447. bool error = false;
  448. };
  449. template <size_t N> constexpr bool parse_string(const char (&s)[N]) {
  450. auto h = test_format_string_handler();
  451. fmt::detail::parse_format_string(fmt::string_view(s, N - 1), h);
  452. return !h.error;
  453. }
  454. TEST(base_test, constexpr_parse_format_string) {
  455. static_assert(parse_string("foo"), "");
  456. static_assert(!parse_string("}"), "");
  457. static_assert(parse_string("{}"), "");
  458. static_assert(parse_string("{42}"), "");
  459. static_assert(parse_string("{foo}"), "");
  460. static_assert(parse_string("{:}"), "");
  461. }
  462. #endif // FMT_USE_CONSTEXPR
  463. struct enabled_formatter {};
  464. struct enabled_ptr_formatter {};
  465. struct disabled_formatter {};
  466. struct disabled_formatter_convertible {
  467. operator int() const { return 42; }
  468. };
  469. FMT_BEGIN_NAMESPACE
  470. template <> struct formatter<enabled_formatter> {
  471. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  472. return ctx.begin();
  473. }
  474. auto format(enabled_formatter, format_context& ctx) const
  475. -> decltype(ctx.out()) {
  476. return ctx.out();
  477. }
  478. };
  479. template <> struct formatter<enabled_ptr_formatter*> {
  480. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  481. return ctx.begin();
  482. }
  483. auto format(enabled_ptr_formatter*, format_context& ctx) const
  484. -> decltype(ctx.out()) {
  485. return ctx.out();
  486. }
  487. };
  488. FMT_END_NAMESPACE
  489. struct const_formattable {};
  490. struct nonconst_formattable {};
  491. FMT_BEGIN_NAMESPACE
  492. template <> struct formatter<const_formattable> {
  493. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  494. return ctx.begin();
  495. }
  496. auto format(const const_formattable&, format_context& ctx) const
  497. -> decltype(ctx.out()) {
  498. return copy("test", ctx.out());
  499. }
  500. };
  501. template <> struct formatter<nonconst_formattable> {
  502. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  503. return ctx.begin();
  504. }
  505. auto format(nonconst_formattable&, format_context& ctx) const
  506. -> decltype(ctx.out()) {
  507. return copy("test", ctx.out());
  508. }
  509. };
  510. FMT_END_NAMESPACE
  511. struct convertible_to_pointer {
  512. operator const int*() const { return nullptr; }
  513. };
  514. struct convertible_to_pointer_formattable {
  515. operator const int*() const { return nullptr; }
  516. };
  517. FMT_BEGIN_NAMESPACE
  518. template <> struct formatter<convertible_to_pointer_formattable> {
  519. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  520. return ctx.begin();
  521. }
  522. auto format(convertible_to_pointer_formattable, format_context& ctx) const
  523. -> decltype(ctx.out()) {
  524. return copy("test", ctx.out());
  525. }
  526. };
  527. FMT_END_NAMESPACE
  528. enum class unformattable_scoped_enum {};
  529. TEST(base_test, is_formattable) {
  530. EXPECT_FALSE(fmt::is_formattable<void>::value);
  531. EXPECT_FALSE(fmt::is_formattable<wchar_t>::value);
  532. #ifdef __cpp_char8_t
  533. EXPECT_FALSE(fmt::is_formattable<char8_t>::value);
  534. #endif
  535. EXPECT_FALSE(fmt::is_formattable<char16_t>::value);
  536. EXPECT_FALSE(fmt::is_formattable<char32_t>::value);
  537. EXPECT_FALSE(fmt::is_formattable<signed char*>::value);
  538. EXPECT_FALSE(fmt::is_formattable<unsigned char*>::value);
  539. EXPECT_FALSE(fmt::is_formattable<const signed char*>::value);
  540. EXPECT_FALSE(fmt::is_formattable<const unsigned char*>::value);
  541. EXPECT_FALSE(fmt::is_formattable<const wchar_t*>::value);
  542. EXPECT_FALSE(fmt::is_formattable<const wchar_t[3]>::value);
  543. EXPECT_FALSE(fmt::is_formattable<fmt::basic_string_view<wchar_t>>::value);
  544. EXPECT_FALSE(fmt::is_formattable<enabled_ptr_formatter*>::value);
  545. EXPECT_FALSE(fmt::is_formattable<disabled_formatter>::value);
  546. EXPECT_FALSE(fmt::is_formattable<disabled_formatter_convertible>::value);
  547. EXPECT_TRUE(fmt::is_formattable<enabled_formatter>::value);
  548. EXPECT_TRUE(fmt::is_formattable<const_formattable&>::value);
  549. EXPECT_TRUE(fmt::is_formattable<const const_formattable&>::value);
  550. EXPECT_TRUE(fmt::is_formattable<nonconst_formattable&>::value);
  551. EXPECT_FALSE(fmt::is_formattable<const nonconst_formattable&>::value);
  552. EXPECT_FALSE(fmt::is_formattable<convertible_to_pointer>::value);
  553. const auto f = convertible_to_pointer_formattable();
  554. auto str = std::string();
  555. fmt::format_to(std::back_inserter(str), "{}", f);
  556. EXPECT_EQ(str, "test");
  557. EXPECT_FALSE(fmt::is_formattable<void (*)()>::value);
  558. struct s;
  559. EXPECT_FALSE(fmt::is_formattable<int(s::*)>::value);
  560. EXPECT_FALSE(fmt::is_formattable<int (s::*)()>::value);
  561. EXPECT_FALSE(fmt::is_formattable<unformattable_scoped_enum>::value);
  562. EXPECT_FALSE(fmt::is_formattable<unformattable_scoped_enum>::value);
  563. }
  564. #ifdef __cpp_concepts
  565. TEST(base_test, formattable_concept) {
  566. static_assert(fmt::formattable<char>);
  567. static_assert(fmt::formattable<char&>);
  568. static_assert(fmt::formattable<char&&>);
  569. static_assert(fmt::formattable<const char>);
  570. static_assert(fmt::formattable<const char&>);
  571. static_assert(fmt::formattable<const char&&>);
  572. static_assert(fmt::formattable<int>);
  573. static_assert(!fmt::formattable<wchar_t>);
  574. }
  575. #endif
  576. TEST(base_test, format_to) {
  577. auto s = std::string();
  578. fmt::format_to(std::back_inserter(s), "{}", 42);
  579. EXPECT_EQ(s, "42");
  580. }
  581. TEST(base_test, format_to_array) {
  582. char buffer[4];
  583. auto result = fmt::format_to(buffer, "{}", 12345);
  584. EXPECT_EQ(4, std::distance(&buffer[0], result.out));
  585. EXPECT_TRUE(result.truncated);
  586. EXPECT_EQ(buffer + 4, result.out);
  587. EXPECT_EQ("1234", fmt::string_view(buffer, 4));
  588. char* out = nullptr;
  589. EXPECT_THROW(out = result, std::runtime_error);
  590. (void)out;
  591. result = fmt::format_to(buffer, "{:s}", "foobar");
  592. EXPECT_EQ(4, std::distance(&buffer[0], result.out));
  593. EXPECT_TRUE(result.truncated);
  594. EXPECT_EQ(buffer + 4, result.out);
  595. EXPECT_EQ("foob", fmt::string_view(buffer, 4));
  596. buffer[0] = 'x';
  597. buffer[1] = 'x';
  598. buffer[2] = 'x';
  599. buffer[3] = 'x';
  600. result = fmt::format_to(buffer, "{}", 'A');
  601. EXPECT_EQ(1, std::distance(&buffer[0], result.out));
  602. EXPECT_FALSE(result.truncated);
  603. EXPECT_EQ(buffer + 1, result.out);
  604. EXPECT_EQ("Axxx", fmt::string_view(buffer, 4));
  605. result = fmt::format_to(buffer, "{}{} ", 'B', 'C');
  606. EXPECT_EQ(3, std::distance(&buffer[0], result.out));
  607. EXPECT_FALSE(result.truncated);
  608. EXPECT_EQ(buffer + 3, result.out);
  609. EXPECT_EQ("BC x", fmt::string_view(buffer, 4));
  610. result = fmt::format_to(buffer, "{}", "ABCDE");
  611. EXPECT_EQ(4, std::distance(&buffer[0], result.out));
  612. EXPECT_TRUE(result.truncated);
  613. EXPECT_EQ("ABCD", fmt::string_view(buffer, 4));
  614. result = fmt::format_to(buffer, "{}", std::string(1000, '*').c_str());
  615. EXPECT_EQ(4, std::distance(&buffer[0], result.out));
  616. EXPECT_TRUE(result.truncated);
  617. EXPECT_EQ("****", fmt::string_view(buffer, 4));
  618. }
  619. // Test that check is not found by ADL.
  620. template <typename T> void check(T);
  621. TEST(base_test, adl_check) {
  622. auto s = std::string();
  623. fmt::format_to(std::back_inserter(s), "{}", test_struct());
  624. EXPECT_EQ(s, "test");
  625. }
  626. struct implicitly_convertible_to_string_view {
  627. operator fmt::string_view() const { return "foo"; }
  628. };
  629. TEST(base_test, no_implicit_conversion_to_string_view) {
  630. EXPECT_FALSE(
  631. fmt::is_formattable<implicitly_convertible_to_string_view>::value);
  632. }
  633. struct explicitly_convertible_to_string_view {
  634. explicit operator fmt::string_view() const { return "foo"; }
  635. };
  636. TEST(base_test, format_explicitly_convertible_to_string_view) {
  637. // Types explicitly convertible to string_view are not formattable by
  638. // default because it may introduce ODR violations.
  639. static_assert(
  640. !fmt::is_formattable<explicitly_convertible_to_string_view>::value, "");
  641. }
  642. #if FMT_CPLUSPLUS >= 201703L
  643. struct implicitly_convertible_to_std_string_view {
  644. operator std::string_view() const { return "foo"; }
  645. };
  646. TEST(base_test, no_implicit_conversion_to_std_string_view) {
  647. EXPECT_FALSE(
  648. fmt::is_formattable<implicitly_convertible_to_std_string_view>::value);
  649. }
  650. struct explicitly_convertible_to_std_string_view {
  651. explicit operator std::string_view() const { return "foo"; }
  652. };
  653. TEST(base_test, format_explicitly_convertible_to_std_string_view) {
  654. // Types explicitly convertible to string_view are not formattable by
  655. // default because it may introduce ODR violations.
  656. static_assert(
  657. !fmt::is_formattable<explicitly_convertible_to_std_string_view>::value,
  658. "");
  659. }
  660. #endif // FMT_CPLUSPLUS >= 201703L
  661. TEST(base_test, has_formatter) {
  662. EXPECT_TRUE((fmt::detail::has_formatter<const const_formattable, char>()));
  663. EXPECT_FALSE(
  664. (fmt::detail::has_formatter<const nonconst_formattable, char>()));
  665. }
  666. TEST(base_test, format_nonconst) {
  667. auto s = std::string();
  668. fmt::format_to(std::back_inserter(s), "{}", nonconst_formattable());
  669. EXPECT_EQ(s, "test");
  670. }
  671. TEST(base_test, throw_in_buffer_dtor) {
  672. enum { buffer_size = 256 };
  673. struct throwing_iterator {
  674. int& count;
  675. auto operator=(char) -> throwing_iterator& {
  676. if (++count > buffer_size) throw std::exception();
  677. return *this;
  678. }
  679. auto operator*() -> throwing_iterator& { return *this; }
  680. auto operator++() -> throwing_iterator& { return *this; }
  681. auto operator++(int) -> throwing_iterator { return *this; }
  682. };
  683. try {
  684. int count = 0;
  685. fmt::format_to(throwing_iterator{count}, fmt::runtime("{:{}}{"), "",
  686. buffer_size + 1);
  687. } catch (const std::exception&) {
  688. }
  689. }
  690. struct its_a_trap {
  691. template <typename T> operator T() const {
  692. auto v = T();
  693. v.x = 42;
  694. return v;
  695. }
  696. };
  697. FMT_BEGIN_NAMESPACE
  698. template <> struct formatter<its_a_trap> {
  699. FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
  700. return ctx.begin();
  701. }
  702. auto format(its_a_trap, format_context& ctx) const
  703. -> decltype(ctx.out()) const {
  704. auto out = ctx.out();
  705. *out++ = 'x';
  706. return out;
  707. }
  708. };
  709. FMT_END_NAMESPACE
  710. TEST(base_test, trappy_conversion) {
  711. auto s = std::string();
  712. fmt::format_to(std::back_inserter(s), "{}", its_a_trap());
  713. EXPECT_EQ(s, "x");
  714. }
  715. struct custom_container {
  716. char data;
  717. using value_type = char;
  718. size_t size() const { return 0; }
  719. void resize(size_t) {}
  720. void push_back(char) {}
  721. char& operator[](size_t) { return data; }
  722. };
  723. FMT_BEGIN_NAMESPACE
  724. template <> struct is_contiguous<custom_container> : std::true_type {};
  725. FMT_END_NAMESPACE
  726. TEST(base_test, format_to_custom_container) {
  727. auto c = custom_container();
  728. fmt::format_to(std::back_inserter(c), "");
  729. }
  730. struct nondeterministic_format_string {
  731. mutable int i = 0;
  732. FMT_CONSTEXPR operator string_view() const {
  733. return string_view("{}", i++ != 0 ? 2 : 0);
  734. }
  735. };
  736. TEST(base_test, no_repeated_format_string_conversions) {
  737. #if !FMT_GCC_VERSION
  738. char buf[10];
  739. fmt::format_to(buf, nondeterministic_format_string());
  740. #endif
  741. }
  742. TEST(base_test, format_context_accessors) {
  743. class copier {
  744. static fmt::format_context copy(fmt::appender app,
  745. const fmt::format_context& ctx) {
  746. return fmt::format_context(std::move(app), ctx.args(), ctx.locale());
  747. }
  748. };
  749. }