| 
									
										
										
										
											2018-03-04 09:16:51 -08:00
										 |  |  | // Formatting library for C++ - std::ostream support tests
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Copyright (c) 2012 - present, Victor Zverovich
 | 
					
						
							|  |  |  | // All rights reserved.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // For the license information refer to format.h.
 | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 17:02:31 -07:00
										 |  |  | #include "fmt/format.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  | using fmt::runtime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 17:02:31 -07:00
										 |  |  | struct test {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Test that there is no issues with specializations when fmt/ostream.h is
 | 
					
						
							|  |  |  | // included after fmt/format.h.
 | 
					
						
							|  |  |  | namespace fmt { | 
					
						
							|  |  |  | template <> struct formatter<test> : formatter<int> { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  |   auto format(const test&, format_context& ctx) -> decltype(ctx.out()) { | 
					
						
							| 
									
										
										
										
											2019-04-19 17:02:31 -07:00
										 |  |  |     return formatter<int>::format(42, ctx); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | }  // namespace fmt
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2020-05-06 17:15:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "fmt/ostream.h"
 | 
					
						
							| 
									
										
										
										
											2020-11-21 16:31:22 -08:00
										 |  |  | #include "fmt/ranges.h"
 | 
					
						
							| 
									
										
										
										
											2021-04-29 01:59:43 +03:00
										 |  |  | #include "gmock/gmock.h"
 | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | #include "gtest-extra.h"
 | 
					
						
							|  |  |  | #include "util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  | std::ostream& operator<<(std::ostream& os, const date& d) { | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   os << d.year() << '-' << d.month() << '-' << d.day(); | 
					
						
							|  |  |  |   return os; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  | std::wostream& operator<<(std::wostream& os, const date& d) { | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   os << d.year() << L'-' << d.month() << L'-' << d.day(); | 
					
						
							|  |  |  |   return os; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-06 19:45:14 +09:00
										 |  |  | // Make sure that overloaded comma operators do no harm to is_streamable.
 | 
					
						
							|  |  |  | struct type_with_comma_op {}; | 
					
						
							|  |  |  | template <typename T> void operator,(type_with_comma_op, const T&); | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  | template <typename T> type_with_comma_op operator<<(T&, const date&); | 
					
						
							| 
									
										
										
										
											2019-02-06 19:45:14 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 07:08:04 -07:00
										 |  |  | enum streamable_enum {}; | 
					
						
							| 
									
										
										
										
											2021-06-05 20:19:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | std::ostream& operator<<(std::ostream& os, streamable_enum) { | 
					
						
							| 
									
										
										
										
											2019-06-07 07:08:04 -07:00
										 |  |  |   return os << "streamable_enum"; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 07:08:04 -07:00
										 |  |  | enum unstreamable_enum {}; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, enum) { | 
					
						
							| 
									
										
										
										
											2019-06-07 07:08:04 -07:00
										 |  |  |   EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum())); | 
					
						
							|  |  |  |   EXPECT_EQ("0", fmt::format("{}", unstreamable_enum())); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format) { | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   EXPECT_EQ("a string", fmt::format("{0}", test_string("a string"))); | 
					
						
							|  |  |  |   EXPECT_EQ("The date is 2012-12-9", | 
					
						
							|  |  |  |             fmt::format("The date is {0}", date(2012, 12, 9))); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format_specs) { | 
					
						
							|  |  |  |   using fmt::format_error; | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   EXPECT_EQ("def  ", fmt::format("{0:<5}", test_string("def"))); | 
					
						
							|  |  |  |   EXPECT_EQ("  def", fmt::format("{0:>5}", test_string("def"))); | 
					
						
							|  |  |  |   EXPECT_EQ(" def ", fmt::format("{0:^5}", test_string("def"))); | 
					
						
							|  |  |  |   EXPECT_EQ("def**", fmt::format("{0:*<5}", test_string("def"))); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  |   EXPECT_THROW_MSG(fmt::format(runtime("{0:+}"), test_string()), format_error, | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |                    "format specifier requires numeric argument"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  |   EXPECT_THROW_MSG(fmt::format(runtime("{0:-}"), test_string()), format_error, | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |                    "format specifier requires numeric argument"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  |   EXPECT_THROW_MSG(fmt::format(runtime("{0: }"), test_string()), format_error, | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |                    "format specifier requires numeric argument"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  |   EXPECT_THROW_MSG(fmt::format(runtime("{0:#}"), test_string()), format_error, | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |                    "format specifier requires numeric argument"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:38:52 -07:00
										 |  |  |   EXPECT_THROW_MSG(fmt::format(runtime("{0:05}"), test_string()), format_error, | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |                    "format specifier requires numeric argument"); | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   EXPECT_EQ("test         ", fmt::format("{0:13}", test_string("test"))); | 
					
						
							|  |  |  |   EXPECT_EQ("test         ", fmt::format("{0:{1}}", test_string("test"), 13)); | 
					
						
							|  |  |  |   EXPECT_EQ("te", fmt::format("{0:.2}", test_string("test"))); | 
					
						
							|  |  |  |   EXPECT_EQ("te", fmt::format("{0:.{1}}", test_string("test"), 2)); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | struct empty_test {}; | 
					
						
							|  |  |  | std::ostream& operator<<(std::ostream& os, empty_test) { return os << ""; } | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, empty_custom_output) { | 
					
						
							|  |  |  |   EXPECT_EQ("", fmt::format("{}", empty_test())); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, print) { | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   std::ostringstream os; | 
					
						
							|  |  |  |   fmt::print(os, "Don't {}!", "panic"); | 
					
						
							|  |  |  |   EXPECT_EQ("Don't panic!", os.str()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, write_to_ostream) { | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   std::ostringstream os; | 
					
						
							| 
									
										
										
										
											2017-02-18 09:13:12 -08:00
										 |  |  |   fmt::memory_buffer buffer; | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |   const char* foo = "foo"; | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |   buffer.append(foo, foo + std::strlen(foo)); | 
					
						
							| 
									
										
										
										
											2020-06-08 07:23:18 -07:00
										 |  |  |   fmt::detail::write_buffer(os, buffer); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   EXPECT_EQ("foo", os.str()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, write_to_ostream_max_size) { | 
					
						
							|  |  |  |   auto max_size = fmt::detail::max_value<size_t>(); | 
					
						
							|  |  |  |   auto max_streamsize = fmt::detail::max_value<std::streamsize>(); | 
					
						
							| 
									
										
										
										
											2020-05-10 07:25:42 -07:00
										 |  |  |   if (max_size <= fmt::detail::to_unsigned(max_streamsize)) return; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-16 02:41:56 +02:00
										 |  |  |   struct test_buffer final : fmt::detail::buffer<char> { | 
					
						
							| 
									
										
										
										
											2020-07-10 07:50:37 -07:00
										 |  |  |     explicit test_buffer(size_t size) | 
					
						
							| 
									
										
										
										
											2020-10-27 21:55:44 -06:00
										 |  |  |         : fmt::detail::buffer<char>(nullptr, size, size) {} | 
					
						
							| 
									
										
										
										
											2020-05-07 15:59:46 -07:00
										 |  |  |     void grow(size_t) {} | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |   } buffer(max_size); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:25:03 -08:00
										 |  |  |   struct mock_streambuf : std::streambuf { | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  |     MOCK_METHOD2(xsputn, std::streamsize(const void* s, std::streamsize n)); | 
					
						
							|  |  |  |     std::streamsize xsputn(const char* s, std::streamsize n) { | 
					
						
							|  |  |  |       const void* v = s; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |       return xsputn(v, n); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |   } streambuf; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 12:25:03 -08:00
										 |  |  |   struct test_ostream : std::ostream { | 
					
						
							| 
									
										
										
										
											2020-10-27 21:55:44 -06:00
										 |  |  |     explicit test_ostream(mock_streambuf& output_buffer) | 
					
						
							|  |  |  |         : std::ostream(&output_buffer) {} | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |   } os(streambuf); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   testing::InSequence sequence; | 
					
						
							| 
									
										
										
										
											2019-05-30 07:01:31 -07:00
										 |  |  |   const char* data = nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  |   using ustreamsize = std::make_unsigned<std::streamsize>::type; | 
					
						
							| 
									
										
										
										
											2018-12-05 07:11:06 -08:00
										 |  |  |   ustreamsize size = max_size; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   do { | 
					
						
							| 
									
										
										
										
											2020-05-10 07:25:42 -07:00
										 |  |  |     auto n = std::min(size, fmt::detail::to_unsigned(max_streamsize)); | 
					
						
							| 
									
										
										
										
											2017-02-14 16:29:47 -05:00
										 |  |  |     EXPECT_CALL(streambuf, xsputn(data, static_cast<std::streamsize>(n))) | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |         .WillOnce(testing::Return(max_streamsize)); | 
					
						
							|  |  |  |     data += n; | 
					
						
							| 
									
										
										
										
											2019-02-02 20:24:07 -05:00
										 |  |  |     size -= n; | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  |   } while (size != 0); | 
					
						
							| 
									
										
										
										
											2020-06-08 07:23:18 -07:00
										 |  |  |   fmt::detail::write_buffer(os, buffer); | 
					
						
							| 
									
										
										
										
											2016-05-06 07:37:20 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-05-21 20:21:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, join) { | 
					
						
							| 
									
										
										
										
											2018-05-21 20:21:06 -07:00
										 |  |  |   int v[3] = {1, 2, 3}; | 
					
						
							|  |  |  |   EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-06-10 19:05:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, join_fallback_formatter) { | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   auto strs = std::vector<test_string>{test_string("foo"), test_string("bar")}; | 
					
						
							| 
									
										
										
										
											2020-12-08 17:56:53 +01:00
										 |  |  |   EXPECT_EQ("foo, bar", fmt::format("{}", fmt::join(strs, ", "))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-04 13:17:03 -07:00
										 |  |  | #if FMT_USE_CONSTEXPR
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, constexpr_string) { | 
					
						
							| 
									
										
										
										
											2019-11-19 10:20:31 -08:00
										 |  |  |   EXPECT_EQ("42", format(FMT_STRING("{}"), std::string("42"))); | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   EXPECT_EQ("a string", format(FMT_STRING("{0}"), test_string("a string"))); | 
					
						
							| 
									
										
										
										
											2018-06-10 19:05:27 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-07-04 13:17:03 -07:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace fmt_test { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | struct abc {}; | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | template <typename Output> Output& operator<<(Output& out, abc) { | 
					
						
							|  |  |  |   return out << "abc"; | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-01-12 18:27:38 -08:00
										 |  |  | }  // namespace fmt_test
 | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | template <typename T> struct test_template {}; | 
					
						
							| 
									
										
										
										
											2019-01-21 07:11:49 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | std::ostream& operator<<(std::ostream& os, test_template<T>) { | 
					
						
							| 
									
										
										
										
											2019-01-21 07:11:49 -08:00
										 |  |  |   return os << 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace fmt { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | template <typename T> struct formatter<test_template<T>> : formatter<int> { | 
					
						
							|  |  |  |   auto format(test_template<T>, format_context& ctx) -> decltype(ctx.out()) { | 
					
						
							| 
									
										
										
										
											2019-01-21 07:11:49 -08:00
										 |  |  |     return formatter<int>::format(2, ctx); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-01-31 23:47:57 -05:00
										 |  |  | }  // namespace fmt
 | 
					
						
							| 
									
										
										
										
											2019-01-21 07:11:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, template) { | 
					
						
							|  |  |  |   EXPECT_EQ("2", fmt::format("{}", test_template<int>())); | 
					
						
							| 
									
										
										
										
											2019-01-21 07:11:49 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format_to_n) { | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  |   char buffer[4]; | 
					
						
							|  |  |  |   buffer[3] = 'x'; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  |   auto result = fmt::format_to_n(buffer, 3, "{}", fmt_test::abc()); | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  |   EXPECT_EQ(3u, result.size); | 
					
						
							|  |  |  |   EXPECT_EQ(buffer + 3, result.out); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  |   EXPECT_EQ("abcx", fmt::string_view(buffer, 4)); | 
					
						
							|  |  |  |   result = fmt::format_to_n(buffer, 3, "x{}y", fmt_test::abc()); | 
					
						
							| 
									
										
										
										
											2018-07-09 15:49:44 +02:00
										 |  |  |   EXPECT_EQ(5u, result.size); | 
					
						
							|  |  |  |   EXPECT_EQ(buffer + 3, result.out); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  |   EXPECT_EQ("xabx", fmt::string_view(buffer, 4)); | 
					
						
							| 
									
										
										
										
											2018-08-11 09:13:54 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-09-23 11:45:07 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-25 16:46:33 -08:00
										 |  |  | template <typename T> struct convertible { | 
					
						
							| 
									
										
										
										
											2019-09-23 11:45:07 -07:00
										 |  |  |   T value; | 
					
						
							|  |  |  |   explicit convertible(const T& val) : value(val) {} | 
					
						
							|  |  |  |   operator T() const { return value; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, disable_builtin_ostream_operators) { | 
					
						
							| 
									
										
										
										
											2019-09-23 20:34:08 -07:00
										 |  |  |   EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42))); | 
					
						
							| 
									
										
										
										
											2019-09-23 11:45:07 -07:00
										 |  |  |   EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo"))); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-11-25 16:46:33 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct explicitly_convertible_to_string_like { | 
					
						
							|  |  |  |   template <typename String, | 
					
						
							|  |  |  |             typename = typename std::enable_if<std::is_constructible< | 
					
						
							| 
									
										
										
										
											2020-05-07 15:59:46 -07:00
										 |  |  |                 String, const char*, size_t>::value>::type> | 
					
						
							| 
									
										
										
										
											2019-11-25 16:46:33 -08:00
										 |  |  |   explicit operator String() const { | 
					
						
							|  |  |  |     return String("foo", 3u); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::ostream& operator<<(std::ostream& os, | 
					
						
							|  |  |  |                          explicitly_convertible_to_string_like) { | 
					
						
							|  |  |  |   return os << "bar"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format_explicitly_convertible_to_string_like) { | 
					
						
							| 
									
										
										
										
											2020-02-07 18:47:48 -08:00
										 |  |  |   EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); | 
					
						
							| 
									
										
										
										
											2019-11-27 11:06:40 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-12-09 13:25:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef FMT_USE_STRING_VIEW
 | 
					
						
							|  |  |  | struct explicitly_convertible_to_std_string_view { | 
					
						
							| 
									
										
										
										
											2020-05-10 07:25:42 -07:00
										 |  |  |   explicit operator fmt::detail::std_string_view<char>() const { | 
					
						
							| 
									
										
										
										
											2019-12-09 13:25:08 -08:00
										 |  |  |     return {"foo", 3u}; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::ostream& operator<<(std::ostream& os, | 
					
						
							|  |  |  |                          explicitly_convertible_to_std_string_view) { | 
					
						
							|  |  |  |   return os << "bar"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format_explicitly_convertible_to_std_string_view) { | 
					
						
							| 
									
										
										
										
											2020-02-07 18:47:48 -08:00
										 |  |  |   EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); | 
					
						
							| 
									
										
										
										
											2019-12-09 13:25:08 -08:00
										 |  |  | } | 
					
						
							|  |  |  | #endif  // FMT_USE_STRING_VIEW
 | 
					
						
							| 
									
										
										
										
											2020-05-06 17:15:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-12 08:26:35 -07:00
										 |  |  | struct streamable_and_convertible_to_bool { | 
					
						
							|  |  |  |   operator bool() const { return true; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::ostream& operator<<(std::ostream& os, streamable_and_convertible_to_bool) { | 
					
						
							|  |  |  |   return os << "foo"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, format_convertible_to_bool) { | 
					
						
							| 
									
										
										
										
											2020-07-12 08:26:35 -07:00
										 |  |  |   EXPECT_EQ("foo", fmt::format("{}", streamable_and_convertible_to_bool())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-06 17:15:46 -07:00
										 |  |  | struct copyfmt_test {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::ostream& operator<<(std::ostream& os, copyfmt_test) { | 
					
						
							|  |  |  |   std::ios ios(nullptr); | 
					
						
							|  |  |  |   ios.copyfmt(os); | 
					
						
							|  |  |  |   return os << "foo"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, copyfmt) { | 
					
						
							| 
									
										
										
										
											2020-05-06 17:15:46 -07:00
										 |  |  |   EXPECT_EQ("foo", fmt::format("{}", copyfmt_test())); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-20 14:59:57 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, to_string) { | 
					
						
							|  |  |  |   EXPECT_EQ("abc", fmt::to_string(fmt_test::abc())); | 
					
						
							| 
									
										
										
										
											2020-08-20 16:41:09 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-11-21 16:31:22 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:54:20 -07:00
										 |  |  | TEST(ostream_test, range) { | 
					
						
							| 
									
										
										
										
											2021-05-05 17:43:06 -07:00
										 |  |  |   auto strs = std::vector<test_string>{test_string("foo"), test_string("bar")}; | 
					
						
							| 
									
										
										
										
											2021-05-04 21:04:21 -07:00
										 |  |  |   EXPECT_EQ("[foo, bar]", fmt::format("{}", strs)); | 
					
						
							| 
									
										
										
										
											2020-11-21 16:52:40 -08:00
										 |  |  | } |