From c929684e336ca7657a1dd787efaa1bea12c3286f Mon Sep 17 00:00:00 2001 From: Christopher Di Bella Date: Sat, 1 Jun 2019 14:57:06 +0100 Subject: [PATCH 01/16] inlines count_code_points(basic_string_view) was defined in fmt/format-inl.h, and only declared in fmt/format.h, but not defined in src/format.cc. This commit moves the overload to fmt/format.h and inlines it. --- include/fmt/format-inl.h | 9 --------- include/fmt/format.h | 9 ++++++++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 8f9d58f7b40e..24c6c77bcdcd 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -200,15 +200,6 @@ void report_error(FormatFunc func, int error_code, } } // namespace -FMT_FUNC size_t internal::count_code_points(basic_string_view s) { - const char8_t* data = s.data(); - size_t num_code_points = 0; - for (size_t i = 0, size = s.size(); i != size; ++i) { - if ((data[i] & 0xc0) != 0x80) ++num_code_points; - } - return num_code_points; -} - #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) namespace internal { diff --git a/include/fmt/format.h b/include/fmt/format.h index 72be49bc2072..7e4cf3be9044 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -766,7 +766,14 @@ inline size_t count_code_points(basic_string_view s) { } // Counts the number of code points in a UTF-8 string. -FMT_API size_t count_code_points(basic_string_view s); +inline size_t count_code_points(basic_string_view s) { + const char8_t* data = s.data(); + size_t num_code_points = 0; + for (size_t i = 0, size = s.size(); i != size; ++i) { + if ((data[i] & 0xc0) != 0x80) ++num_code_points; + } + return num_code_points; +} inline char8_t to_char8_t(char c) { return static_cast(c); } From c56b17029afb2c1f163f295f3333f9a07bb3dbe6 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 06:47:48 -0700 Subject: [PATCH 02/16] Add msvc2019 to CI --- support/appveyor-build.py | 19 +++++++++++-------- support/appveyor.yml | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/support/appveyor-build.py b/support/appveyor-build.py index 2cfcb03a414b..654461032673 100644 --- a/support/appveyor-build.py +++ b/support/appveyor-build.py @@ -23,14 +23,17 @@ # Add MSBuild 14.0 to PATH as described in # http://help.appveyor.com/discussions/problems/2229-v140-not-found-on-vs2105rc. os.environ['PATH'] = r'C:\Program Files (x86)\MSBuild\15.0\Bin;' + path - if image == 'Visual Studio 2013': - generator = 'Visual Studio 12 2013' - elif image == 'Visual Studio 2015': - generator = 'Visual Studio 14 2015' - elif image == 'Visual Studio 2017': - generator = 'Visual Studio 15 2017' - if platform == 'x64': - generator += ' Win64' + if image == 'Visual Studio 2019': + generator = 'Visual Studio 16 2019' + if platform == 'x64': + cmake_command.extend(['-A', 'x64']) + else: + if image == 'Visual Studio 2015': + generator = 'Visual Studio 14 2015' + elif image == 'Visual Studio 2017': + generator = 'Visual Studio 15 2017' + if platform == 'x64': + generator += ' Win64' cmake_command.append('-G' + generator) build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4'] test_command = ['ctest', '-C', config] diff --git a/support/appveyor.yml b/support/appveyor.yml index 525cbe0e2a64..f53e4383998b 100644 --- a/support/appveyor.yml +++ b/support/appveyor.yml @@ -4,19 +4,27 @@ configuration: clone_depth: 1 -platform: - - Win32 - - x64 - image: - Visual Studio 2015 + - Visual Studio 2019 - Visual Studio 2017 +platform: + - Win32 + - x64 + environment: CTEST_OUTPUT_ON_FAILURE: 1 MSVC_DEFAULT_OPTIONS: ON BUILD: msvc +matrix: + exclude: + - image: Visual Studio 2015 + platform: Win32 + - image: Visual Studio 2019 + platform: Win32 + before_build: - mkdir build - cd build From 87e4ea2906d1134346de8d88c9e88e9c8cee0742 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 08:24:36 -0700 Subject: [PATCH 03/16] Fix a warning --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 02d6a8588f97..ace5ed67a3c9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,7 +26,7 @@ if (MSVC) target_compile_definitions(gmock PUBLIC _VARIADIC_MAX=10) # Disable MSVC warnings of _CRT_INSECURE_DEPRECATE functions. - target_compile_definitions(gmock PUBLIC _CRT_SECURE_NO_WARNINGS) + target_compile_definitions(gmock PRIVATE _CRT_SECURE_NO_WARNINGS) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Disable MSVC warnings of POSIX functions. target_compile_options(gmock PUBLIC -Wno-deprecated-declarations) From 78daa50ffc5caf7aedd51d1b2d491e48568bf5ac Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 09:07:49 -0700 Subject: [PATCH 04/16] Fix handling of chrono durations with minimal signed rep --- include/fmt/chrono.h | 33 +++++++++++++++++++++++++-------- test/chrono-test.cc | 5 ++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index f57aef387c3f..738f1beadd59 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -401,6 +401,17 @@ inline T mod(T x, int y) { return std::fmod(x, y); } +// If T is an integral type, maps T to its unsigned counterpart, otherwise +// leaves it unchanged (unlike std::make_unsigned). +template ::value> +struct make_unsigned_or_unchanged { + using type = T; +}; + +template struct make_unsigned_or_unchanged { + using type = typename std::make_unsigned::type; +}; + template ::value, int>::type = 0> inline std::chrono::duration get_milliseconds( @@ -438,21 +449,27 @@ struct chrono_formatter { FormatContext& context; OutputIt out; int precision; - typedef typename std::conditional::value && - sizeof(Rep) < sizeof(int), - int, Rep>::type rep; + // rep is unsigned to avoid overflow. + using rep = typename std::conditional< + std::is_integral::value && sizeof(Rep) < sizeof(int), unsigned, + typename make_unsigned_or_unchanged::type>::type; rep val; typedef std::chrono::duration seconds; seconds s; typedef std::chrono::duration milliseconds; + bool negative; typedef typename FormatContext::char_type char_type; explicit chrono_formatter(FormatContext& ctx, OutputIt o, std::chrono::duration d) - : context(ctx), out(o), val(d.count()) { - if (d.count() < 0) d = -d; - s = std::chrono::duration_cast(d); + : context(ctx), out(o), val(d.count()), negative(false) { + if (d.count() < 0) { + val = -val; + negative = true; + } + s = std::chrono::duration_cast( + std::chrono::duration(val)); } Rep hour() const { return mod((s.count() / 3600), 24); } @@ -474,9 +491,9 @@ struct chrono_formatter { } void write_sign() { - if (val < 0) { + if (negative) { *out++ = '-'; - val = -val; + negative = false; } } diff --git a/test/chrono-test.cc b/test/chrono-test.cc index abb8cb8bbe1f..a9412c90e248 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -306,7 +306,7 @@ TEST(ChronoTest, InvalidColons) { fmt::format_error); } -TEST(ChronoTest, NegativeDuration) { +TEST(ChronoTest, NegativeDurations) { EXPECT_EQ("-12345", fmt::format("{:%Q}", std::chrono::seconds(-12345))); EXPECT_EQ("-03:25:45", fmt::format("{:%H:%M:%S}", std::chrono::seconds(-12345))); @@ -316,6 +316,9 @@ TEST(ChronoTest, NegativeDuration) { EXPECT_EQ("-00.127", fmt::format("{:%S}", std::chrono::duration{-127})); + auto min = std::numeric_limits::min(); + EXPECT_EQ(fmt::format("{}", min), + fmt::format("{:%Q}", std::chrono::duration(min))); } TEST(ChronoTest, SpecialDurations) { From 67feef558969b9819987c6e55751075b8279c347 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 09:35:02 -0700 Subject: [PATCH 05/16] Make enable_if_t more std-like and move to fmt namespace --- include/fmt/core.h | 12 ++++++++---- include/fmt/format-inl.h | 2 +- include/fmt/format.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index a733e4ef01ab..6e73481f8e62 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -199,6 +199,11 @@ #endif FMT_BEGIN_NAMESPACE + +// An implementation of enable_if_t for pre-C++14 systems. +template +using enable_if_t = typename std::enable_if::type; + namespace internal { #if defined(FMT_USE_STRING_VIEW) @@ -210,10 +215,9 @@ using std_string_view = std::experimental::basic_string_view; template struct std_string_view {}; #endif -// An enable_if helper to be used in template parameters. enable_if in template -// parameters results in much shorter symbols: https://godbolt.org/z/sWw4vP. -template using enable_if_t = typename std::enable_if::type; -#define FMT_ENABLE_IF(...) internal::enable_if_t<__VA_ARGS__> = 0 +// An enable_if helper to be used in template parameters which results in much +// shorter symbols: https://godbolt.org/z/sWw4vP. +#define FMT_ENABLE_IF(...) enable_if_t<__VA_ARGS__, int> = 0 #if (__cplusplus >= 201703L || \ (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) && \ diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 24c6c77bcdcd..28027a592091 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -674,7 +674,7 @@ template struct grisu_shortest_handler { } }; -template > +template > FMT_API bool grisu_format(Double value, buffer& buf, int precision, unsigned options, int& exp) { FMT_ASSERT(value >= 0, "value is negative"); diff --git a/include/fmt/format.h b/include/fmt/format.h index 7e4cf3be9044..42846f902cd6 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -2245,7 +2245,7 @@ FMT_CONSTEXPR bool do_check_format_string(basic_string_view s, } template ::value>> + enable_if_t::value, int>> void check_format_string(S format_str) { typedef typename S::char_type char_t; FMT_CONSTEXPR_DECL bool invalid_format = From 2833c76f223289a9de47c64d0c29a21a9d81ba7e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 12:14:27 -0700 Subject: [PATCH 06/16] Move char_t to template param to reduce symbol size --- include/fmt/core.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 6e73481f8e62..e9cea5701434 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1443,11 +1443,11 @@ inline std::basic_string vformat( std::string message = fmt::format("The answer is {}", 42); \endrst */ -// Use SFINAE instead of static_assert because of color overload of fmt::format. +// Pass fmt::char_t as a default template parameter instead of using +// std::basic_string> to reduce the symbol size. template ::value)> -inline std::basic_string format(const S& format_str, - const Args&... args) { + typename Char = enable_if_t::value, char_t>> +inline std::basic_string format(const S& format_str, const Args&... args) { return internal::vformat(to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } From 4c650057a06bf9565014269bd74a1635fdd57226 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 12:32:24 -0700 Subject: [PATCH 07/16] FMT_CHAR -> char_t --- include/fmt/core.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index e9cea5701434..7bc20af0fa06 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1352,9 +1352,10 @@ template ::value)> void check_format_string(S); -template ::value)> -inline format_arg_store::type, Args...> +template < + typename S, typename... Args, + typename Char = enable_if_t::value, fmt::char_t>> +inline format_arg_store::type, Args...> make_args_checked(const S& format_str, const Args&... args) { internal::check_format_string(format_str); return {args...}; @@ -1386,8 +1387,8 @@ typename buffer_context::type::iterator vformat_to( fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); \endrst */ -template -inline internal::named_arg arg(const S& name, const T& arg) { +template > +inline internal::named_arg arg(const S& name, const T& arg) { static_assert(internal::is_string::value, ""); return {name, arg}; } @@ -1405,11 +1406,12 @@ template struct is_contiguous> : std::true_type {}; /** Formats a string and writes the output to ``out``. */ -template -typename std::enable_if::value, - std::back_insert_iterator>::type -vformat_to(std::back_insert_iterator out, const S& format_str, - basic_format_args::type> args) { +template < + typename Container, typename S, + typename Char = enable_if_t::value, char_t>> +std::back_insert_iterator vformat_to( + std::back_insert_iterator out, const S& format_str, + basic_format_args::type> args) { internal::container_buffer buf(internal::get_container(out)); internal::vformat_to(buf, to_string_view(format_str), args); return out; @@ -1425,8 +1427,8 @@ inline std::back_insert_iterator format_to( {internal::make_args_checked(format_str, args...)}); } -template ::value)> +template ::value, char_t>> inline std::basic_string vformat( const S& format_str, basic_format_args::type> args) { @@ -1447,7 +1449,8 @@ inline std::basic_string vformat( // std::basic_string> to reduce the symbol size. template ::value, char_t>> -inline std::basic_string format(const S& format_str, const Args&... args) { +inline std::basic_string format(const S& format_str, + const Args&... args) { return internal::vformat(to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } From 5b7bbf88537f704005e3e71d9d4fda57e880e416 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 15:01:04 -0700 Subject: [PATCH 08/16] Revert "FMT_CHAR -> char_t" This reverts commit 4c650057a06bf9565014269bd74a1635fdd57226. --- include/fmt/core.h | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 7bc20af0fa06..e9cea5701434 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1352,10 +1352,9 @@ template ::value)> void check_format_string(S); -template < - typename S, typename... Args, - typename Char = enable_if_t::value, fmt::char_t>> -inline format_arg_store::type, Args...> +template ::value)> +inline format_arg_store::type, Args...> make_args_checked(const S& format_str, const Args&... args) { internal::check_format_string(format_str); return {args...}; @@ -1387,8 +1386,8 @@ typename buffer_context::type::iterator vformat_to( fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); \endrst */ -template > -inline internal::named_arg arg(const S& name, const T& arg) { +template +inline internal::named_arg arg(const S& name, const T& arg) { static_assert(internal::is_string::value, ""); return {name, arg}; } @@ -1406,12 +1405,11 @@ template struct is_contiguous> : std::true_type {}; /** Formats a string and writes the output to ``out``. */ -template < - typename Container, typename S, - typename Char = enable_if_t::value, char_t>> -std::back_insert_iterator vformat_to( - std::back_insert_iterator out, const S& format_str, - basic_format_args::type> args) { +template +typename std::enable_if::value, + std::back_insert_iterator>::type +vformat_to(std::back_insert_iterator out, const S& format_str, + basic_format_args::type> args) { internal::container_buffer buf(internal::get_container(out)); internal::vformat_to(buf, to_string_view(format_str), args); return out; @@ -1427,8 +1425,8 @@ inline std::back_insert_iterator format_to( {internal::make_args_checked(format_str, args...)}); } -template ::value, char_t>> +template ::value)> inline std::basic_string vformat( const S& format_str, basic_format_args::type> args) { @@ -1449,8 +1447,7 @@ inline std::basic_string vformat( // std::basic_string> to reduce the symbol size. template ::value, char_t>> -inline std::basic_string format(const S& format_str, - const Args&... args) { +inline std::basic_string format(const S& format_str, const Args&... args) { return internal::vformat(to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } From 9df0e2d1f160980d2ae86ccd95f167e8dcb2ff43 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 07:30:26 -0700 Subject: [PATCH 09/16] Implement string parsing --- test/scan-test.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/scan-test.cc b/test/scan-test.cc index 42417748211e..f9edcecfcfc3 100644 --- a/test/scan-test.cc +++ b/test/scan-test.cc @@ -21,6 +21,7 @@ struct scan_arg { unsigned* uint_value; long long* long_long_value; unsigned long long* ulong_long_value; + std::string* string; // TODO: more types }; @@ -31,6 +32,7 @@ struct scan_arg { : arg_type(long_long_type), long_long_value(&value) {} scan_arg(unsigned long long& value) : arg_type(ulong_long_type), ulong_long_value(&value) {} + scan_arg(std::string& value) : arg_type(string_type), string(&value) {} }; } // namespace internal @@ -112,6 +114,11 @@ struct scan_handler : error_handler { case ulong_long_type: *arg_.ulong_long_value = read_uint(); break; + case string_type: { + while (begin_ != end_ && *begin_ != ' ') + arg_.string->push_back(*begin_++); + break; + } default: assert(false); } @@ -178,6 +185,11 @@ TEST(ScanTest, ReadULongLong) { EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, "invalid input"); } +TEST(ScanTest, ReadString) { + std::string s; + fmt::scan("foo", "{}", s); + EXPECT_EQ(s, "foo"); +} TEST(ScanTest, InvalidFormat) { EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, @@ -185,3 +197,11 @@ TEST(ScanTest, InvalidFormat) { EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error, "invalid format string"); } + +TEST(ScanTest, Example) { + std::string key; + int value; + fmt::scan("answer = 42", "{} = {}", key, value); + EXPECT_EQ(key, "answer"); + EXPECT_EQ(value, 42); +} From af2c73772ce8e06b266650849b4232c25d1fe63f Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 11:11:28 -0700 Subject: [PATCH 10/16] Implement parsing of string_views --- test/scan-test.cc | 52 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/test/scan-test.cc b/test/scan-test.cc index f9edcecfcfc3..82e83249a2d4 100644 --- a/test/scan-test.cc +++ b/test/scan-test.cc @@ -14,25 +14,40 @@ FMT_BEGIN_NAMESPACE namespace internal { +enum class scan_type { + none_type, + int_type, + uint_type, + long_long_type, + ulong_long_type, + string_type, + string_view_type +}; + struct scan_arg { - type arg_type; + scan_type arg_type; union { int* int_value; unsigned* uint_value; long long* long_long_value; unsigned long long* ulong_long_value; std::string* string; + fmt::string_view* string_view; // TODO: more types }; - scan_arg() : arg_type(none_type) {} - scan_arg(int& value) : arg_type(int_type), int_value(&value) {} - scan_arg(unsigned& value) : arg_type(uint_type), uint_value(&value) {} + scan_arg() : arg_type(scan_type::none_type) {} + scan_arg(int& value) : arg_type(scan_type::int_type), int_value(&value) {} + scan_arg(unsigned& value) + : arg_type(scan_type::uint_type), uint_value(&value) {} scan_arg(long long& value) - : arg_type(long_long_type), long_long_value(&value) {} + : arg_type(scan_type::long_long_type), long_long_value(&value) {} scan_arg(unsigned long long& value) - : arg_type(ulong_long_type), ulong_long_value(&value) {} - scan_arg(std::string& value) : arg_type(string_type), string(&value) {} + : arg_type(scan_type::ulong_long_type), ulong_long_value(&value) {} + scan_arg(std::string& value) + : arg_type(scan_type::string_type), string(&value) {} + scan_arg(fmt::string_view& value) + : arg_type(scan_type::string_view_type), string_view(&value) {} }; } // namespace internal @@ -102,22 +117,28 @@ struct scan_handler : error_handler { void on_replacement_field(const char*) { switch (arg_.arg_type) { - case int_type: + case scan_type::int_type: *arg_.int_value = read_int(); break; - case uint_type: + case scan_type::uint_type: *arg_.uint_value = read_uint(); break; - case long_long_type: + case scan_type::long_long_type: *arg_.long_long_value = read_int(); break; - case ulong_long_type: + case scan_type::ulong_long_type: *arg_.ulong_long_value = read_uint(); break; - case string_type: { + case scan_type::string_type: while (begin_ != end_ && *begin_ != ' ') arg_.string->push_back(*begin_++); break; + case scan_type::string_view_type: { + auto s = begin_; + while (begin_ != end_ && *begin_ != ' ') + ++begin_; + *arg_.string_view = fmt::string_view(s, begin_ - s); + break; } default: assert(false); @@ -185,12 +206,19 @@ TEST(ScanTest, ReadULongLong) { EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, "invalid input"); } + TEST(ScanTest, ReadString) { std::string s; fmt::scan("foo", "{}", s); EXPECT_EQ(s, "foo"); } +TEST(ScanTest, ReadStringView) { + fmt::string_view s; + fmt::scan("foo", "{}", s); + EXPECT_EQ(s, "foo"); +} + TEST(ScanTest, InvalidFormat) { EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, "argument index out of range"); From 76ef39fc50ec156346f93aa2c72f4a72ba175c88 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 13:19:33 -0700 Subject: [PATCH 11/16] Update vagrant config --- support/Vagrantfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/support/Vagrantfile b/support/Vagrantfile index d18aec3c2e0f..0cd16a5caef9 100644 --- a/support/Vagrantfile +++ b/support/Vagrantfile @@ -1,19 +1,18 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -# A vagrant config for testing against gcc-4.4. +# A vagrant config for testing against gcc-4.8. Vagrant.configure("2") do |config| - config.vm.box = "bento/ubuntu-10.04" + config.vm.box = "ubuntu/trusty64" config.vm.provider "virtualbox" do |vb| vb.memory = "4096" end config.vm.provision "shell", inline: <<-SHELL - sed -i 's/us.archive/old-releases/' /etc/apt/sources.list apt-get update apt-get install -y g++ make wget - wget -q https://www.dropbox.com/s/ssvomsla6bkx2wl/cmake-3.14.4-Linux-x86_64.tar.gz + wget -q https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.4-Linux-x86_64.tar.gz tar xzf cmake-3.14.4-Linux-x86_64.tar.gz ln -s `pwd`/cmake-3.14.4-Linux-x86_64/bin/cmake /usr/local/bin SHELL From 89d6c959b203fca96ec240d2c255867b7f1959a5 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 13:24:32 -0700 Subject: [PATCH 12/16] Fix cmake link --- support/Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/Vagrantfile b/support/Vagrantfile index 0cd16a5caef9..67360e1e277c 100644 --- a/support/Vagrantfile +++ b/support/Vagrantfile @@ -12,7 +12,7 @@ Vagrant.configure("2") do |config| config.vm.provision "shell", inline: <<-SHELL apt-get update apt-get install -y g++ make wget - wget -q https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.4-Linux-x86_64.tar.gz + wget -q https://github.com/Kitware/CMake/releases/download/v3.14.4/cmake-3.14.4-Linux-x86_64.tar.gz tar xzf cmake-3.14.4-Linux-x86_64.tar.gz ln -s `pwd`/cmake-3.14.4-Linux-x86_64/bin/cmake /usr/local/bin SHELL From 56d2b91108b78dbbd688488ea1f76e452fa2a9e9 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 13:57:19 -0700 Subject: [PATCH 13/16] Install git --- support/Vagrantfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/Vagrantfile b/support/Vagrantfile index 67360e1e277c..de0fcb9efafa 100644 --- a/support/Vagrantfile +++ b/support/Vagrantfile @@ -11,7 +11,7 @@ Vagrant.configure("2") do |config| config.vm.provision "shell", inline: <<-SHELL apt-get update - apt-get install -y g++ make wget + apt-get install -y g++ make wget git wget -q https://github.com/Kitware/CMake/releases/download/v3.14.4/cmake-3.14.4-Linux-x86_64.tar.gz tar xzf cmake-3.14.4-Linux-x86_64.tar.gz ln -s `pwd`/cmake-3.14.4-Linux-x86_64/bin/cmake /usr/local/bin From 4d4b8c238d0ef7ed242d3fed550a3e85cbedd4e1 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 1 Jun 2019 12:32:24 -0700 Subject: [PATCH 14/16] FMT_CHAR -> char_t --- include/fmt/color.h | 27 +++++++++++------------- include/fmt/core.h | 48 ++++++++++++++++++++++++++----------------- include/fmt/format.h | 38 ++++++++++++++++++---------------- include/fmt/locale.h | 29 +++++++++++++------------- include/fmt/ostream.h | 10 ++++----- include/fmt/prepare.h | 8 ++++---- include/fmt/printf.h | 33 +++++++++++++---------------- 7 files changed, 99 insertions(+), 94 deletions(-) diff --git a/include/fmt/color.h b/include/fmt/color.h index b29ab0821920..5c9b04917555 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -556,7 +556,7 @@ std::basic_string vformat( } } // namespace internal -template ::type> +template > void vprint(std::FILE* f, const text_style& ts, const S& format, basic_format_args::type> args) { bool has_style = false; @@ -587,13 +587,12 @@ void vprint(std::FILE* f, const text_style& ts, const S& format, fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ -template ::value)> -void print(std::FILE* f, const text_style& ts, const String& format_str, +template ::value)> +void print(std::FILE* f, const text_style& ts, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef typename internal::char_t::type char_t; - typedef typename buffer_context::type context_t; + typedef typename buffer_context >::type context_t; format_arg_store as{args...}; vprint(f, ts, format_str, basic_format_args(as)); } @@ -605,14 +604,13 @@ void print(std::FILE* f, const text_style& ts, const String& format_str, fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); */ -template ::value)> -void print(const text_style& ts, const String& format_str, - const Args&... args) { +template ::value)> +void print(const text_style& ts, const S& format_str, const Args&... args) { return print(stdout, ts, format_str, args...); } -template +template > inline std::basic_string vformat( const text_style& ts, const S& format_str, basic_format_args::type> args) { @@ -631,10 +629,9 @@ inline std::basic_string vformat( "The answer is {}", 42); \endrst */ -template -inline std::basic_string format(const text_style& ts, - const S& format_str, - const Args&... args) { +template > +inline std::basic_string format(const text_style& ts, const S& format_str, + const Args&... args) { return internal::vformat(ts, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } diff --git a/include/fmt/core.h b/include/fmt/core.h index e9cea5701434..3298b05fcb23 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -617,7 +617,7 @@ struct is_string template <> struct is_string; template <> struct is_string; -template struct char_t { +template struct char_t_impl { typedef decltype(to_string_view(std::declval())) result; typedef typename result::char_type type; }; @@ -883,7 +883,7 @@ FMT_CONSTEXPR11 init, string_type> make_value(const S& val) { // Handle adapted strings. static_assert(std::is_same::type>::value, + typename internal::char_t_impl::type>::value, "mismatch between char-types of context and argument"); return to_string_view(val); } @@ -1311,8 +1311,7 @@ struct wformat_args : basic_format_args { }; /** String's character type. */ -template using char_t = typename internal::char_t::type; -#define FMT_CHAR(S) fmt::char_t +template using char_t = typename internal::char_t_impl::type; namespace internal { template @@ -1353,8 +1352,8 @@ template ::value)> -inline format_arg_store::type, Args...> + typename Char = enable_if_t::value, char_t>> +inline format_arg_store::type, Args...> make_args_checked(const S& format_str, const Args&... args) { internal::check_format_string(format_str); return {args...}; @@ -1386,8 +1385,8 @@ typename buffer_context::type::iterator vformat_to( fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); \endrst */ -template -inline internal::named_arg arg(const S& name, const T& arg) { +template > +inline internal::named_arg arg(const S& name, const T& arg) { static_assert(internal::is_string::value, ""); return {name, arg}; } @@ -1404,13 +1403,23 @@ struct is_contiguous> : std::true_type {}; template struct is_contiguous> : std::true_type {}; +template +struct is_contiguous_back_insert_iterator : std::false_type {}; + +template +struct is_contiguous_back_insert_iterator> + : is_contiguous {}; + /** Formats a string and writes the output to ``out``. */ -template -typename std::enable_if::value, - std::back_insert_iterator>::type -vformat_to(std::back_insert_iterator out, const S& format_str, - basic_format_args::type> args) { - internal::container_buffer buf(internal::get_container(out)); +template ::value, char_t>> +OutputIt vformat_to( + OutputIt out, const S& format_str, + basic_format_args::type> args) { + using container = typename std::remove_reference::type; + internal::container_buffer buf((internal::get_container(out))); internal::vformat_to(buf, to_string_view(format_str), args); return out; } @@ -1425,8 +1434,8 @@ inline std::back_insert_iterator format_to( {internal::make_args_checked(format_str, args...)}); } -template ::value)> +template ::value, char_t>> inline std::basic_string vformat( const S& format_str, basic_format_args::type> args) { @@ -1443,11 +1452,12 @@ inline std::basic_string vformat( std::string message = fmt::format("The answer is {}", 42); \endrst */ -// Pass fmt::char_t as a default template parameter instead of using -// std::basic_string> to reduce the symbol size. +// Pass char_t as a default template parameter instead of using +// std::basic_string> to reduce the symbol size. template ::value, char_t>> -inline std::basic_string format(const S& format_str, const Args&... args) { +inline std::basic_string format(const S& format_str, + const Args&... args) { return internal::vformat(to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } diff --git a/include/fmt/format.h b/include/fmt/format.h index 42846f902cd6..c8ce2f39bf26 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1805,10 +1805,11 @@ struct string_view_metadata { : offset_(view.data() - primary_string.data()), size_(view.size()) {} FMT_CONSTEXPR string_view_metadata(std::size_t offset, std::size_t size) : offset_(offset), size_(size) {} - template ::value)> - FMT_CONSTEXPR basic_string_view to_view(S&& str) const { + template ::value, char_t>> + FMT_CONSTEXPR basic_string_view to_view(S&& str) const { const auto view = to_string_view(str); - return basic_string_view(view.data() + offset_, size_); + return basic_string_view(view.data() + offset_, size_); } std::size_t offset_; @@ -3384,7 +3385,7 @@ typename buffer_context::type::iterator internal::vformat_to( args); } -template , FMT_ENABLE_IF(internal::is_string::value)> inline typename buffer_context::type::iterator vformat_to( internal::buffer& buf, const S& format_str, @@ -3393,12 +3394,12 @@ inline typename buffer_context::type::iterator vformat_to( } template ::type> + typename Char = enable_if_t::value, char_t>> inline typename buffer_context::type::iterator format_to( basic_memory_buffer& buf, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef typename buffer_context::type context; + using context = typename buffer_context::type; format_arg_store as{args...}; return internal::vformat_to(buf, to_string_view(format_str), basic_format_args(as)); @@ -3459,12 +3460,13 @@ struct format_args_t { type; }; -template ::value)> +template ::value && + !is_contiguous_back_insert_iterator::value)> inline OutputIt vformat_to( - OutputIt out, const String& format_str, - typename format_args_t::type args) { - typedef output_range range; + OutputIt out, const S& format_str, + typename format_args_t>::type args) { + typedef output_range> range; return vformat_to>(range(out), to_string_view(format_str), args); } @@ -3481,13 +3483,13 @@ inline OutputIt vformat_to( \endrst */ template -inline - typename std::enable_if::value && - internal::is_output_iterator::value, - OutputIt>::type - format_to(OutputIt out, const S& format_str, const Args&... args) { +inline OutputIt format_to(OutputIt out, const S& format_str, + const Args&... args) { + static_assert(internal::is_output_iterator::value && + internal::is_string::value, + ""); internal::check_format_string(format_str); - typedef typename format_context_t::type context; + typedef typename format_context_t>::type context; format_arg_store as{args...}; return vformat_to(out, to_string_view(format_str), basic_format_args(as)); @@ -3542,7 +3544,7 @@ inline format_to_n_result format_to_n(OutputIt out, std::size_t n, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef FMT_CHAR(S) Char; + using Char = char_t; format_arg_store::type, Args...> as(args...); return vformat_to_n(out, n, to_string_view(format_str), diff --git a/include/fmt/locale.h b/include/fmt/locale.h index aeb352170ebd..b6b4cf901c3e 100644 --- a/include/fmt/locale.h +++ b/include/fmt/locale.h @@ -34,38 +34,39 @@ std::basic_string vformat( } } // namespace internal -template +template > inline std::basic_string vformat( const std::locale& loc, const S& format_str, basic_format_args::type> args) { return internal::vformat(loc, to_string_view(format_str), args); } -template -inline std::basic_string format(const std::locale& loc, - const S& format_str, - const Args&... args) { +template > +inline std::basic_string format(const std::locale& loc, + const S& format_str, + const Args&... args) { return internal::vformat(loc, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); } -template ::value)> -inline OutputIt vformat_to( - OutputIt out, const std::locale& loc, const String& format_str, - typename format_args_t::type args) { - typedef output_range range; +template ::value, char_t>> +inline OutputIt vformat_to(OutputIt out, const std::locale& loc, + const S& format_str, + typename format_args_t::type args) { + using range = output_range; return vformat_to>( range(out), to_string_view(format_str), args, internal::locale_ref(loc)); } template ::value&& - internal::is_output_iterator::value)> + FMT_ENABLE_IF(internal::is_output_iterator::value&& + internal::is_string::value)> inline OutputIt format_to(OutputIt out, const std::locale& loc, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef typename format_context_t::type context; + using context = typename format_context_t>::type; format_arg_store as{args...}; return vformat_to(out, loc, to_string_view(format_str), basic_format_args(as)); diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 47d81a90500f..0399108f148d 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -120,13 +120,13 @@ struct convert_to_int< }; template -inline void vprint( - std::basic_ostream& os, basic_string_view format_str, - basic_format_args::type> args) { +void vprint(std::basic_ostream& os, basic_string_view format_str, + basic_format_args::type> args) { basic_memory_buffer buffer; internal::vformat_to(buffer, format_str, args); internal::write(os, buffer); } + /** \rst Prints formatted data to the stream *os*. @@ -137,8 +137,8 @@ inline void vprint( \endrst */ template ::value)> -inline void print(std::basic_ostream& os, const S& format_str, + typename Char = enable_if_t::value, char_t>> +inline void print(std::basic_ostream& os, const S& format_str, const Args&... args) { vprint(os, to_string_view(format_str), {internal::make_args_checked(format_str, args...)}); diff --git a/include/fmt/prepare.h b/include/fmt/prepare.h index 7bfe73d43a08..7f4ff082b9da 100644 --- a/include/fmt/prepare.h +++ b/include/fmt/prepare.h @@ -185,8 +185,8 @@ class format_preparation_handler : public internal::error_handler { template class prepared_format { public: - typedef FMT_CHAR(Format) char_type; - typedef format_part format_part_t; + using char_type = char_t; + using format_part_t = format_part; prepared_format(Format f) : format_(std::move(f)), parts_provider_(to_string_view(format_)) {} @@ -351,7 +351,7 @@ class prepared_format { template class compiletime_prepared_parts_type_provider { private: - typedef FMT_CHAR(Format) char_type; + using char_type = char_t; class count_handler { private: @@ -649,7 +649,7 @@ class parts_container { // Delegate preparing to preparator, to take advantage of a partial // specialization. template struct preparator { - typedef parts_container container; + typedef parts_container> container; typedef typename basic_prepared_format::type prepared_format_type; diff --git a/include/fmt/printf.h b/include/fmt/printf.h index f879dc830018..3dbf1fc0da4a 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -608,7 +608,7 @@ inline format_arg_store make_wprintf_args( return {args...}; } -template +template > inline std::basic_string vsprintf( const S& format, basic_format_args< @@ -629,16 +629,14 @@ inline std::basic_string vsprintf( \endrst */ template ::value)> -inline std::basic_string sprintf(const S& format, - const Args&... args) { - typedef internal::buffer buffer; - typedef typename basic_printf_context_t::type context; + typename Char = enable_if_t::value, char_t>> +inline std::basic_string sprintf(const S& format, const Args&... args) { + using context = typename basic_printf_context_t>::type; format_arg_store as{args...}; return vsprintf(to_string_view(format), basic_format_args(as)); } -template +template > inline int vfprintf( std::FILE* f, const S& format, basic_format_args< @@ -662,15 +660,14 @@ inline int vfprintf( \endrst */ template ::value)> + typename Char = enable_if_t::value, char_t>> inline int fprintf(std::FILE* f, const S& format, const Args&... args) { - typedef internal::buffer buffer; - typedef typename basic_printf_context_t::type context; + using context = typename basic_printf_context_t>::type; format_arg_store as{args...}; return vfprintf(f, to_string_view(format), basic_format_args(as)); } -template +template > inline int vprintf( const S& format, basic_format_args< @@ -692,13 +689,13 @@ template ::value)> inline int printf(const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef internal::buffer buffer; - typedef typename basic_printf_context_t::type context; + using buffer = internal::buffer>; + using context = typename basic_printf_context_t::type; format_arg_store as{args...}; return vprintf(to_string_view(format_str), basic_format_args(as)); } -template +template > inline int vfprintf( std::basic_ostream& os, const S& format, basic_format_args< @@ -731,13 +728,11 @@ typename ArgFormatter::iterator vprintf(internal::buffer& out, fmt::fprintf(cerr, "Don't %s!", "panic"); \endrst */ -template ::value)> -inline int fprintf(std::basic_ostream& os, const S& format_str, +template > +inline int fprintf(std::basic_ostream& os, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - typedef internal::buffer buffer; - typedef typename basic_printf_context_t::type context; + using context = typename basic_printf_context_t>::type; format_arg_store as{args...}; return vfprintf(os, to_string_view(format_str), basic_format_args(as)); From ec6651087d05e8a3e4e886e2673a492ee3a0db88 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 16:04:17 -0700 Subject: [PATCH 15/16] Remove old is_constructible workarounds and replace typedefs with using --- include/fmt/core.h | 114 +++++++++++++++++-------------------------- include/fmt/printf.h | 9 ++-- test/core-test.cc | 20 ++++---- 3 files changed, 57 insertions(+), 86 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 3298b05fcb23..524c47d4cae1 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -204,6 +204,10 @@ FMT_BEGIN_NAMESPACE template using enable_if_t = typename std::enable_if::type; +// An enable_if helper to be used in template parameters which results in much +// shorter symbols: https://godbolt.org/z/sWw4vP. +#define FMT_ENABLE_IF(...) enable_if_t<__VA_ARGS__, int> = 0 + namespace internal { #if defined(FMT_USE_STRING_VIEW) @@ -215,10 +219,6 @@ using std_string_view = std::experimental::basic_string_view; template struct std_string_view {}; #endif -// An enable_if helper to be used in template parameters which results in much -// shorter symbols: https://godbolt.org/z/sWw4vP. -#define FMT_ENABLE_IF(...) enable_if_t<__VA_ARGS__, int> = 0 - #if (__cplusplus >= 201703L || \ (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) && \ __cpp_lib_is_invocable >= 201703L @@ -266,8 +266,8 @@ template class buffer { virtual void grow(std::size_t capacity) = 0; public: - typedef T value_type; - typedef const T& const_reference; + using value_type = T; + using const_reference = const T&; virtual ~buffer() {} @@ -334,7 +334,7 @@ class container_buffer : public buffer { // Extracts a reference to the container from back_insert_iterator. template inline Container& get_container(std::back_insert_iterator it) { - typedef std::back_insert_iterator bi_iterator; + using bi_iterator = std::back_insert_iterator; struct accessor : bi_iterator { accessor(bi_iterator iter) : bi_iterator(iter) {} using bi_iterator::container; @@ -349,23 +349,6 @@ struct error_handler { // This function is intentionally not constexpr to give a compile-time error. FMT_API FMT_NORETURN void on_error(const char* message); }; - -// GCC 4.6.x cannot expand `T...`. -#if FMT_GCC_VERSION && FMT_GCC_VERSION < 407 -typedef char yes[1]; -typedef char no[2]; - -template struct is_constructible { - template - static yes& test(int (*)[sizeof(new U(std::declval()))]); - template static no& test(...); - enum { value = sizeof(test(nullptr)) == sizeof(yes) }; -}; -#else -template -struct is_constructible : std::is_constructible {}; -#endif -struct dummy_formatter_arg {}; // Workaround broken is_constructible in MSVC. } // namespace internal /** @@ -381,8 +364,8 @@ template class basic_string_view { size_t size_; public: - typedef Char char_type; - typedef const Char* iterator; + using char_type = Char; + using iterator = const Char*; FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} @@ -455,8 +438,8 @@ template class basic_string_view { } }; -typedef basic_string_view string_view; -typedef basic_string_view wstring_view; +using string_view = basic_string_view; +using wstring_view = basic_string_view; /** \rst @@ -525,8 +508,8 @@ class basic_parse_context : private ErrorHandler { int next_arg_id_; public: - typedef Char char_type; - typedef typename basic_string_view::iterator iterator; + using char_type = Char; + using iterator = typename basic_string_view::iterator; explicit FMT_CONSTEXPR basic_parse_context(basic_string_view format_str, ErrorHandler eh = ErrorHandler()) @@ -567,11 +550,11 @@ class basic_parse_context : private ErrorHandler { FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; } }; -typedef basic_parse_context format_parse_context; -typedef basic_parse_context wformat_parse_context; +using format_parse_context = basic_parse_context; +using wformat_parse_context = basic_parse_context; -FMT_DEPRECATED typedef basic_parse_context parse_context; -FMT_DEPRECATED typedef basic_parse_context wparse_context; +using parse_context FMT_DEPRECATED = basic_parse_context; +using wparse_context FMT_DEPRECATED = basic_parse_context; template class basic_format_arg; template class basic_format_args; @@ -579,7 +562,7 @@ template class basic_format_args; // A formatter for objects of type T. template struct formatter { - explicit formatter(internal::dummy_formatter_arg); + formatter() = delete; }; template @@ -669,18 +652,14 @@ template struct custom_value { Context& ctx); }; -template struct is_formattable { - enum { - value = - !is_constructible::type, - internal::dummy_formatter_arg>::value - }; -}; +template +using is_formattable = + std::is_constructible>; // A formatting argument value. template class value { public: - typedef typename Context::char_type char_type; + using char_type = typename Context::char_type; union { int int_value; @@ -727,7 +706,7 @@ template class value { custom.format = &format_custom_arg< T, typename std::conditional< is_formattable::value, - typename Context::template formatter_type::type, + typename Context::template formatter_type, internal::fallback_formatter>::type>; } @@ -779,12 +758,12 @@ FMT_MAKE_VALUE_SAME(uint_type, unsigned) // To minimize the number of types we need to deal with, long is translated // either to int or to long long depending on its size. -typedef std::conditional::type - long_type; +using long_type = + std::conditional::type; FMT_MAKE_VALUE((sizeof(long) == sizeof(int) ? int_type : long_long_type), long, long_type) -typedef std::conditional::type ulong_type; +using ulong_type = std::conditional::type; FMT_MAKE_VALUE((sizeof(unsigned long) == sizeof(unsigned) ? uint_type : ulong_long_type), unsigned long, ulong_type) @@ -849,9 +828,10 @@ inline init make_value(const T& val) { return static_cast(val); } -template , T>::value && - !internal::is_string::value)> +template < + typename C, typename T, typename Char = typename C::char_type, + FMT_ENABLE_IF(std::is_constructible, T>::value && + !internal::is_string::value)> inline init, string_type> make_value(const T& val) { return basic_string_view(val); } @@ -864,7 +844,7 @@ template < FMT_ENABLE_IF(!convert_to_int::value && !std::is_same::value && !std::is_convertible>::value && - !is_constructible, U>::value && + !std::is_constructible, U>::value && !internal::is_string::value)> inline init make_value(const T& val) { return val; @@ -913,7 +893,7 @@ template class basic_format_arg { friend class basic_format_args; friend class internal::arg_map; - typedef typename Context::char_type char_type; + using char_type = typename Context::char_type; public: class handle { @@ -952,7 +932,7 @@ struct monostate {}; template FMT_CONSTEXPR internal::invoke_result_t visit_format_arg( Visitor&& vis, const basic_format_arg& arg) { - typedef typename Context::char_type char_type; + using char_type = typename Context::char_type; switch (arg.type_) { case internal::none_type: break; @@ -1001,7 +981,7 @@ template class arg_map { arg_map(const arg_map&) = delete; void operator=(const arg_map&) = delete; - typedef typename Context::char_type char_type; + using char_type = typename Context::char_type; struct entry { basic_string_view name; @@ -1084,7 +1064,7 @@ inline basic_format_arg make_arg(const T& value) { template class basic_format_context { public: /** The character type for the output. */ - typedef Char char_type; + using char_type = Char; private: OutputIt out_; @@ -1096,13 +1076,9 @@ template class basic_format_context { void operator=(const basic_format_context&) = delete; public: - typedef OutputIt iterator; - typedef basic_format_arg format_arg; - - // using formatter_type = formatter; - template struct formatter_type { - typedef formatter type; - }; + using iterator = OutputIt; + using format_arg = basic_format_arg ; + template using formatter_type = formatter; /** Constructs a ``basic_format_context`` object. References to the arguments are @@ -1137,8 +1113,8 @@ template struct buffer_context { std::back_insert_iterator>, Char> type; }; -typedef buffer_context::type format_context; -typedef buffer_context::type wformat_context; +using format_context = buffer_context::type; +using wformat_context = buffer_context::type; /** \rst @@ -1154,8 +1130,8 @@ template class format_arg_store { // Packed is a macro on MinGW so use IS_PACKED instead. static const bool IS_PACKED = NUM_ARGS < internal::max_packed_args; - typedef typename std::conditional, - basic_format_arg>::type value_type; + using value_type = typename std::conditional, + basic_format_arg>::type; // If the arguments are not packed, add one more element to mark the end. static const size_t DATA_SIZE = @@ -1213,8 +1189,8 @@ inline format_arg_store make_format_args( /** Formatting arguments. */ template class basic_format_args { public: - typedef unsigned size_type; - typedef basic_format_arg format_arg; + using size_type = unsigned; + using format_arg = basic_format_arg; private: // To reduce compiled code size per formatting function call, types of first diff --git a/include/fmt/printf.h b/include/fmt/printf.h index 3dbf1fc0da4a..29f36323a55c 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -329,12 +329,9 @@ template struct printf_formatter { template class basic_printf_context { public: /** The character type for the output. */ - typedef Char char_type; - typedef basic_format_arg format_arg; - - template struct formatter_type { - typedef printf_formatter type; - }; + using char_type = Char; + using format_arg = basic_format_arg; + template using formatter_type = printf_formatter; private: typedef basic_format_specs format_specs; diff --git a/test/core-test.cc b/test/core-test.cc index 5f210b8d955c..ff868e14535e 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -209,17 +209,15 @@ struct custom_context { typedef char char_type; template struct formatter_type { - struct type { - template - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - const char* format(const T&, custom_context& ctx) { - ctx.called = true; - return nullptr; - } - }; + template + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + const char* format(const T&, custom_context& ctx) { + ctx.called = true; + return nullptr; + } }; bool called; From d54e64b3c813067c5dec5097e70f28a847f9eff4 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 2 Jun 2019 17:13:50 -0700 Subject: [PATCH 16/16] Make buffer_context an alias template --- include/fmt/color.h | 16 ++++++------- include/fmt/core.h | 49 ++++++++++++++++++---------------------- include/fmt/format-inl.h | 2 +- include/fmt/format.h | 19 ++++++++-------- include/fmt/locale.h | 12 +++++----- include/fmt/ostream.h | 2 +- include/fmt/prepare.h | 4 ++-- test/format | 3 +-- 8 files changed, 50 insertions(+), 57 deletions(-) diff --git a/include/fmt/color.h b/include/fmt/color.h index 5c9b04917555..bc534805bec1 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -526,9 +526,9 @@ template <> struct is_string : std::false_type {}; template <> struct is_string : std::false_type {}; template -std::basic_string vformat( - const text_style& ts, basic_string_view format_str, - basic_format_args::type> args) { +std::basic_string vformat(const text_style& ts, + basic_string_view format_str, + basic_format_args > args) { basic_memory_buffer buffer; bool has_style = false; if (ts.has_emphasis()) { @@ -558,7 +558,7 @@ std::basic_string vformat( template > void vprint(std::FILE* f, const text_style& ts, const S& format, - basic_format_args::type> args) { + basic_format_args > args) { bool has_style = false; if (ts.has_emphasis()) { has_style = true; @@ -592,9 +592,9 @@ template (format_str); - typedef typename buffer_context >::type context_t; - format_arg_store as{args...}; - vprint(f, ts, format_str, basic_format_args(as)); + using context = buffer_context >; + format_arg_store as{args...}; + vprint(f, ts, format_str, basic_format_args(as)); } /** @@ -613,7 +613,7 @@ void print(const text_style& ts, const S& format_str, const Args&... args) { template > inline std::basic_string vformat( const text_style& ts, const S& format_str, - basic_format_args::type> args) { + basic_format_args > args) { return internal::vformat(ts, to_string_view(format_str), args); } diff --git a/include/fmt/core.h b/include/fmt/core.h index 524c47d4cae1..58c716d85f15 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1077,7 +1077,7 @@ template class basic_format_context { public: using iterator = OutputIt; - using format_arg = basic_format_arg ; + using format_arg = basic_format_arg; template using formatter_type = formatter; /** @@ -1108,13 +1108,12 @@ template class basic_format_context { internal::locale_ref locale() { return loc_; } }; -template struct buffer_context { - typedef basic_format_context< - std::back_insert_iterator>, Char> - type; -}; -using format_context = buffer_context::type; -using wformat_context = buffer_context::type; +template +using buffer_context = + basic_format_context>, + Char>; +using format_context = buffer_context; +using wformat_context = buffer_context; /** \rst @@ -1130,8 +1129,9 @@ template class format_arg_store { // Packed is a macro on MinGW so use IS_PACKED instead. static const bool IS_PACKED = NUM_ARGS < internal::max_packed_args; - using value_type = typename std::conditional, - basic_format_arg>::type; + using value_type = + typename std::conditional, + basic_format_arg>::type; // If the arguments are not packed, add one more element to mark the end. static const size_t DATA_SIZE = @@ -1301,8 +1301,7 @@ template struct named_arg_base { basic_string_view name; // Serialized value. - mutable char - data[sizeof(basic_format_arg::type>)]; + mutable char data[sizeof(basic_format_arg>)]; named_arg_base(basic_string_view nm) : name(nm) {} @@ -1329,21 +1328,20 @@ void check_format_string(S); template ::value, char_t>> -inline format_arg_store::type, Args...> -make_args_checked(const S& format_str, const Args&... args) { +inline format_arg_store, Args...> make_args_checked( + const S& format_str, const Args&... args) { internal::check_format_string(format_str); return {args...}; } template -std::basic_string vformat( - basic_string_view format_str, - basic_format_args::type> args); +std::basic_string vformat(basic_string_view format_str, + basic_format_args> args); template -typename buffer_context::type::iterator vformat_to( +typename buffer_context::iterator vformat_to( internal::buffer& buf, basic_string_view format_str, - basic_format_args::type> args); + basic_format_args> args); } // namespace internal /** @@ -1387,12 +1385,10 @@ struct is_contiguous_back_insert_iterator> : is_contiguous {}; /** Formats a string and writes the output to ``out``. */ -template ::value, char_t>> -OutputIt vformat_to( - OutputIt out, const S& format_str, - basic_format_args::type> args) { +template , + FMT_ENABLE_IF(is_contiguous_back_insert_iterator::value)> +OutputIt vformat_to(OutputIt out, const S& format_str, + basic_format_args> args) { using container = typename std::remove_reference::type; internal::container_buffer buf((internal::get_container(out))); @@ -1413,8 +1409,7 @@ inline std::back_insert_iterator format_to( template ::value, char_t>> inline std::basic_string vformat( - const S& format_str, - basic_format_args::type> args) { + const S& format_str, basic_format_args> args) { return internal::vformat(to_string_view(format_str), args); } diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 28027a592091..fa5eb6f3610c 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -953,7 +953,7 @@ FMT_FUNC void report_windows_error(int error_code, FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { memory_buffer buffer; internal::vformat_to(buffer, format_str, - basic_format_args::type>(args)); + basic_format_args>(args)); fwrite_fully(buffer.data(), 1, buffer.size(), f); } diff --git a/include/fmt/format.h b/include/fmt/format.h index c8ce2f39bf26..82f7092d00c1 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3046,7 +3046,7 @@ class format_int { template struct formatter::type, T>::value>::type> { + buffer_context, T>::value>::type> { FMT_CONSTEXPR formatter() : format_str_(nullptr) {} // Parses format specifiers stopping either at the end of the range or at the @@ -3055,8 +3055,7 @@ struct formatter handler_type; - auto type = - internal::get_type::type, T>::value; + auto type = internal::get_type, T>::value; internal::specs_checker handler(handler_type(specs_, ctx), type); auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); @@ -3377,9 +3376,9 @@ std::basic_string to_string(const basic_memory_buffer& buf) { } template -typename buffer_context::type::iterator internal::vformat_to( +typename buffer_context::iterator internal::vformat_to( internal::buffer& buf, basic_string_view format_str, - basic_format_args::type> args) { + basic_format_args> args) { typedef back_insert_range> range; return vformat_to>(buf, to_string_view(format_str), args); @@ -3387,19 +3386,19 @@ typename buffer_context::type::iterator internal::vformat_to( template , FMT_ENABLE_IF(internal::is_string::value)> -inline typename buffer_context::type::iterator vformat_to( +inline typename buffer_context::iterator vformat_to( internal::buffer& buf, const S& format_str, - basic_format_args::type> args) { + basic_format_args> args) { return internal::vformat_to(buf, to_string_view(format_str), args); } template ::value, char_t>> -inline typename buffer_context::type::iterator format_to( +inline typename buffer_context::iterator format_to( basic_memory_buffer& buf, const S& format_str, const Args&... args) { internal::check_format_string(format_str); - using context = typename buffer_context::type; + using context = buffer_context; format_arg_store as{args...}; return internal::vformat_to(buf, to_string_view(format_str), basic_format_args(as)); @@ -3554,7 +3553,7 @@ inline format_to_n_result format_to_n(OutputIt out, std::size_t n, template inline std::basic_string internal::vformat( basic_string_view format_str, - basic_format_args::type> args) { + basic_format_args> args) { basic_memory_buffer buffer; internal::vformat_to(buffer, format_str, args); return fmt::to_string(buffer); diff --git a/include/fmt/locale.h b/include/fmt/locale.h index b6b4cf901c3e..f3e3d6762191 100644 --- a/include/fmt/locale.h +++ b/include/fmt/locale.h @@ -15,19 +15,19 @@ FMT_BEGIN_NAMESPACE namespace internal { template -typename buffer_context::type::iterator vformat_to( +typename buffer_context::iterator vformat_to( const std::locale& loc, buffer& buf, basic_string_view format_str, - basic_format_args::type> args) { + basic_format_args> args) { typedef back_insert_range> range; return vformat_to>(buf, to_string_view(format_str), args, internal::locale_ref(loc)); } template -std::basic_string vformat( - const std::locale& loc, basic_string_view format_str, - basic_format_args::type> args) { +std::basic_string vformat(const std::locale& loc, + basic_string_view format_str, + basic_format_args> args) { basic_memory_buffer buffer; internal::vformat_to(loc, buffer, format_str, args); return fmt::to_string(buffer); @@ -37,7 +37,7 @@ std::basic_string vformat( template > inline std::basic_string vformat( const std::locale& loc, const S& format_str, - basic_format_args::type> args) { + basic_format_args> args) { return internal::vformat(loc, to_string_view(format_str), args); } diff --git a/include/fmt/ostream.h b/include/fmt/ostream.h index 0399108f148d..4c2acf4ae96a 100644 --- a/include/fmt/ostream.h +++ b/include/fmt/ostream.h @@ -121,7 +121,7 @@ struct convert_to_int< template void vprint(std::basic_ostream& os, basic_string_view format_str, - basic_format_args::type> args) { + basic_format_args> args) { basic_memory_buffer buffer; internal::vformat_to(buffer, format_str, args); internal::write(os, buffer); diff --git a/include/fmt/prepare.h b/include/fmt/prepare.h index 7f4ff082b9da..9b30b5d6b760 100644 --- a/include/fmt/prepare.h +++ b/include/fmt/prepare.h @@ -239,14 +239,14 @@ class prepared_format { } template - inline typename buffer_context::type::iterator format_to( + inline typename buffer_context::iterator format_to( basic_memory_buffer& buf, const Args&... args) const { typedef back_insert_range> range; return this->vformat_to(range(buf), make_args_checked(format_, args...)); } private: - typedef typename buffer_context::type context; + typedef buffer_context context; template typename context::iterator vformat_to(Range out, diff --git a/test/format b/test/format index 3aca2f34aff5..3f9f2f928b6b 100644 --- a/test/format +++ b/test/format @@ -643,8 +643,7 @@ struct formatter { FMT_CONSTEXPR typename ParseContext::iterator parse(ParseContext& ctx) { namespace internal = fmt::internal; typedef internal::dynamic_specs_handler handler_type; - auto type = - internal::get_type::type, T>::value; + auto type = internal::get_type, T>::value; internal::specs_checker handler(handler_type(specs_, ctx), type); auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);