Compare commits

...

3920 Commits

Author SHA1 Message Date
c43fe02f66 Rewrites for esp-idf 2023-11-14 15:11:05 +01:00
f5e54359df Update version 2023-08-26 08:20:41 -07:00
a003ab93cf Update changelog 2023-08-26 08:18:55 -07:00
9b74160817 atomic_flag formatting (#3594) 2023-08-25 08:06:10 -07:00
a21690bdfa Coding conventions 2023-08-25 07:46:32 -07:00
c9efd8968c Merge branch 'MathewBensonCode-master' 2023-08-25 07:44:44 -07:00
e786824053 Refactor Improvement on umul128 function
- Removal of direct access to members of uint128_fallback and instead
  create the values at the callsite and pass them via the constructor of
  uint128_fallback on the return statement.
2023-08-25 13:21:52 +03:00
2b20d7be6f Refactor To remove friend function private access
- Remove umul128 friend function from uint128_fallback class using
  non-const member access functions instead.
2023-08-24 00:55:43 +03:00
1f38ebbdb1 Add condition to include friend function in win32 2023-08-22 23:07:04 +03:00
e418179694 Fix for FMT_MODULE not compiling on GCC 2023-08-22 21:11:53 +03:00
0bffed8957 Bump actions/checkout from 3.1.0 to 3.5.3 (#3602)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.5.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.1.0...c85c95e3d7251135ab7dc9ce3241c5835cc595a9)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-21 10:58:34 -07:00
cc077a5e3b Fix FMT_NO_UNIQUE_ADDRESS warning with clang-cl. (#3600)
See https://reviews.llvm.org/D110485 for info.
2023-08-20 10:21:50 -07:00
a992b3d1fc Fix for Compilation Error When Using FMT_MODULE (#3597)
* FMT_EXPORT reorganization to fix compile error

- When compiling with FMT_MODULE, an error was being generated due to
  use of FMT_EXPORT on a declaration within FMT_BEGIN_EXPORT and
  FMT_END_EXPORT on `include/core.h`

- On `include/format.h` had to exclude the function vformat_to by ending
  the export block just before it and beginning a new one after it.
2023-08-20 07:32:36 -07:00
af1b768cc7 Update changelog 2023-08-19 08:22:50 -07:00
2a7c45b54e Update changelog 2023-08-19 08:19:01 -07:00
bd868f3a51 Improve compatibility with GBK #3598 (#3599) 2023-08-19 08:13:20 -07:00
bbb784fb1b Fix a gcc error about partial specialization after instantiation 2023-08-19 07:22:40 -07:00
6c845f57e5 Fix formatted_size with FMT_COMPILE and format specs (#3588)
Addresses issue #3586
2023-08-15 06:45:48 -07:00
a379595c5f Bump actions/upload-artifact from 3.1.0 to 3.1.2 (#3593)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3.1.0...0b7f8abb1508181956e8e162db84b466c27e18ce)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 14:02:10 -07:00
9dfde78714 Bump ossf/scorecard-action from 2.1.2 to 2.2.0 (#3592)
Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.1.2 to 2.2.0.
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](e38b1902ae...08b4669551)

---
updated-dependencies:
- dependency-name: ossf/scorecard-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 13:43:25 -07:00
e92a705bdc Bump github/codeql-action from 2.2.4 to 2.21.4 (#3591)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.2.4 to 2.21.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](17573ee1cc...a09933a12a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-14 11:49:24 -07:00
5a866fe852 Add formatter for std::atomic (#3574) 2023-08-14 08:34:31 -07:00
e150ea0cc2 to_string supports types with format_as
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-08-13 08:39:52 -07:00
29ce2ff8a8 Update README.rst
Signed-off-by: Joyce <joycebrum@google.com>
2023-08-13 07:32:33 -07:00
2e1362addb Create scorecard.yml
Signed-off-by: Joyce <joycebrum@google.com>
2023-08-13 07:32:33 -07:00
e57ca2e368 Update version 2023-08-12 07:18:59 -07:00
4c56612c67 Update changelog 2023-08-12 07:18:12 -07:00
e1acd5f4d9 Bump version 2023-08-12 06:52:15 -07:00
6ffee2f752 Handle new rst nodes 2023-08-12 06:51:40 -07:00
ee475d6409 Update changelog 2023-08-07 15:12:34 -07:00
ecc9141259 Update changelog 2023-08-07 14:41:53 -07:00
d424862319 Fix fixed precision handling during rounding in long double 2023-08-07 13:56:53 -07:00
3c1b3337de Update changelog 2023-08-07 11:39:30 -07:00
35fb69ebe0 Update changelog 2023-08-07 10:30:52 -07:00
f92be35c09 Update changelog 2023-08-07 09:44:43 -07:00
7a2f6ac210 Fix a comment 2023-08-07 09:33:45 -07:00
744ff55549 Fix docs 2023-08-07 08:40:41 -07:00
70ae48b005 Update changelog 2023-08-07 08:38:17 -07:00
ebb10347c4 Merge branch 'master' of github.com:fmtlib/fmt 2023-08-07 08:18:13 -07:00
1005720169 Clarify that visit_format_arg is deprecated 2023-08-07 08:17:55 -07:00
aeb6ad4dd0 Added formatter for bit_reference-like types (#3570)
* Add test for std::vector<bool>::reference

Co-authored-by: Felix <felix-antoine.constantin@polymtl.ca>
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

* Add test for std::bitset<N>::reference

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

* Add test for const std::bitset<N>::reference and const std::vector<bool>::reference

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

* Add bit_reference-like formatter

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

* Use std::addressof

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

---------

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
Co-authored-by: Felix <felix-antoine.constantin@polymtl.ca>
2023-08-06 11:36:30 -07:00
96d1fa22d4 Update changelog 2023-08-05 10:00:27 -07:00
8a4bec5cf5 fix ambiguous formatter lookup for flat_set (#3561) 2023-07-31 09:26:33 -07:00
eacd51c249 cmake: fix FMT_PKGCONFIG_DIR path (#3563) 2023-07-31 08:11:56 -07:00
757564f5cd add missing inline specifier (#3552) 2023-07-27 12:12:00 -07:00
f4214ae8dd Use the U literal for unsigned integer constants. (#3549)
Fix MSVC Error C2398 Element '1': conversion from 'int' to 'const uint32_t' requires a narrowing conversion.
2023-07-27 11:43:00 -07:00
aecf80d304 Update a comment 2023-07-26 15:10:12 -07:00
503d49286d expose detail::throw_format_error (#3551)
This enables to only #include <fmt/core.h> when defining formatters.
2023-07-26 13:21:38 -07:00
4f46cb82f3 Remove std::copy usage. (#3550) 2023-07-26 07:27:01 -07:00
3dec65b7fd Use replacement character in path 2023-07-22 09:07:28 -07:00
dbabb305c3 Turn off error-producing NVCC workaround when using c++20 (#3544) 2023-07-21 11:29:15 -07:00
ac0ab8eff3 Improve path formatter 2023-07-20 17:49:12 -07:00
40f35d6f04 Cleanup std formatters 2023-07-20 16:26:27 -07:00
31c2c5679e Cleanup formatters 2023-07-20 15:57:43 -07:00
b2728a3170 Improve path formatter 2023-07-20 15:25:35 -07:00
77e0b0e228 Cleanup chrono formatter 2023-07-20 15:00:59 -07:00
e475859042 Fix overspecified tests 2023-07-20 14:09:22 -07:00
436c131d4c Optimize compiled format_to_n 2023-07-20 12:35:01 -07:00
388bc296b7 Fix fixed formatting of small long doubles 2023-07-20 12:06:05 -07:00
95e1ea5737 Clarify requirement on compiled formatter 2023-07-20 10:24:02 -07:00
fb97cb2318 Suppress a bogus stringop-overflow warning 2023-07-20 09:53:54 -07:00
dd5a9691f9 Clarify that data is not null-terminated 2023-07-20 07:36:30 -07:00
72dc4491ea Fix format_string_checker initialisation order (#3542)
Linter (clang-tidy) complains about uninitialised fields in
format_string_checker since types_ is passed to context_ before being
initialised. Fixes #3541.
2023-07-20 07:30:45 -07:00
9bea6ec04a Don't use deprecated checked_array_iterator 2023-07-20 07:12:06 -07:00
661b23edeb Call parse on empty specs at compile time 2023-07-15 22:20:29 -07:00
8e87d3a8be Fix include 2023-07-15 09:02:19 -07:00
a474916560 Update CMakeLists.txt (#3523) 2023-07-05 06:38:38 -07:00
de4705f84d Trying to improve errors in the unformattable case (#3478) 2023-07-01 06:46:04 -07:00
e4c8cfe38e README: Add link to merged clang-tidy check (#3515)
A much-improved version of the main clang-tidy-fmt check for converting
printf and fprintf has landed in upstream LLVM. It converts to
std::print by default, but can be configured to convert to fmt::print
instead. It makes more sense for the README to point to that version
instead now.
2023-06-30 15:49:36 -07:00
606f85f8b2 Workaround brain-damaged conversions 2023-06-26 16:06:24 -07:00
a331dbfb65 Fix type in assert message. (#3508)
Reviewed all strings in the file and found no other typos.
2023-06-26 11:35:29 -07:00
13156e54bf Revert "add ability to build Apple framework using CMAKE_FRAMEWORK" (#3496)
This reverts commit ae25f7968e.

Co-authored-by: Petr Manek <1252039-petrmanek@users.noreply.gitlab.com>
2023-06-18 20:41:07 -07:00
9158bea1e1 Remove old grisu tests 2023-06-18 18:15:09 +03:00
dd17f89a16 Fix for issue #3492 (#3493)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-06-16 02:20:40 -07:00
1daae555b3 Optimize format string compilation 2023-06-15 10:28:23 +03:00
6ad301235f Optimize code unit output in compiled format 2023-06-14 21:13:26 +03:00
8732ad8773 Update docs 2023-06-13 19:24:18 +03:00
5afb1821a9 Update docs 2023-06-13 18:58:15 +03:00
a81135f2c8 Fix a link 2023-06-13 18:39:00 +03:00
dfc34821ad Update docs 2023-06-13 18:33:36 +03:00
0765e7284c Update docs 2023-06-13 18:12:27 +03:00
977d887a4e Suppress a bogus warning 2023-06-13 14:01:46 +03:00
c86fe0b8d3 Give basic_memory_buffer allocator [[no_unique_address]] (#3485)
This allows stateless allocators to take up no space while still avoiding the empty base class optimization.
2023-06-13 01:22:19 -07:00
5dbe0ff954 Bump actions/checkout from 3.5.2 to 3.5.3 (#3486)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8e5e7e5ab8...c85c95e3d7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-12 22:46:54 -07:00
de0757b578 Use FMT_TRY and FMT_CATCH in std.h (#3482)
This naked try-catch block prevents compilation when exceptions are disabled.
2023-06-10 21:28:13 -07:00
8fe893c0ac Update README.rst 2023-06-06 19:56:53 -07:00
0f823df46a Remove detail namespace hack 2023-06-04 15:19:50 -07:00
60fd9941c0 Use correct Char type in std::filesystem::path (#3476)
Godbolt repro:
https://godbolt.org/z/o4bjG6ddo

Co-authored-by: Hans-Martin B. Jensen <haje@eposaudio.com>
2023-06-02 14:12:57 -07:00
8abfc145be Fix MSVC warning in std::chrono::time_point formatter (#3475)
* Fix MSVC warning in std::chrono::time_point formatter

The condition is constexpr causing MSVC level 4 warning:
warning C4127: conditional expression is constant

Changed the code to eliminate the warning

* Use detail::const_check

* Review: revert else condition

---------

Co-authored-by: Hans-Martin B. Jensen <haje@eposaudio.com>
2023-06-02 08:40:34 -07:00
686b3353aa Simplify typeid check 2023-06-01 09:32:44 -07:00
b2106f3639 Tweak comments 2023-05-31 09:52:44 -07:00
35547d6003 Use const_check to silence MSVC warning
The condition is constexpr, so the compiler warns if a runtime check
is used as there's no need to generate code for it.
2023-05-31 09:25:53 -07:00
179c7e5a66 Use typeid() only if it's available
On MSVC it is always available, otherwise it depends on whether
RTTI is enabled.
2023-05-31 09:25:53 -07:00
61fb3a15ff Add VxWorks7 user space and kernel space support (#3467) 2023-05-31 06:35:07 -07:00
bd393456ed Remove FMT_*_DETAIL_NAMESPACE 2023-05-28 07:33:26 -07:00
6be36af0d4 Remove udl_formatter 2023-05-27 17:16:36 -07:00
2a35eeed8a Remove unused data 2023-05-27 10:47:17 -07:00
256a826d63 Consolidate formatters 2023-05-27 09:19:50 -07:00
6369af37d3 Simplify formatters 2023-05-27 09:19:50 -07:00
0b8404918e Remove get_cached_power 2023-05-27 09:19:50 -07:00
171a020c82 Pass correct Char to base format_as formatter (#3457) 2023-05-24 14:50:47 -07:00
d8f04e3995 Simplify ceil 2023-05-24 11:51:34 -07:00
5e988f8dfa Remove is_constant_evaluated() check
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-24 09:07:12 -07:00
19b17618a9 Make constexpr ceil
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-24 09:07:12 -07:00
c684a06d51 New CI: macOS 13, Xcode 14.3, C++ 20
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-24 09:07:12 -07:00
abdb7fdf88 Update api.rst 2023-05-24 06:30:48 -07:00
8b09fe2a0a Fix example for user-defined types in documentation for 10.0.0 (#3461)
* Fix example for user-defined types in documentation for 10.0.0

* Fix the fix
2023-05-24 06:25:51 -07:00
adad18a74d Update ChangeLog.rst 2023-05-23 12:46:26 -07:00
858e528abd Use dragon in constexpr 2023-05-23 06:30:09 -07:00
a54cb108d4 CMake: Do not fail on unknown compiler features (#3453)
If CMake does not know much about a compiler, `target_compile_features` will fail. Issue a warning instead.
2023-05-22 14:17:32 -07:00
ef55d4f52e Suppress a bogus gcc warning 2023-05-22 11:27:20 -07:00
70b6a6fa44 Update README.rst (#3454)
Fixed grammar and punctuation issues.
2023-05-22 10:35:24 -07:00
6fe895410d Remove invalid_arg_index 2023-05-21 19:57:17 -07:00
d0652d225f Create dependabot.yml (#3452)
Signed-off-by: Joyce <joycebrum@google.com>
2023-05-21 06:41:30 -07:00
de8d0171a2 Simplify FMT_FORMAT_AS 2023-05-20 18:28:01 -07:00
7401fe046a Hash pin Github Workflows (#3451)
* hash pin doc.yml

Signed-off-by: Joyce <joycebrum@google.com>

* hash pin linux.yml

Signed-off-by: Joyce <joycebrum@google.com>

* hash pin macos.yml

Signed-off-by: Joyce <joycebrum@google.com>

* hash pin windows.yml

Signed-off-by: Joyce <joycebrum@google.com>

* hash pin github owned cifuzz.yml

Signed-off-by: Joyce <joycebrum@google.com>

---------

Signed-off-by: Joyce <joycebrum@google.com>
2023-05-20 06:33:37 -07:00
08ef0d0842 fix formatter<char*> (#3432) 2023-05-20 06:32:21 -07:00
d60b907f87 Replace mod_inv_25 by explicit value (#3450) 2023-05-18 11:26:19 -07:00
4ce086f731 remove code duplication (#3448)
* remove code duplication

* new interface for remove_trailing_zeros(uint32_t& n, int s = 0)

---------

Co-authored-by: Florimond Collette <4939681+florimondcollette@users.noreply.github.com>
2023-05-18 08:27:57 -07:00
821f8cdb45 Detemplatize printf more 2023-05-17 12:34:12 -07:00
0bf6ed7e1d Cleanup printf 2023-05-17 10:53:25 -07:00
e40e04face Detemplatize printf_arg_formatter 2023-05-17 10:05:46 -07:00
0a1c27281a Detemplatize basic_printf_context 2023-05-17 09:29:20 -07:00
2f605cc896 Deprecate wide printf 2023-05-17 08:58:55 -07:00
1d54499ac0 Apply coding conventions 2023-05-17 08:21:13 -07:00
3c6053c535 Cleanup basic_printf_context 2023-05-17 07:57:53 -07:00
4a392adaa7 Remove basic_printf_parse_context 2023-05-17 07:47:42 -07:00
b14913fae5 FMT_MODULE_EXPORT -> FMT_EXPORT 2023-05-17 07:38:06 -07:00
2117df299c format-inl.h: address implicit int to bool conversion (#3446) 2023-05-17 06:39:20 -07:00
616a493786 Revert Char* formatter removal 2023-05-17 06:11:11 -07:00
9a034b0d55 Always assert in FMT_THROW (#3439) 2023-05-17 06:04:36 -07:00
e0fc0e85e3 Remove unneeded FMT_API 2023-05-16 17:25:20 -07:00
552c43aba9 Improve long formatters 2023-05-14 07:07:36 -07:00
d6846f4ac8 Clarify why byte formatter is in core 2023-05-13 08:04:53 -07:00
aeedac5884 Remove unneeded specialization 2023-05-13 07:46:47 -07:00
eaa6307691 Make hex float test more stable (#3434)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-13 06:34:33 -07:00
e82bf41a1a Update README.rst 2023-05-12 16:24:47 -07:00
e077396f5a Update docs 2023-05-12 16:10:38 -07:00
861facad0a Fix a typo 2023-05-12 16:08:55 -07:00
75bfe57614 Improve docs 2023-05-12 12:57:01 -07:00
697e76ba30 Don't call init_named_args unnecessarily 2023-05-12 11:53:22 -07:00
a425e0ff3b Cleanup xchar API 2023-05-12 07:05:14 -07:00
c36dd825ba Remove unnecessary forwarding 2023-05-12 06:45:49 -07:00
130b8fcdb9 Reduce template instantiations 2023-05-11 20:18:34 -07:00
a47e8419be Cleanup the core API 2023-05-11 19:07:56 -07:00
ea49c91cd1 Cleanup argument construction 2023-05-11 18:43:39 -07:00
d7592ad8bf Fix time_point formatting for durations with certain ratios (#3430)
* Fix time_point formatting

* Add timestamps_ratios tests
2023-05-11 15:25:21 -07:00
ebfb2e6779 Remove unused alias 2023-05-11 10:51:32 -07:00
5780269d57 Improve API safety 2023-05-11 10:19:56 -07:00
b471192160 Fix a comment 2023-05-11 09:39:53 -07:00
8f18e72df5 Improve API safety 2023-05-11 06:32:58 -07:00
93d7cb12f1 Fix formatting 2023-05-10 16:29:47 -07:00
0e4278717b Remove unused macro 2023-05-10 16:27:16 -07:00
93a30a0746 unicode_to_utf8 -> to_utf8 since both sides of conversion are Unicode 2023-05-10 16:26:02 -07:00
a08196b149 Update ChangeLog.rst 2023-05-10 09:49:39 -07:00
0398ba42ca Update ChangeLog.rst 2023-05-10 09:39:04 -07:00
a0b8a92e3d Update version 2023-05-09 15:55:39 -07:00
5cf2342aa2 Bump version 2023-05-09 15:37:01 -07:00
fe9d39d7cb Update changelog 2023-05-09 14:27:48 -07:00
4c98561979 Update changelog 2023-05-09 14:25:56 -07:00
403b271ed7 Update changelog 2023-05-09 14:20:59 -07:00
2c991e1af6 Update changelog 2023-05-08 14:43:16 -07:00
c984df9815 Remove an unused function from internal class 2023-05-08 13:35:23 -07:00
fbf21ed224 Update changelog 2023-05-08 13:34:29 -07:00
575583144e Update changelog 2023-05-08 11:37:33 -07:00
e7f6888c7a Update changelog 2023-05-08 09:49:39 -07:00
39db2dfd06 Update changelog 2023-05-08 09:41:57 -07:00
9b7829e264 Update changelog 2023-05-08 09:15:07 -07:00
1e0ce567ef Fix formatting of paths containing invalid Unicode 2023-05-07 10:05:15 -07:00
dde8cf3bb7 Unification utf16/utf32 to utf8 conversion
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-06 08:32:51 -07:00
e84b00e014 Workaround to error: variable 'n' set but not used [-Werror,-Wunused-but-set-variable]
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-05-06 08:32:51 -07:00
b12ffea4fb Add filesystem_error test back 2023-05-06 07:49:46 -07:00
f61f15cc5b Suppress a false positive in gcc 2023-05-06 06:54:30 -07:00
192df93d7b modules missing pieces (#3399)
- don't export names from `detail`
- put more headers into the global module fragment
- support MSYS2 and Clang
2023-05-05 10:21:18 -07:00
d8973bf16b Add FMT_STRING for format_to() call (#3413) 2023-05-03 07:58:40 -07:00
d7a8e50cb5 Improve module testing (#3397)
* use the standard `test-main.cc` component instead of injected test infrastructure sources
 * undo now obsolete commit `00235d8a` from July 2021
 * Clang cannot import user-defined literals as it seems -> disable test
 * Clang emits duplicate, non-mergeable copies of `detail::buffer`'s vtable, causing linker errors -> disable test
2023-05-03 07:56:24 -07:00
02cae7e48a Improve handling of Unicode in paths 2023-04-30 09:58:59 -07:00
53162142b2 Remove .bazelrc mention from Bazel related readme (#3411) 2023-04-29 16:25:00 -07:00
5bcf0d7f97 Bazel support (#3406)
* Bazel support: Remove not needed .bazelrc file

* Bump tested Bazel version

* Apply buildifier to format Bazel build files

* Add note about Bzlmod
2023-04-29 07:45:49 -07:00
f8c9fabd94 Fix spelling (#3404) 2023-04-25 11:47:37 -07:00
62ff4e1dbd Remove foonathan from maintainer list (#3402) 2023-04-23 13:35:05 -07:00
f449ca0525 Name vfprintf clashes with the identically named declaration in 'stdio.h' if that happens to be #included into the same TU. Fix this by using qualified name lookup instead of unqualified lookup that also enables ADL. (#3400) 2023-04-23 07:10:57 -07:00
eafcd3c8e1 Optionally attach declarations to the global module rather than module fmt (#3387)
This allows coexistence with TUs that use {fmt} through #include without duplicating declarations, definitions, linker symbols, and object code.
2023-04-23 06:04:36 -07:00
18154cc903 Simplify print 2023-04-22 14:03:40 -07:00
0de789cf29 Update changelog 2023-04-22 09:20:28 -07:00
c039389223 export names only once (#3392)
names declared to be exported at the point of introduction into a namespace *must not* be (re-)declared as exported later in the TU, e.g. when they are redeclared, defined, or specialized. [module.export]/6

Drive-by fix found during module testing: add a missing `detail::` name qualification
2023-04-22 06:21:06 -07:00
93e81bb5d8 Fix C4365 (signed/unsigned mismatch) warning on 32-bit Windows (#3398) 2023-04-20 17:36:05 -07:00
e7d6eb6794 Update tests to use recommended MOCK_METHOD (#3395) 2023-04-20 13:16:21 -07:00
18e7a2532b Remove obsolete msvc workarounds (#3388)
This bug in the modules implementation is fixed since at least msvc 19.34, possibly even earlier like 19.32.
2023-04-19 17:09:51 -07:00
0489c19dcb fix and improve module (#3386)
* export public documented API
* don't export `namespace detail`
* add `std.h` into module
* add missing namespace qualification in `xchar.h`
* fix call to `detail::get_iterator` in `xchar.h`
* fix ambiguous overload of `detail::isfinite` in `chrono.h`
2023-04-18 06:47:01 -07:00
8ec94ac6a5 Use full path to pcm 2023-04-14 11:57:17 -07:00
d97d8cea67 Push module check to test 2023-04-14 11:42:01 -07:00
d8a2698e6c Fix compilation as a C++20 module with gcc 13 2023-04-14 09:49:07 -07:00
d9c19940a3 Update add_module_library 2023-04-13 17:13:52 -07:00
4b5ae0b0ef Remove unnecessary module support check 2023-04-13 16:53:45 -07:00
75f3b1c094 Use add_module_library 2023-04-12 09:10:34 -07:00
faf83406a9 Workaround cmake issue 2023-04-11 15:59:08 -07:00
165814d57a Add module support to CMake 2023-04-11 14:38:34 -07:00
33f7150778 Fix error C2668 on msvc (#3378) 2023-04-11 06:27:28 -07:00
c98e5a08a4 Fix modular build on clang 2023-04-10 12:07:25 -07:00
119c6bd16f Move the modules check 2023-04-10 09:28:00 -07:00
77eeb71830 Remove unused headers 2023-04-10 09:08:19 -07:00
13bf99f9db Enable modules in clang 16 2023-04-10 08:44:43 -07:00
1d0257e4c0 FMT_MODULE_EXPORT_* -> FMT_EXPORT_* 2023-04-10 08:33:39 -07:00
4613d48fd3 FMT_EXPORT -> FMT_LIB_EXPORT 2023-04-10 08:24:23 -07:00
4a4a2a2bd6 Fix diagnostics 2023-04-09 09:30:20 -07:00
fce74caa15 Disable problematic implicit conversions 2023-04-09 09:08:46 -07:00
02bf4d1c1c Disable to_string_view ADL 2023-04-09 08:49:05 -07:00
466e0650ec Remove problematic workaround 2023-04-09 08:04:11 -07:00
029caa8ea2 Update changelog 2023-04-09 07:01:06 -07:00
e406ddbfaf Remove broken part of the config 2023-04-08 08:46:43 -07:00
9095679536 Update changelog 2023-04-08 08:39:17 -07:00
7f46cb75b8 ranges: Fix extra semi (#3374) 2023-04-06 08:31:07 -07:00
4e3f381058 Update changelog 2023-04-02 07:13:42 -07:00
d3c10f5167 fix compilation for MSDOS (#3369) 2023-04-01 13:40:53 -07:00
ab956f600f Update changelog 2023-04-01 08:04:47 -07:00
97aedeab48 Workaround a double-double hexfloat format (#3366)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-04-01 07:19:23 -07:00
bce8d4ed08 Remove stray comment 2023-03-27 11:04:00 -07:00
a91c7b286d Cleanup the core API 2023-03-26 21:07:26 -07:00
19c074e477 Remove deprecated fallback formatter 2023-03-26 08:45:06 -07:00
41cfc739fe Generalize format_as 2023-03-26 07:37:51 -07:00
f6276a2c2b Force use a signed char (On ARM char is unsigned by default) (#3362)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-03-22 11:34:59 -07:00
6002ddf825 Remove a deprecated option 2023-03-19 12:17:43 -07:00
6549ffde8e Improve format_as safety 2023-03-19 12:09:54 -07:00
d9bc5f1320 Fix code causing spurious Wstringop-overflow warning
See #2989, #3054, and others
2023-03-18 09:29:54 -07:00
9c5cd998d1 Remove unused functions 2023-03-18 08:40:16 -07:00
93bfa05382 %T is %H:%M:%S (#3349) 2023-03-18 07:16:22 -07:00
d8e1c4265a fix case of variant which is valueless by exception (#3347)
Co-authored-by: theomegacarrot <theomegacarrot@gmail.com>
2023-03-18 07:07:06 -07:00
e1720c0e51 Fix CUDA nvcc warning fmt/include/fmt/core.h(295): warning #1675-D: unrecognized GCC pragma (#3352) 2023-03-17 11:35:35 -07:00
7f882918eb write_floating_seconds: Fall back to ::round (#3343)
On some toolchains, `std::round` is not available.

Fixes #3342
2023-03-12 09:34:19 -07:00
cbc7b8d5c1 Cleanup dead variable (#3338) 2023-03-10 09:17:43 -08:00
050293646f Path is not escaped twice in the debug mode (#3321)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-03-05 08:01:06 -08:00
3daf33837c Enable consteval for Xcode 14.0.1 and later (#3331)
Co-authored-by: Cloyce D. Spradling <cloyce_spradling@apple.com>
2023-03-04 09:22:43 -08:00
e0748e61dd Fix recursion check in range formatting 2023-03-04 08:20:32 -08:00
b94e1016fa chore: set permission to cifuzz.yml (#3328)
Signed-off-by: Joyce <joycebrum@google.com>
2023-03-01 07:58:59 -08:00
98699719f8 Make # handling consistent with std::format 2023-02-26 10:15:16 -08:00
48dfbcaa95 Improve license and PR template wording 2023-02-26 09:08:53 -08:00
c644c753d7 Add '🐙 userver framework' to the projects 2023-02-26 08:42:55 -08:00
73b7cee7fb Fix for issue #3325 (#3326)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-02-26 06:59:41 -08:00
5b8302079d Add optional support (#3303) 2023-02-25 06:45:56 -08:00
3a69529e8b Fix various typos (#3312)
Found via `codespell -q 3 -S ./test/gtest -L "fo,pres,seh,wronly"`
2023-02-21 15:14:41 -08:00
76f520835f Call element parse in tuple parse 2023-02-20 12:54:20 -08:00
507c3042d8 class -> typename 2023-02-18 10:23:42 -08:00
1741e90dec Always call parse in range formatter 2023-02-18 09:58:37 -08:00
d646fd0daf Minor cleanup 2023-02-16 11:21:08 -08:00
b5c2f74f45 change sopen_s to wsopen_s (fmtlib#3234) (#3293) 2023-02-16 11:17:55 -08:00
e03753c4ac Add ubuntu mirrors (#3302)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-02-12 07:46:50 -08:00
6e6eb63770 [msvc] fix warning about non-inline variable 2023-02-11 09:45:13 -08:00
3c5464ba1c Fix OpenBSD build error (#3295) 2023-02-11 08:46:28 -08:00
655046d24f Fix container adaptor formatting 2023-02-10 09:45:37 -08:00
581c6292c9 Add formatters for container adapters (#3279) 2023-02-08 17:25:41 -08:00
7718eeeacc Implement glibc ext for sec, min, and hour (#3271) 2023-02-08 09:22:58 -08:00
44e0eea94e Use FMT_HAS_INCLUDE and apply clang-format 2023-02-08 07:19:10 -08:00
99070899b7 Fix errors setting of FMT_USE_FLOAT128 (#3259) 2023-02-08 07:15:02 -08:00
05e3a9233a Allowing formatting non-copyable ranges. (#3290) 2023-01-27 12:29:57 -08:00
70db193f09 Visual Studio 2022: fmt/format-inl.h(1145,60): warning C4310: cast truncates constant value #3287 (#3288) 2023-01-26 11:46:30 -08:00
a2c05a10ec Workaround a bug in MSVC <= 19.22 2023-01-25 10:34:28 +13:00
cae9bf45b9 Simplify apidoc comments 2023-01-25 09:32:03 +13:00
87c066a35b Implement println (#3267) 2023-01-24 12:30:00 -08:00
9409b2e4d8 Workaround for incompatibility between libstdc++ consteval-based std::is_constant_evaluated() implementation and clang-14 (#3281)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2023-01-22 11:29:34 -08:00
f89cd276f7 Refactor countl_zero fallback (#3276) 2023-01-17 15:04:34 -08:00
240b728d81 Report an error on overflow 2023-01-18 11:52:33 +13:00
dfbb952b2c Fix empty spec for time point (#3275) 2023-01-16 11:48:00 -08:00
39971eb336 Fix localized format for float-point numbers (#3272) 2023-01-15 11:47:24 -08:00
0f42c17d85 Implement a new formatting algorithm for small given precision (#3269)
Implement the formatting algorithm for small given precision discussed in https://github.com/fmtlib/fmt/issues/3262 and https://github.com/fmtlib/fmt/pull/2750
2023-01-14 11:30:20 -08:00
bfc0924eac Bugfix for fmt::printf on Power9 architecture with the XL compiler (#3256) 2023-01-13 11:36:00 -08:00
676c2a107e Fix negative subsec for time_point (#3261) 2023-01-11 11:36:50 -08:00
2c80cedc39 Fix standard default installation target presence (#3264) 2023-01-10 17:56:00 -08:00
dda53082be Support fill, align & width for time point (#3260) 2023-01-09 11:25:31 -08:00
2622cd23e6 Simplify arg_mapper 2023-01-03 16:35:21 -08:00
9e4a54fa6e Disable remaining implicit conversions 2023-01-03 12:08:42 -08:00
9ce6480676 Disble deprecated implicit enum conversions 2023-01-03 10:24:31 -08:00
9121f9b1d3 Enable format_as for classes 2023-01-03 08:58:23 -08:00
b7535365b2 Enable format_as for non-integral types 2023-01-02 13:37:13 -08:00
09ed1ddb9c Cleanup tests 2023-01-02 09:58:12 -08:00
0ec65d99aa Merge parse_presentation_type into parse_format_specs 2023-01-02 09:19:32 -08:00
71e4e02722 Cleanup vprintf 2023-01-02 08:37:00 -08:00
aad546baa5 Simplify presentation type parsing 2023-01-01 16:14:17 -08:00
14a69fcc54 Use parse_align 2023-01-01 10:44:55 -08:00
bf34ffd33f Refactor format string parsing 2023-01-01 10:21:47 -08:00
6056e07125 Simplify symbols 2022-12-30 19:35:05 -08:00
aa99b86409 Minor cleanup 2022-12-30 18:51:15 -08:00
6ade2eb4e5 Inline all_int_set 2022-12-30 17:05:08 -08:00
caa6974942 Simplify parse functions 2022-12-30 16:34:36 -08:00
a73a9b6a84 Refactor format string checks 2022-12-30 16:03:41 -08:00
72785a3aba Cleanup write 2022-12-30 13:53:55 -08:00
0c3dd5ddd7 Remove redundant check 2022-12-30 12:55:19 -08:00
739b600f40 Remove iterator shenanigans 2022-12-30 12:37:22 -08:00
3710c4d38f Link to dragonbox 2022-12-30 12:07:55 -08:00
a05ba44df8 Simplify format string parsing 2022-12-30 11:23:42 -08:00
ffb9b1d13c Improve handling of signed types 2022-12-30 10:31:39 -08:00
32190859ec Fix handling of char 2022-12-30 09:11:42 -08:00
8fe4d97d5e Reduce template instantiations 2022-12-30 08:44:23 -08:00
7e5a959564 Fix build with MSVC C++20 modules (#3254)
When using fmt with C++20 modules under MSVC, it can end up requiring certain things to have storage that would not otherwise have needed to. Since I didn't see anything that was already doing detection for `inline constexpr` variable support, I've just moved the entire thing into the only function where it's used.
2022-12-28 19:58:57 -08:00
9e60304869 Clarify that unused args are allowed 2022-12-28 06:58:04 -08:00
7ad48c1f65 Cleanup core.h 2022-12-26 09:14:15 -08:00
a921a596e7 Cleanup core.h 2022-12-26 07:46:31 -08:00
3e762fdf5c Use ignore_unused 2022-12-26 06:57:21 -08:00
79981a2528 Cleanup ranges formatting 2022-12-25 20:05:20 -08:00
bd12aaa98e Simplify format string parsing 2022-12-25 12:31:38 -08:00
b8f36207c9 Simplify format string parsing 2022-12-25 11:47:43 -08:00
d907786f04 Move anchor to where it belongs 2022-12-25 10:58:54 -08:00
f2355bbe5e Fix docs 2022-12-25 10:25:35 -08:00
f398c94761 Fix docs 2022-12-25 10:24:36 -08:00
4841784e82 Simplify C99 strftime detection conditions
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-25 10:16:19 -08:00
cb72c23e9e Improve timezone tests
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-25 10:16:19 -08:00
583f2d8209 Set timezone for chrono tests
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-25 10:16:19 -08:00
32c4390704 Minor cleanup 2022-12-25 08:59:25 -08:00
3a5e19fbf5 Minor cleanup 2022-12-25 08:42:16 -08:00
dfb857ebef Refactor format spec parsing 2022-12-25 07:25:32 -08:00
9ea9b6bcb1 Cleanup arg id parsing 2022-12-24 16:33:57 -08:00
2b0ff62a7f Remove unused template arg from format_string_checker 2022-12-24 15:46:34 -08:00
d1745084e0 Simplify parse context 2022-12-24 15:20:24 -08:00
407e7b7b6d basic_format_specs -> format_specs 2022-12-24 14:34:50 -08:00
3cf9794755 Cleanup format string parsing 2022-12-24 13:47:20 -08:00
934c8e5f76 Refactor precision parsing 2022-12-24 13:29:23 -08:00
fc96938345 Remove empty semicolon 2022-12-24 09:54:55 -08:00
f0ab112c34 Cleanup parsing 2022-12-24 09:40:35 -08:00
9660e5b956 Remove redundant tests 2022-12-24 07:28:13 -08:00
a585571e90 Ignore 0 character with align 2022-12-23 19:36:05 -08:00
840ec8569d Cleanup width handlers 2022-12-23 19:18:35 -08:00
1dadeb8a33 Refactor width parsing 2022-12-23 18:29:59 -08:00
275b4b3417 Remove obsolete parse-benchmark 2022-12-23 12:50:08 -08:00
e004f1d699 Fix for issue #3241
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-23 12:26:20 -08:00
bde1a6070d Simplify fill and alignment parsing 2022-12-23 10:52:56 -08:00
040dc2a5d4 small typo in syntax.rst
0x1e was misread as 0x13, it looks like
2022-12-23 10:29:14 -08:00
6a186bcd66 Localize FMT_USE_LOCAL_TIME 2022-12-21 14:52:52 -08:00
8c56919bd2 Check chrono spec starts with % 2022-12-21 14:40:30 -08:00
115001a3b1 Formatting of system clocks ought to be to UTC, not to local time.
This improves standards conformance of fmt.
2022-12-21 14:23:02 -08:00
b90895412f Fix formatting of named arguments with locale 2022-12-15 09:59:40 -08:00
d072f1dc69 Fix for issue #3228
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-14 13:49:36 -08:00
3999fd193a Workaround an ADL issue 2022-12-11 09:32:17 -08:00
c06e0b4ede Extract timezone offset from timezone conversion functions
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-10 10:13:53 -08:00
1bf302a4ea Implement %Ez, %Oz for chrono formatter
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-12-10 10:13:53 -08:00
f1733afd49 Pin godbolt example to specific version 2022-12-10 09:35:55 -08:00
f61dcccc6e Update README.rst 2022-12-06 11:52:37 -08:00
f9bcbdcbcf Update README.rst 2022-12-06 11:51:59 -08:00
1a854b4aa5 Clarify what mod_inv_5 is 2022-12-04 08:36:03 -08:00
62ceb181b1 fix #3105 - Compile-time error when mixing named argument with automatic indexing 2022-12-04 08:13:26 -08:00
b0c8263cb2 include/fmt/core.h: copy constructors removal 2022-11-30 16:44:42 -08:00
d24be2e95c Add countl_zero function
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-30 12:25:01 -08:00
8d50d814db Fix a chrono formatting issue found by fuzzing 2022-11-30 11:04:51 -08:00
115ca96e0e Bump tested CMake version to 3.25
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-30 08:09:32 -08:00
886491625d Remove workaround for GTest bug
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-30 07:16:37 -08:00
74c51ff37e Skip only strptime dependent test in scan-test
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-27 08:59:30 -08:00
69ffedfe52 Use target_compile_features to specify C++ standard requirement 2022-11-26 11:03:17 -08:00
fae6f7e081 Optimize range formatter 2022-11-26 08:50:46 -08:00
a69e43c9d7 Update benchmark results 2022-11-25 09:52:02 -08:00
91c024ed33 Rename leading_v -> leading_xdigit
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-25 09:08:40 -08:00
649aa102d6 CI linux: add CIFuzz Github action
Signed-off-by: David Korczynski <david@adalogics.com>
2022-11-24 08:22:51 -08:00
31364732dc Replace snprintf-based hex float formatter with internal implementation
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-24 07:15:46 -08:00
74d55a4938 Add missing operators
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-24 07:15:46 -08:00
8276f1a204 Fix warning: the implicit by-copy capture of "this" is deprecated (EDG frontend)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-22 10:51:00 -08:00
81ebe70b9b Fix warning: a class type that is not trivially copyable passed through ellipsis (EDG frontend)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-22 10:51:00 -08:00
3160847ebd Enable C++17 tests on macOS
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-18 08:22:07 -08:00
6a95f8c7eb Add missing env CTEST_OUTPUT_ON_FAILURE
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-18 08:22:07 -08:00
c7980542d3 Skip the scan-test if strptime isn't defined (#3184)
cygwin and embedded systems. By default newlib doesn't provide strptime
in time.h because it was added in a later X/Open versions. Issue: #3178
2022-11-16 09:42:01 -08:00
7df30f91ae Format unique_ptr with custom deleter (#3177)
* Format unique_ptr with custom deleter

Added deleter type to fmt::ptr unique_ptr overload. Deleter type is
part of the unique_ptr type.

* Review: apply clang-format

Co-authored-by: Hans-Martin B. Jensen <haje@eposaudio.com>
2022-11-13 21:54:32 -08:00
d2e89c8b08 Document more chrono specs 2022-11-08 19:35:34 -10:00
bd19593204 Document more chrono specs 2022-11-08 16:22:23 -10:00
fd0d0ec8df Document more chrono specs 2022-11-08 14:57:57 -10:00
8e93434edd Update README.rst 2022-11-08 11:21:16 -08:00
fc07217d85 Make utf-8 detection compatible with gbk 2022-11-02 15:42:47 -07:00
cb7373b469 Replace format with FMT_STRING. (#3162)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-11-02 13:17:16 -07:00
795ed8abf5 Add precision modifier for seconds in chrono format (#3148)
Co-authored-by: Stepan Ponomarev <stepan.ponomarev@itiviti.com>
2022-11-02 11:58:51 -07:00
66d71a1b35 Fixing formatting of range of range of char. (#3158) 2022-11-02 11:04:54 -07:00
80f8d34427 fmt::ostream - aggregate buffer instead of inheriting it (#3139)
Some MSVC-specific behavior:
When class fmt::ostream inherits detail::buffer - the last gets implicitly exported when fmt is built as a shared library.
Unless os.h is included, the compiler assumes detail::buffer is not externally exported and instantiates a local copy of it, which causes ODR violation.
With aggregation - there is no extra exporting of detail::buffer symbols.
2022-10-23 07:21:36 -07:00
64965bdc96 Add locale getter in tm_writer (#3147)
* Add locale getter in tm_writer

* Apply clang-format

Co-authored-by: Stepan Ponomarev <stepan.ponomarev@itiviti.com>
2022-10-20 10:22:03 -07:00
e1ffa7655d Fix warning: conditional expression is constant. (#3150)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-20 07:49:53 -07:00
8c19bf3f2f Mention MariaDB amongst the projects that use fmt (#3145) 2022-10-17 13:33:05 -07:00
f67dbc9811 Remove duplicate implementation (#3144)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-17 11:15:28 -07:00
cd7202e039 Fix overflow error (#3143)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-16 14:04:55 -07:00
51d3685efe Remove duplicate template parameter. (#3142)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-14 16:34:24 -07:00
9254cfa6f0 Support formatting of subseconds (#3115)
* Timestamp formatting shall print also subseconds, fixed a bug for fractional durations
2022-10-12 14:33:53 -07:00
cfb34a0607 Avoid using uint as a type name (#3137)
Sometime `uint` is defined as a global type by the project's code directly or by some 3rdparty libraries (e.g. Qt or OpenCV).
Some versions of MSVC (e.g. v16.11.15) gives a type shadowing warning:
```
3rdparty\fmtlib\fmt\include\fmt/format.h(3251): warning C4459: declaration of 'uint' hides global declaration
opencv2/core/hal/interface.h(45): note: see declaration of 'uint'
```
This also causes a compilation failure when `/WX` is used.
2022-10-12 10:53:47 -07:00
5ad7b71381 Fix options for C++20 experimental module in CMake (#3134)
* Fix options for C++20 experimental module in CMake

* Replace `FMT_CAN_MODULE` by `FMT_MODULE` in test/CMakeLists.txt
2022-10-12 08:23:12 -07:00
d2c47c0df2 Fix broken condition (#3129)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-07 13:46:45 -07:00
491c32cbd9 Workaround gcc bug 103879 2022-10-05 21:12:38 -07:00
662adf4f33 Move formatter<std::error_code> from fmt/os.h to fmt/std.h (#3125)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-10-01 17:46:09 -07:00
ad91cab374 Normalization of stdlib inline namespace names (#3119)
* Normalization of stdlib inline namespace names

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

* Remove all subnamespaces with names matching "__*" mask

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-29 09:52:38 -07:00
0ccaed3a6c Set CMAKE_RUNTIME_OUTPUT_DIRECTORY relative to CMAKE_CURRENT_BINARY_DIR instead of CMAKE_BINARY_DIR (#3120)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-28 16:51:23 -07:00
ad719619cc Support formatting of std time_point with utc_clock (#3110) 2022-09-28 07:31:53 -07:00
6e0a5f7fba Update CI to Ubuntu 20.04 and to newer versions of actions 2022-09-27 15:06:12 -07:00
48f525d025 Add basic_format_string::get() 2022-09-22 19:50:04 -07:00
0b5cb18b71 Use buffering in to_string to avoid bloat 2022-09-21 17:11:43 -07:00
4c4f99a583 Update a godbolt link 2022-09-21 12:05:57 -07:00
3272a7a3ce Update an example 2022-09-21 12:03:18 -07:00
a48e3355a6 Improve docs 2022-09-18 08:44:04 -07:00
afcf424294 Update docs 2022-09-16 15:27:18 -07:00
ac85afaab6 Simplify format_error 2022-09-16 14:25:14 -07:00
3178bb9a26 Update docs 2022-09-16 10:29:53 -07:00
cf58f64c54 Update docs 2022-09-16 10:28:00 -07:00
e4e0ae3918 Use fmt/core.h in examples 2022-09-15 20:41:32 -07:00
d65acc4e6c Improve docs 2022-09-14 10:59:50 -07:00
c9f790b061 Update docs 2022-09-14 10:58:52 -07:00
6b8144a5ac Update locale docs 2022-09-14 06:38:29 -07:00
2d66ad5d33 Suppress -Wshadow
Solves:
/fmt/include/fmt/ostream.h:89:18: warning: declaration of 'fbuf' shadows a previous local [-Wshadow]
   89 |   else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
      |                  ^~~~
C:/GIT/ok-mimot/libs/3rdParty/fmt/include/fmt/ostream.h:87:13: note: shadowed declaration is here
   87 |   if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
      |             ^~~~
2022-09-13 11:14:30 -07:00
042af53324 Suppress -Wfloat-equal
Only NaN and Inf are not less than Inf and the check for NaN is done
before.

Solves:
.../fmt/include/fmt/format.h:2509:43: warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]
 2509 |     return !detail::isnan(value) && value != inf && value != -inf;
2022-09-13 11:14:30 -07:00
192859c2b5 Optimize writing to buffers via back_insert_iterator 2022-09-12 15:32:12 -07:00
e2f6d7665b fix gcc <= 7.1 compile errors 2022-09-12 10:43:16 -07:00
61844b6b67 Fix build error on GCC-9
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-12 07:02:29 -07:00
7a752e75ff New CI: GCC-9
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-12 07:02:29 -07:00
94ceb38a09 Improve locale API 2022-09-11 09:33:31 -07:00
58c4c012fa Disable slow windows build and simplify write_loc 2022-09-11 08:35:09 -07:00
c3494ae364 Refactor float localization 2022-09-11 07:47:27 -07:00
8ae56161c8 Fix compilation with FMT_ENFORCE_COMPILE_STRING and FMT_WERROR (#3091) 2022-09-10 18:05:10 -07:00
76705fc2ee Update doc 2022-09-10 15:06:09 -07:00
21c2137e77 Add class name output to formatter for std::exception (#3076)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-10 08:04:00 -07:00
ecffca6726 Don't parse '}' as fill 2022-09-07 17:33:31 -07:00
3176e0fad7 Add locale overload for formatted_size (#3084) (#3087)
Co-authored-by: Gerbo Engels <gerbo.engels@ortec-finance.com>
2022-09-07 14:15:12 -07:00
1feb430faa Fix intellisense on Windows (#3082)
__INTELLISENSE__ is 1 on vs2022 and clang, causing FMT_HAS_INCLUDE, FMT_USE_FCNTL, etc to be 0.
That results in VS and VSCode having a lot of linter errors while code compiles just fine.
2022-09-05 11:50:06 -07:00
b98ffb7dbd Improve locale handling 2022-09-04 21:07:30 -07:00
bac53951b8 Add starts_with to basic_string_view. (#3080)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-04 11:41:16 -07:00
d59b89e9cd More locale 2022-09-04 11:23:45 -07:00
58a5563a9f Implement grouping 2022-09-04 09:01:26 -07:00
1b94271ff6 Add support for UTF-8 digit separators 2022-09-03 11:01:05 -07:00
768d79a839 Implement format_facet 2022-09-03 09:42:36 -07:00
91ecb38a34 Localize negative integers 2022-09-03 07:01:11 -07:00
aec3bb5d0a Workaround C complex.h idiocy 2022-09-03 06:35:55 -07:00
29c6000137 Simplify is_variant_like_ check, fix compile error before GCC 11 (#3072)
Co-authored-by: Vladislav Shchapov <vladislav@shchapov.ru>

Co-authored-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-02 21:08:07 -07:00
fec5515c55 num_format_facet -> format_facet 2022-09-02 18:55:08 -07:00
f187274d36 Add loc_value 2022-09-02 13:45:23 -07:00
fc5e59fe4a Don't use stringstream 2022-09-02 13:05:26 -07:00
d6a8704605 Improve locale support 2022-09-02 11:52:19 -07:00
56c72a671c Reduce locale dependency 2022-09-02 10:22:11 -07:00
4191477b98 Add formatter for std::exception (#3062)
Co-authored-by: fekir <federico.kircheis@gmail.com>
Co-authored-by: Alexey Ochapov <alexez@alexez.com>
Co-authored-by: Vladislav Shchapov <vladislav@shchapov.ru>

Co-authored-by: fekir <federico.kircheis@gmail.com>
Co-authored-by: Alexey Ochapov <alexez@alexez.com>
Co-authored-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-09-02 08:33:37 -07:00
75383a87f9 Inline trivial functions 2022-09-01 18:25:23 -07:00
48327a82e3 Make format.h compile faster 2022-09-01 17:06:47 -07:00
b79ed4105a Remove unnecessary type_identity 2022-09-01 16:29:08 -07:00
64e29893cf Improve locale support 2022-09-01 14:48:43 -07:00
0b0f7cfbfc hip workaround 2022-09-01 09:18:53 -07:00
40e414d823 Fix compilation error with gcc-7.2.0
Without the added line, the gcc-7.2.0 compiler will give the following error:
```
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:1240:8: error: uninitialized variable 'buffer' in 'constexpr' function
   Char buffer[digits10<UInt>() + 1];
        ^~~~~~
```
See https://godbolt.org/z/fh7TMs9qs
2022-08-30 10:55:57 -07:00
33b4c33c5b Requires FMT_CONSTEXPR20 support
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-29 13:33:48 -07:00
a07411c2b9 Disable compile-time checks for dynamic width/precision test for LCC and compiler without std::is_constant_evaluated()
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-29 13:33:48 -07:00
797d82b21a Disable non-type template args for LCC
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-29 13:33:48 -07:00
a553521d6d Disable "GCC optimize" pragma for LCC
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-29 13:33:48 -07:00
a33701196a Update version 2022-08-27 08:57:10 -07:00
1f575fd5c9 Bump version 2022-08-27 08:55:39 -07:00
c7635288f7 Fix docs, take 2 2022-08-27 08:28:07 -07:00
c8ed78e315 Fix docs 2022-08-27 08:01:47 -07:00
e07cfb2068 Update changelog 2022-08-27 07:55:06 -07:00
1dc7af5693 Fix markup 2022-08-27 07:52:58 -07:00
f7d21c3a1a Update changelog 2022-08-27 07:51:24 -07:00
a55bcb24bd Update changelog 2022-08-27 07:13:36 -07:00
30cb2b3122 Remove appveyor config 2022-08-27 06:52:25 -07:00
cf8d3c3229 Update changelog 2022-08-26 16:17:42 -07:00
3c3cb6f6b1 Update changelog 2022-08-26 16:00:24 -07:00
91481f255c Detemplatize code_point_length_impl 2022-08-26 15:45:00 -07:00
f98048b621 Fix bugs in utf8 decoder (#3056)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-26 15:37:15 -07:00
4a8e2949bb Fix formatting of ranges of code unit types
Thanks Nicole Mazzuca.
2022-08-26 13:48:58 -07:00
3a3b0709e2 Disable bogus -Wstringop-overflow on GCC 11 (#3054)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-24 12:37:34 -07:00
e724bbea16 Fix wchar_t corner cases 2022-08-24 12:23:10 -07:00
665d9779ec Disable non-type template args for nvhpc (#3053) 2022-08-24 10:56:45 -07:00
13d07c6a3d Apply doc fixes retroactively 2022-08-24 09:16:12 -07:00
391f922acc Improve error reporting in format string compilation 2022-08-24 09:05:15 -07:00
dc59d3df3f Fix a warning in gtest 2022-08-24 07:18:14 -07:00
489dabbd31 Fix decoder on broken utf8 sequences. (#3044)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-24 07:13:27 -07:00
541cd21838 Fix locale name (thanks Mikhail Paulyshka) 2022-08-20 08:06:20 -07:00
1f95c34381 Fix sign handling with large code units 2022-08-20 07:46:58 -07:00
779449fd99 Belarusify test 2022-08-20 07:37:15 -07:00
fbb568bce0 nvhpc/22.3: workaround for c++17 mode. (#3043) 2022-08-18 11:30:40 -07:00
36c23bd5fd Prepare for deprecating FindPythonInterp module. (#3040)
* Prepare for deprecating FindPythonInterp module.

Since FindPythonInterp module is deprecated after CMake 3.12, it is better to start using the new FindPython module.

* Add the proper punctuation in comments.
2022-08-17 14:18:39 -07:00
9ff0f3a7d6 Fix docs 2022-08-16 11:31:11 -07:00
fd41110d38 Add MinGW to CI 2022-08-14 08:40:38 -07:00
fc23cfbf4e Fix testsuite on MinGW + MSVCRT
Fixes #2952. The testsuite indirectly called strftime() with conversion
specifiers defined only in C99. In MSVCRT this function conforms only to
C89. Only in the updated UCRT this functon provides the functionality of
C99.
2022-08-14 08:40:38 -07:00
fd93b633b8 Constexpr formatted_size (#3026)
* Constexpr formatted_size

* Add C++20 tests for gcc 9 and 10

* Adjust unit test to require __cpp_lib_bit_cast
2022-08-10 09:35:30 -07:00
7fb8d33f9d Fix compile-time width/precision type check 2022-08-09 16:10:02 -07:00
8bd02e93b2 Reduce conditional compilation 2022-08-09 09:05:01 -07:00
d9c1c7353a Use is_utf8() in print(std::ostream&, ...)
This patch concludes the Unicode support for print(ostream&, ...)
2022-08-09 09:05:01 -07:00
682e097bee Remove -Wl,--as-needed linker option
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-07 06:51:41 -07:00
b9087ee587 Suppress unused typedef warning 2022-08-05 15:27:01 -07:00
df56fdf883 Clarify docs for compile-time checks 2022-08-05 07:00:34 -07:00
90c48b8525 Remove double code execution
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
5a8b7cd742 Add comment
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
36a25d75b4 Reuse detail::string_literal in the chrono formatter
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
6c9304b2c2 Replace ParseContext with basic_format_parse_context
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
24ab9dd19e Remove duplicate method
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
a95dc17017 Remove unused condition
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-05 06:15:59 -07:00
5f774c0aed I shouldn't be there 2022-08-02 16:35:50 -07:00
6567df7f24 Update README.rst 2022-08-02 06:50:09 -07:00
6c6b1fbf6e Workaround a bug in MSVC
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-08-02 06:46:02 -07:00
9beddd08f9 Improve CI on Windows 2022-08-02 06:46:02 -07:00
6452e3c9eb Fix a typo in example 2022-08-02 06:26:19 -07:00
756822ba39 Fix Unicode handling for ostream under Windows with libc++. (#3001)
Also replaces the SFIANE tricks applied in
ce7ecdb7af with conditional compilation.
The code was too complicated along with the other trick to access private
data members.
2022-07-30 06:49:21 -07:00
0b2862a1e4 Range formatter (#2983)
* Implement range_formatter and format_kind

* Attempted gcc 4.8 fix

* gcc 4.8 interprets inaccessible as a hard error (instead of... not available)

* Attempting to delete set_debug_format.

* clang-format

* Different implementation of FMT_STATICALLY_WIDEN

* Renaming copy_str_range to copy_str.

* I guess I need a definition

* Forgot to delete these.

* Other PR comments.
2022-07-29 13:55:16 -07:00
258000064d Add fmt:: namespace to doc (#3009)
Otherwise as-is the example does not compile on Visual Studio due to the conflict with std::format_to: 
https://gcc.godbolt.org/z/qe4jEvvqY
2022-07-29 13:10:09 -07:00
e9ca7ea472 Suppress a bogus warning 2022-07-28 07:12:49 -07:00
81f1cc74a7 Improve Unicode handling when writing to an ostream on Windows (#2994)
* Refactor detail::print() by splitting into two functions.

The part with SetConsoleW is a separate function, without fwrite().

* Make Unicode handing when writing to std::ostream more robust.

Calls to print(ostream&) in the special Unicode case on Windows fallback
to writing via ostream::write instead of fwrite().

* Fix Unicode handling when writing to an ostream on GCC on Windows

* Add TODO note about detail::is_utf8()

* Fix warning -Wundef

* Fix for non-Windows OSs

* Fix building as DLL on Windows

* Refactor

* Suppress warning
2022-07-23 08:03:31 -07:00
bbcb129e02 Reduce filesize of the tests on MinGW (#2995)
This patch removes the workaround applied here
1acfd07f1e.
MinGW is not tested on Appveyor anymore.
2022-07-22 20:11:33 -07:00
48e0a59222 Implement compile-time checks for dynamic width/precision type 2022-07-22 17:00:40 -07:00
bc5c7c50fd Fixes IBM XLC behavior with uint128 fallback (#2985)
* Fixes IBM XLC behavior with uint128 fallback

* Replace legacy xlc with clang-based xlc

* simplify xlc intrinsics handling

Co-authored-by: Federico Busato <fbusato@nvidia.com>
2022-07-22 13:49:17 -07:00
00adc7120d Add a regression test for here be dragons 2022-07-22 11:08:00 -07:00
c48be439f1 Add additional search paths for doxygen on Windows
`find_program(DOXYGEN doxygen)` didn't find the executable automatically even if I installed Doxygen on Windows. Therefore, I added some additional search paths.
2022-07-19 08:59:18 -07:00
371f9c71ca Fix even in format_dragon 2022-07-19 08:36:34 -07:00
91abfcd6cf Suppress an msvc warning 2022-07-16 08:57:09 -07:00
deeab54b40 Remove unused include 2022-07-15 20:11:35 -07:00
688a627d6c Remove unused constants. 2022-07-14 15:25:35 -07:00
9bb1605f10 Remove some branches 2022-07-14 15:25:35 -07:00
8061d9afbe Simplify Dragonbox implementation 2022-07-14 15:25:35 -07:00
d82e1a108d Make sure the correct fmod overload is called 2022-07-13 12:42:03 -07:00
defa04e730 Fix for EDG frontend (Intel, NVHPC compilers) (#2982)
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-13 11:34:43 -07:00
92d36e82c4 The n specifier for ranges (#2981)
* The n specifier for ranges.

* Flipping flag polarity.
2022-07-12 10:08:38 -07:00
0db43cf7fe Pointless comparison warnings (#2971)
Co-authored-by: Federico Busato <fbusato@nvidia.com>
2022-07-11 12:29:39 -07:00
05be7a0764 Use FMT_USE_FLOAT128 instead of __SIZEOF_FLOAT128__ 2022-07-10 08:54:34 -07:00
2a1b3ac629 Fix large shift in uint128_fallback 2022-07-10 08:27:21 -07:00
e1d3d3a326 Exclude recursive ranges from the formatter specialization for ranges (#2974)
* 2954: Add test case

* Eliminate extra-test and merge it into existing std-test instead. Add conditionals for filesystem::path testing that does not run into the ambiguity problem.

* #2968: Introduce additional compile-time predicate to detect recursive ranges and reject them in formatter specialization for ranges. In addition, introduce additional wrapper traits for the individual logical operands of the complete range constraints

* #2968: Eliminate preprocessor condition that enables the formatter specialization for std::filesystem::path

* #2968: Eliminate preprocessor condition that enables the test for the formatter specialization for std::filesystem::path

* Use own bool_constant, which is available for all C++ versions

* Reintroduce previous workaround but restrict to VS 2015 for now

* Comma fix

* - Rename is_not_recursive_range to is_nonrecursive_range and add comment that explains it being depending on is_range being true
- Merge has_fallback_formatter_delayed into is_formattable_delayed and add comment that explains it being depending on is_not_recursive_range being true
- Replace disjunction in formatter specialization by has_fallback_formatter_delayed
- Get rid of unneeded detail:: prefixes within namespace detail
2022-07-10 06:26:23 -07:00
b761f1279e Improve forward using the idea from Jonathan Müller 2022-07-07 16:48:17 -07:00
cc1926942f Inline std::forward 2022-07-07 14:41:54 -07:00
d5e9166f54 Fixed typo in changelog example. 2022-07-05 19:07:39 -07:00
b31d1a75a0 Add xchar support for fmt::streamed().
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-05 19:07:06 -07:00
c4ee726532 Update version 2022-07-04 09:50:06 -07:00
fa2eb2d2e3 Bump version 2022-07-04 09:37:29 -07:00
35f72bf210 Bump version 2022-07-04 09:10:55 -07:00
d22f00d7e4 Update changelog 2022-07-04 09:01:56 -07:00
4e8d215606 Update changelog 2022-07-04 08:56:18 -07:00
84eecb6561 Prune CI configs 2022-07-04 08:51:35 -07:00
55727e3b21 More compile-time checks 2022-07-04 08:25:27 -07:00
1010b7f148 Update docs 2022-07-04 08:18:44 -07:00
2ac51fc448 Update changelog 2022-07-04 08:13:27 -07:00
831132293b Workaround for Microsoft Visual Studio 2022 Internal compiler error.
D:\a\fmt\fmt\test\compile-test.cc(362,3): fatal error C1001: Internal compiler error. [D:\a\fmt\build\test\compile-test.vcxproj]
(compiler file 'D:\a\_work\1\s\src\vctools\Compiler\CxxFE\sl\p1\c\constexpr\constexpr.cpp', line 8635)

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-04 07:18:21 -07:00
115e00e0b9 Replace __cplusplus with FMT_CPLUSPLUS.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-04 07:18:21 -07:00
94114b05ca New CI: Microsoft Visual Studio 2022.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-04 07:18:21 -07:00
d2a2320820 Fix partial specialization problem for filesystem for Visual Studio (#2957)
* #2954: Provide std::conjunction and std::disjunction substitutes

* #2954: Use conjunction and disjunction substitute to make formatter specializations for ranges and maps more robust (especially for Visual Studio compiler family)

* #2954: As workaround for older MSVC compilers split formatter<std::filesystem::path> partial template specialization into two explicit specialization.

* 2954: Add test case

* Provide simplified implementations of conjunction and disjunction

* Remove workaround explicit specializations if the partial specialization would cause an ambiguity error

* Eliminate extra-test and merge it into existing std-test instead. Add conditionals for filesystem::path testing that does not run into the ambiguity problem.
2022-07-03 11:06:54 -07:00
0c06c81da8 Deprecated implicit conversion of enums to ints for consistency with scoped enums 2022-07-03 09:02:22 -07:00
c12b4c0cf1 New CI: GCC-8 C++17, Clang-8 C++17.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-02 08:34:52 -07:00
99bb5b1d17 Fix std::variant, std::filesystem::path tests on GCC-8, Clang-7,8.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-07-02 08:34:52 -07:00
e29c2bc60e Update docs 2022-06-30 08:13:34 -07:00
c65e4286bf Update changelog 2022-06-29 09:02:08 -07:00
69c24e47e8 Update changelog 2022-06-28 11:00:56 -07:00
6a775e9560 Add support for 'std::variant' in C++17 (#2941)
Add support for 'std::variant' in C++17.

For C++17, if all the alternatives of a variant are formattable
the variant is now also formattable. In addition 'std::monostate'
is now formattable.

Moves implementation into 'std.h', and tests into 'std-test.cc'.

Avoid fold-expression since MSVC was crashing.

Add section for 'fmt/std.h' in API-docs.
2022-06-26 07:28:01 -07:00
51535866d0 Update docs 2022-06-25 09:13:29 -07:00
3ef5caa9fe Update docs 2022-06-25 09:11:10 -07:00
dccd3e6742 Fix docs 2022-06-25 09:04:31 -07:00
9cb02aaaad Fix UDLs 2022-06-25 08:52:10 -07:00
e6d478f8e8 Update changelog and docs 2022-06-25 08:33:57 -07:00
2d931b1497 Add fmt::streamed 2022-06-24 09:26:24 -07:00
0506a5733d Update changelog 2022-06-24 09:04:56 -07:00
e8bd2a804d Fix enable_ifs for map formatter (#2944) 2022-06-23 08:24:11 -07:00
7c56e11ecf Update changelog 2022-06-23 07:40:56 -07:00
69a20db081 Update changelog and fix an apidoc comment 2022-06-22 08:32:46 -07:00
7a2a97c882 Update changelog 2022-06-22 07:31:34 -07:00
5682338891 Fix is_formattable for tuple-like types. (#2940) 2022-06-19 08:25:58 -07:00
f0de128449 Remove /source-charset:utf-8 compile option.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-06-19 07:37:39 -07:00
eaa8efb950 Fix ofstream handling in msvc 2022-06-16 15:02:33 -07:00
fb991e9d3b Update changelog 2022-06-12 12:17:39 -07:00
8e47cfd1cd fix -Wsign-conversion warning 2022-06-11 12:31:33 -07:00
2471875867 Make the tests pass on a CHERI system. 2022-06-10 07:02:03 -07:00
b135f1c014 Refactor handling of argument types 2022-06-09 17:03:33 -07:00
f61a1e8132 Add format_arg_types 2022-06-09 15:50:30 -07:00
48b7e3dafb Added a FMT_STRING wrapper for system_error() call.
This enables the use of FMT_ENFORCE_COMPILE_STRING on MSVC 2019.
2022-06-07 07:00:57 -07:00
4bb3af7a6b Improve compile-time checks 2022-06-05 13:58:04 -07:00
d02c582b96 Fix 'duplicate symbol' error.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-06-05 07:17:25 -07:00
b59d8c3a23 Make std::filesystem::path formatter utf-8 compatible.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-06-04 10:10:21 -07:00
232e21d51f Add utf-8 test for std::filesystem::path formatter.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-06-04 10:10:21 -07:00
8644654190 Docs: add comment about empty format context range 2022-06-02 08:40:29 -07:00
ba50c19e82 use qualified call to avoid ADL conflict with std::format_to 2022-06-01 15:57:15 -07:00
9d60395953 Fix compilation on ppc64 2022-05-31 13:53:15 -07:00
a2681aabcb Debug ppc failure 2022-05-31 11:30:22 -07:00
bfc5767368 Add support for std.h in Bazel build 2022-05-30 16:52:25 -07:00
798d09bb70 Debug ppc failure 2022-05-30 13:06:34 -07:00
8c7cf51395 Cleanup 2022-05-30 08:21:01 -07:00
cdfacb4345 Cleanup parse_format_string 2022-05-30 07:30:11 -07:00
926ddd0631 Move compile string to detail 2022-05-30 07:06:36 -07:00
cb682f36f4 Move to_string_view to detail 2022-05-29 22:51:31 -07:00
156744ad47 Simplify fmt::runtime 2022-05-29 21:18:52 -07:00
d9c7166cf0 bi_iterator -> base 2022-05-29 21:01:57 -07:00
11316b29af chore: Set permissions for GitHub actions
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.

- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)

Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com>
2022-05-29 19:12:52 -07:00
fe6eb792d5 Cleanup check_format_string 2022-05-29 19:01:06 -07:00
054b1d9808 Remove unused include 2022-05-29 18:24:10 -07:00
e927149f8e Cleanup macros 2022-05-29 17:23:02 -07:00
1761e2666a Remove FMT_CONSTEXPR_DECL 2022-05-29 16:42:58 -07:00
d6b568a6cc Cleanup string_view checks 2022-05-29 16:30:39 -07:00
c83a5d42bb FMT_MSC_VER -> FMT_MSC_VERSION 2022-05-29 15:39:08 -07:00
27cd68c301 Cleanup macros 2022-05-29 14:45:59 -07:00
08be4abb30 Remove FMT_NVCOMPILER_VERSION 2022-05-29 13:54:31 -07:00
661b192545 Remove FMT_HEADER_ONLY_CONSTEXPR20 2022-05-29 13:22:45 -07:00
d1026fa5d2 Remove extern format_float 2022-05-29 13:11:19 -07:00
7e63b600b6 Make to_string work with __float128 2022-05-29 12:23:57 -07:00
b2ea212cd1 Update README.rst 2022-05-29 11:44:09 -07:00
c2fcdc54e2 Move format_float to format.h for __float128 2022-05-29 11:30:33 -07:00
2b9037a190 Move basic_fp to format.h for compile-time formatting 2022-05-29 07:32:52 -07:00
542785ccbf Get rid of detail::bits 2022-05-29 07:10:36 -07:00
65dd2ea52c Use write_escaped_string to std::filesystem::path.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-05-28 07:48:02 -07:00
9860f67cde Improve xchar support for std formatters.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-05-28 07:48:02 -07:00
03b1b2838e Improve std::filesystem::path formatter.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-05-28 07:48:02 -07:00
4f9311e689 Fix definition of error_handler::on_error 2022-05-27 10:49:19 -07:00
652fea45a9 Visual Studio 2022: fmt/format.h(1526,27): warning C4127: conditional expression is constant #2908 2022-05-27 10:38:13 -07:00
1f9eae7e31 Add xchar support for write_escaped_string.
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
2022-05-27 08:36:38 -07:00
90b68783ff Skip cmake targets inclusion if fmt::fmt already exists (#2907) 2022-05-27 08:35:40 -07:00
ce246aaf74 Remove deprecated APIs 2022-05-22 07:10:09 -07:00
edeb3d8091 Remove deprecated APIs 2022-05-21 19:57:38 -07:00
496aff7c33 Remove deprecated APIs 2022-05-21 15:12:38 -07:00
f5cdf7cb04 Simplify snprintf_float 2022-05-21 12:34:21 -07:00
440512f08d Remove deprecated APIs 2022-05-21 12:20:31 -07:00
621eb80bbb Remove deprecated APIs 2022-05-21 11:34:07 -07:00
5c7d315ded Remove locale.h 2022-05-21 08:19:09 -07:00
c6324009ba Add initial double-double support 2022-05-21 07:32:54 -07:00
147e8ca580 Fix Windows max mix-up (#2903) 2022-05-18 16:35:26 -07:00
6bf039d750 Add std:🧵:id formatter 2022-05-17 16:37:19 -07:00
9730fb0156 Fix path formatter 2022-05-17 14:29:49 -07:00
f0903ad9df Add a path formatter 2022-05-16 17:32:25 -07:00
8833f386e4 Merge branch 'master' of github.com:fmtlib/fmt 2022-05-15 09:51:38 -07:00
5ab9d39253 Namespace-qualify format_to to avoid conflict with std::format_to 2022-05-15 09:51:20 -07:00
af5644c274 Update README.rst 2022-05-15 06:29:15 -07:00
3e28dc021c VS2022 17.2: C4189: 'zero': local variable is initialized but not referenced #2891 (#2892)
VS2022 17.2: C4189: 'zero': local variable is initialized but not referenced #2891

Co-authored-by: Ivan Shynkarenka <Ivan_Shynkarenka@epam.com>
2022-05-13 07:04:34 -07:00
f6f920a1a8 Tweak a comment and apply clang-format 2022-05-11 14:40:26 -07:00
ae963e444f Implement constexpr isfinite to avoid producing NaN 2022-05-11 08:43:22 -07:00
358f5a7e50 Make precision computation consistent with width 2022-05-11 06:34:51 -07:00
f63afd161f Fixed all clang -Wsigned-enum-bitfield warnings (#2882)
Made enums involved in bitfields unsigned by specifying their underlying type as unsigned char.

Due to a bug, when specifying an underlying type, gcc < 9.3 warns about bitfields not being big enough to hold the enum, even though they are. So keep the plain enum for old gcc.

An example of the bug is here:

https://godbolt.org/z/58aEv8zEq
2022-05-09 11:03:51 -07:00
7e4ad40171 Add initial support for double-double 2022-04-24 07:43:02 -07:00
ffb5e6a732 Suppress a -Wliteral-range warning on Apple M1 (#2861) 2022-04-19 11:10:18 -07:00
5d804ee7fe Fix handling of subnormals in exotic FP 2022-04-17 08:56:35 -07:00
86e27ccb41 Suppress a warning 2022-04-12 09:30:29 -07:00
192f79aaae Fix handling of locale separators in FP formatting 2022-04-12 08:00:17 -07:00
395cf0f03e Fix detection of unformattable pointers 2022-04-12 06:45:46 -07:00
fc429d18b6 Avoid overhead on sensible platforms 2022-04-11 16:52:34 -07:00
ce7ecdb7af Replace conditional compilation with SFINAE 2022-04-11 12:16:05 -07:00
8751a03a04 Fix Unicode handling when writing to an ostream 2022-04-10 09:46:01 -07:00
c55175a589 Add an issue template 2022-04-08 07:53:42 -07:00
a935ac3e60 MSVC CMake generation optimization (#2852) 2022-04-08 06:27:23 -07:00
22d31b31f0 Add a __float128 test 2022-04-03 14:56:29 -07:00
f607e3e970 Add __float128 support 2022-04-03 12:58:06 -07:00
686de58886 Implement 128-bit constant mul in bigint 2022-04-03 07:24:18 -07:00
02eb215f2f Replace uint128_wrapper with uint128_fallback 2022-04-02 18:01:41 -07:00
b4dc7a1d34 Add 128-bit operations to bigint 2022-04-02 09:29:13 -07:00
ef54f9aa38 Suppress -Wfloat-equal 2022-04-01 12:18:22 -07:00
288c3b928b Remove dead code in ostream.h format_value 2022-03-29 10:21:19 -07:00
96930161f9 Implement 128-bit operator+= for uint128_fallback 2022-03-27 08:07:54 -07:00
b41890c1e5 Make arg_mapper SFINAE-friendly again 2022-03-27 07:10:15 -07:00
e2408f37c8 Check if formatter is not defined if there is format_as 2022-03-26 09:44:49 -07:00
db5b8993ac Fix formatting of std::byte via format_as 2022-03-26 09:01:30 -07:00
1c83eaf75e Fix incompatible between Jinja2 >= 3.1 and sphinx 3.3.0 2022-03-26 07:30:17 -07:00
5379063b54 Fixed clang -Wreserved-identifier warings
Created FMT_UNCHECKED_TYPE that resolves to special identifier _Unchecked_type for Microsoft, but to a dummy string otherwise. Using
_Unchecked_type is invalid because underscore + uppercase is a reserved identifier.
2022-03-24 07:33:43 -07:00
b591fc87dc Fixed all clang -Wreserved-id-macro warnings (on macOS at least)
Avoid defining various reserved identifiers (starting with underscore and capital letter).  Fortunately, they were all Windows-only, so it was easy to conditionalize them in Window-only preprocessor checks.
2022-03-24 07:33:43 -07:00
17dda58391 constexpr -> const for portability 2022-03-23 21:14:22 -07:00
7ffe87c0bc Fix docs 2022-03-22 19:13:01 -07:00
3c4273dd09 Simplify UDL 2022-03-22 17:43:37 -07:00
36d95c9fcc Fix docs 2022-03-22 17:31:31 -07:00
44abd1f483 Update signatures in docs and ostream.h 2022-03-22 16:05:30 -07:00
db745986f2 Workaround broken std::numeric_limits 2022-03-20 08:50:52 -07:00
8271e43e5e Improve __float128 support and use constexpr 2022-03-20 07:20:41 -07:00
3f9b7433a3 Improve __float128 support 2022-03-19 09:44:14 -07:00
71778e8b90 Specialize float_info for __float128 2022-03-19 08:39:16 -07:00
f024565c3f Improve exponent handling in Dragon 2022-03-19 08:23:32 -07:00
e7f31f5cdb Cleanup format_dragon 2022-03-18 16:03:19 -07:00
3c61799fbf Cleanup fuzzing mode 2022-03-18 12:01:52 -07:00
4e39e13085 Remove xchar.h include from ostream.h 2022-03-18 10:53:15 -07:00
ac0d9d5fe2 Issue #2816: also strip named-arg for the fallback formatter 2022-03-18 10:11:14 -07:00
4ad90578f7 Fix #2818: diagnose unformattable arguments in unpacked case 2022-03-18 10:11:14 -07:00
17ba99c1d2 Fix #2817: add compile-time checking to ostream overloads of fmt::print 2022-03-18 10:11:14 -07:00
3d19be282a Fix #2816: strip named argument wrappers for compile-time checking 2022-03-18 10:11:14 -07:00
c076a54a4d Move snprintf_float to format.h 2022-03-18 08:31:31 -07:00
0419d23882 Add FMT_USE_FLOAT128 2022-03-18 07:43:51 -07:00
cre
69396347af Update color.h (#2815)
fixed typo in comment
2022-03-17 10:55:02 -07:00
c51604a0e1 Reduce the number of configs 2022-03-15 18:20:59 -07:00
587dc9946d Remove windows-2016 env no longer suppported by GA 2022-03-15 18:16:13 -07:00
1f3d44b859 Update std::tm/chrono docs 2022-03-15 16:53:51 -07:00
bc654faf82 Add is_floating_point that works with __float128 2022-03-15 08:26:05 -07:00
26bffce66d Simplify basic_memory_buffer 2022-03-15 07:15:52 -07:00
ed18ca3eae Implement isnan 2022-03-14 20:37:46 -07:00
a204b8dde7 Add initial __float128 support 2022-03-14 19:34:41 -07:00
b6b003b073 Cleanup test 2022-03-14 15:48:38 -07:00
f2543b0a98 Add initial support for 128-bit floats 2022-03-14 14:00:15 -07:00
72f487562d Simplify float_info 2022-03-14 13:37:03 -07:00
f91f61cd13 Reuse num_significand_bits 2022-03-14 11:34:24 -07:00
9a1beab574 Workaround Windows API garbage 2022-03-11 17:31:39 -08:00
a8fe8becf4 Fix compilation error for ranges with ADL begin/end (#2807)
* Use `range_begin`/`end` to get formatted range iterators

* Add test for adl `begin`/`end`

* Apply clang-format

* Simplify tests
2022-03-11 11:36:39 -08:00
f6bcb25e16 Remove extra dot 2022-03-10 16:26:17 -08:00
b4a4189d0c Fix handling of implicit bit 2022-03-10 15:34:56 -08:00
32d477e5f1 Add styled in documentation (#2805) 2022-03-10 12:24:47 -08:00
0b7c045a2f Simplify _cf 2022-03-08 15:31:51 -08:00
c10fffecdc Make _cf visible in the doc build 2022-03-08 11:00:04 -08:00
dcfbe4a77a Document output_file default behavior correctly (#2803)
The documentation for output_file incorrectly says that opening an output file happens with `file::WRONLY | file::CREATE` by default, but this includes `file::TRUNC` is also included since 119f7dc3d.
2022-03-08 10:02:22 -08:00
8c9bc070f5 Implement styled arguments (#2793)
* Implement styled arguments

* Inherit from formatter<Arg> to get the underlying `parse` and `format`

* Move styled_arg definition into the previous detail block

* Change styled_arg ctor parameters names to avoid shadowing members

* Move const before auto

* Remove redundant constructor for styled_arg

* Use the iterator instead of the buffer in styled_arg::format

* Remove unnecessary `styled` overloads

* Remove defaulted text_style parameter in styled function
2022-03-08 09:50:14 -08:00
5bc39d363a Eliminate intel compiler warnings (#2802)
The intel compiler emits  `declaration hides parameter "loc" ..."  and similar warnings for "out" and "args" since the function arguments are the same as other visible symbols.  This is for intel-2021.3.0 20210609.
2022-03-07 15:34:33 -08:00
e3d688e79a Fix warning C4251: class fmt::v8::file needs to have dll-interface (#2797)
* Fix warning C4251: class fmt::v8::file needs to have dll-interface

* Add CMake target dependency between test-main and fmt
2022-03-07 12:09:48 -08:00
8d4f3e91b2 Update docs 2022-03-06 10:12:40 -08:00
0cef1f819e Fixing formatting of certain kinds of ranges of ranges. (#2787)
* Fixing formatting of certain kinds of ranges of ranges.

* Renaming const_range to range_type.
2022-03-04 16:21:00 -08:00
5c0d656401 Fix apt install 2022-03-03 15:50:25 -08:00
d416a995ea Update README.rst 2022-03-01 13:53:02 -08:00
3f67a12477 Update README.rst 2022-03-01 13:48:54 -08:00
cc57e35974 Update godbolt link in the readme (#2789) 2022-02-25 13:47:23 -08:00
86477f7ecc Fix size computation 2022-02-22 17:21:07 -08:00
0742606f19 Fix Conversion Warning (#2782)
With -Wconversion and 32 Bit I get a warning here with unsigned long
long converted to unsigned long.
2022-02-22 08:16:36 -08:00
1ba69fb5a1 Remove snprintf FP fallback 2022-02-21 08:01:55 -08:00
ea6f0bf0e5 Minor cleanup 2022-02-21 07:29:36 -08:00
1a18a2f3dd Fixing "C4127: conditional expression is constant" Visual Studio 2022 warning in pedantic mode (#2783) 2022-02-21 07:26:16 -08:00
4fcacea354 Parameterized fp on significand type 2022-02-21 07:25:13 -08:00
cf940ae82e Simplify to_decimal 2022-02-20 19:38:02 -08:00
70dc3de053 Update format.h
To prevent the following compiler message:
[...]/include/fmt/format.h:392:20: warning: conversion to 'long unsigned int' from 'int' may change the sign of the result [-Wsign-conversion]
  392 |     unsigned value[size];
      |                    ^~~~
2022-02-20 11:38:03 -08:00
cbc59ca893 Clear moved from memory buffer 2022-02-20 08:12:59 -08:00
ea3d326c63 Fix clang -Wliteral-range warning (#2779) 2022-02-19 10:52:33 -08:00
aad44f2839 Add fmt::enums::format_as 2022-02-19 08:03:42 -08:00
1319719a5e Add underlying_t 2022-02-19 07:57:43 -08:00
af5d8004fc Limit Dragonbox to supported FP formats 2022-02-19 07:14:18 -08:00
7b96420961 Remove unused include 2022-02-18 18:56:51 -08:00
a0b43bfae2 Add support for 96-bit long double 2022-02-18 18:01:49 -08:00
2c8cd2db34 Fix handling of zero precision 2022-02-18 12:38:30 -08:00
b6d56170fc Remove unnecessary inline 2022-02-18 07:41:55 -08:00
05432e570e Use consistent indentation 2022-02-18 07:38:42 -08:00
47da218cc3 Remove uintptr_fallback 2022-02-18 07:03:33 -08:00
4ddab8901c Merge accumulator into int128_fallback 2022-02-18 06:17:28 -08:00
d38f72aff2 Refactor fallback ints 2022-02-17 20:24:42 -08:00
15c2a3bacc int128_t -> int128_opt 2022-02-17 20:03:25 -08:00
532a69a639 Fix handling of 96-bit long double with -m32 2022-02-17 15:51:59 -08:00
d8e1dd4ab2 improve installing headers 2022-02-17 08:13:26 -08:00
ae25f7968e add ability to build Apple framework using CMAKE_FRAMEWORK 2022-02-17 08:13:26 -08:00
ce93a66dfb Implement a fallback uint128_t 2022-02-17 07:37:09 -08:00
6a13464059 Include 128-bit with other signed integers in specifier check 2022-02-16 16:57:06 -08:00
70de324aa8 Apply 2746 fix for NVidia compiler also (#2770) 2022-02-16 12:04:16 -08:00
a1ea3e015b Move built-in formatter specialization to core 2022-02-16 07:37:00 -08:00
161059dd98 Add support for extended precision FP 2022-02-16 06:07:04 -08:00
c4c6b42de7 Bump version 2022-02-15 13:36:59 -08:00
21785040c7 Fix markup 2022-02-15 13:28:53 -08:00
2b6f7fc7a3 Add partial support for extended precision FP 2022-02-15 07:22:41 -08:00
0a24a0714e Clz builtin may be not constexpr (Issue #2761) (#2762) 2022-02-14 18:19:06 -08:00
ba6f89c76e Update .bazelversion (#2766) 2022-02-14 06:08:46 -08:00
5594edaf67 Address https://github.com/fmtlib/fmt/issues/2763 (#2765) 2022-02-13 20:14:28 -08:00
10e3b83a75 Replace `make_args_checked with make_format_args` (#2760)
* Replace make_args_checked to make_format_args

* Deprecate legacy make_args_checked
2022-02-13 20:13:35 -08:00
c48353cb75 Update docs 2022-02-13 07:41:15 -08:00
083510f0f0 Add FMT_CONSTEXPR to rotr instead 2022-02-13 06:15:17 -08:00
dba99bc860 Revert adding constexpr to rotr to satisfy C++11 compilers 2022-02-13 06:15:17 -08:00
c04af4bfc7 Simplify remove_trailing_zeros 2022-02-13 06:15:17 -08:00
b348caa9e9 Remove some C-style casts for consistency 2022-02-13 06:15:17 -08:00
c8bd1e646e Simplify remove_trailing_zeros 2022-02-13 06:15:17 -08:00
9b23e9dcb8 Fix wrong comment/refer to a correct reference 2022-02-13 06:15:17 -08:00
69f2c550ab Remove std:: infront of uint32_t/64_t & add constexpr to rotr 2022-02-13 06:15:17 -08:00
9b62310f03 Fix some conversion issues 2022-02-13 06:15:17 -08:00
08d12f31d1 Fix typo 2022-02-13 06:15:17 -08:00
dbddb1d066 Remove literal separator to satisfy some compilers 2022-02-13 06:15:17 -08:00
7dbe3dcded Recover log10_2_significand 2022-02-13 06:15:17 -08:00
10642e6082 Optimize remove_trailing_zeros 2022-02-13 06:15:17 -08:00
7b4323e1e0 Add rotr 2022-02-13 06:15:17 -08:00
f1bd6f7731 Check r < deltai first, because that is the major branch chosen for short inputs 2022-02-13 06:15:17 -08:00
5d8eb6a1a0 Reflect the new paper
- Change constants appearing in log & division computations
  - Rename beta_minus_1 to beta
2022-02-13 06:15:17 -08:00
8e2e4d4034 Suppress a gcc warning 2022-02-12 09:26:48 -08:00
a44716f58e Workaround to Intel compiler (#2758) 2022-02-11 06:25:42 -08:00
c71b070168 Add missing const qualifier (#2755) 2022-02-10 10:51:32 -08:00
ecd6022c24 Update docs 2022-02-08 06:28:22 -08:00
afbcf1e8ea Remove legacy C locale wrapper 2022-02-05 12:37:21 -08:00
90325d0970 Fix stored type detection 2022-02-05 10:44:34 -08:00
e2ba01fcb0 Fix overload ambiguity in print 2022-02-05 08:35:19 -08:00
17b362f78c Simplify ostream opt-in API 2022-02-04 18:33:59 -08:00
a5a7e3a261 Update docs 2022-02-04 15:42:22 -08:00
f055ebbd25 Make ostream operators opt in to reduce the risk of ODR violations 2022-02-04 15:06:45 -08:00
8a21e328b8 Remove problematic constructibility check 2022-02-04 12:20:02 -08:00
31e743d06e Don't use ostream for types convertible to string_view 2022-02-04 11:00:00 -08:00
35c0286cd8 Simplify byte handling 2022-02-02 16:13:24 -08:00
c7173a36a1 Drop :: and fix formatting 2022-02-02 07:00:33 -08:00
3e8372b96e qualify unqualified calls to format in compile.h (#2742) 2022-02-01 18:41:19 -08:00
a34a97cc1d Supporting ? as a string presentation type (#2674)
* Supporting ? as a string presentation type.

* Supporting ? as a char presentation type.

* Adding iterator_category to counting_iterator.
2022-01-30 08:55:28 -08:00
ae1aaaee5f Fix access mode of files created (#2530) (#2733)
The previous fix for this in 4a85db1 was incomplete. The intent was to
mimic what `fopen()` is doing. As per standard[1] `fopen()` also sets
`S_IWGRP` and `S_IWOTH` and lets the umask handle the rest.

[1] https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/fopen.html
2022-01-28 17:12:49 -08:00
1557ab7644 Add format_as for enums 2022-01-28 06:38:02 -08:00
b00a1eac75 Fixes NVIDIA HPC compiler and Intel ICC compatibility (#2732)
* Fixes NVIDIA HPC compiler and Intel ICC compatibility

* Fixes NVIDIA HPC compiler and Intel ICC compatibility

* Rename FMT_NVHPC_VERSION to FMT_NVCOMPILER_VERSION

Co-authored-by: Federico Busato <fbusato@nvidia.com>
2022-01-26 15:53:04 -08:00
a7aecbfcaa Remove an old mingw workaround 2022-01-23 09:44:53 -08:00
dfcc730cbd Making target_compile_options PRIVATE, fix #2726, fix #2507 2022-01-23 09:36:11 -08:00
f7a809be6e Clarify the choice of magic numbers and compute the most magic one
https://github.com/fmtlib/fmt/pull/2713#discussion_r788349826
2022-01-23 08:58:58 -08:00
09fde7f4b8 Add fmt::underlying for enum classes 2022-01-22 08:06:22 -08:00
0014024a2c Don't rely on transitive includes 2022-01-21 15:03:28 -08:00
c28500556a FMT_NOEXCEPT -> noexcept 2022-01-20 16:55:47 -08:00
6240d02011 Improve comments 2022-01-19 17:03:44 -08:00
925b744ae8 Improve comments 2022-01-19 17:03:44 -08:00
22b14ff252 Simplify cache recovery 2022-01-19 17:03:44 -08:00
3dc26b44d3 Make a fallback path more compiler-friendly 2022-01-19 17:03:44 -08:00
2e4038bf51 Simplify lines with __builtin_addcll and friends 2022-01-19 17:03:44 -08:00
76336b4f63 Replace noexcept with FMT_NOEXCEPT 2022-01-19 17:03:44 -08:00
9181983483 Fix syntax errors 2022-01-19 17:03:44 -08:00
74097a149b Remove now-unused stuffs 2022-01-19 17:03:44 -08:00
21a1c53381 Fix typo 2022-01-19 17:03:44 -08:00
04eea0f0a8 Remove now-unused stuffs 2022-01-19 17:03:44 -08:00
35a468ed38 Simplify integer checks 2022-01-19 17:03:44 -08:00
1882a7a2c1 Replace Dragonbox cache which allows simpler cache recovery & integer checks 2022-01-19 17:03:44 -08:00
f4dd1b1b8b Simplify Dragonbox Step 3. 2022-01-19 17:03:44 -08:00
70561ed13e Minimize the usage of built-in 128-bit ints
It usually generates slower code than manual handling.
2022-01-19 17:03:44 -08:00
cdf1a3b530 Fix codecvt warning (#2408) (#2725) 2022-01-19 10:26:09 -08:00
b8b037e930 Fix -Wconversion warning (#2724)
* - try fixing the warning "chrono.h:1217:37: warning: conversion from 'std::make_unsigned<long long int>::type' {aka 'long long unsigned int'} to 'size_t' {aka 'unsigned int'} may change value [-Wconversion]" by casting int to size_t (occurs when cross-compiling to Raspberry Pi ARMv7)

* - remove call to to_unsigned() because using static_cast<size_t> is enough
2022-01-19 06:31:33 -08:00
5985f0a7d2 Fix overflow for chrono durations (#2722) 2022-01-17 12:14:59 -08:00
8f8a1a02d5 Fix handling of formattable types implicitly convertible to pointers 2022-01-14 13:42:01 -08:00
b02e5af52c fmt::join support FMT_COMPILE (#2720) 2022-01-14 09:58:49 -08:00
58fb782396 Improve docs 2022-01-13 14:57:17 -08:00
4fe6129d6c Fix FMT_NOEXCEPT definition 2022-01-13 10:20:32 -08:00
c056a009de Docs: Fix link to "Compile-time Format String Checks" section (#2712) 2022-01-12 16:07:56 -08:00
7c12118c19 Deprecate buffered_file::fileno 2022-01-12 10:54:44 -08:00
2a09d468da Use noexcept unconditionally 2022-01-12 09:42:29 -08:00
a126b4d888 Check if right shift is arithmetic 2022-01-11 08:23:30 -08:00
9ff91b18cd Simplify write_fractional_seconds 2022-01-09 15:08:46 -08:00
d9f045fba1 Fix a UB in chrono 2022-01-09 14:06:13 -08:00
c06bef7273 Adding comments for range formatting. (#2706)
* Adding comments for range formatting.

* Adding missing quotes
2022-01-08 16:37:21 -08:00
3c98f1a4cd Comment style 2022-01-08 09:52:39 -08:00
6e0f1399d7 Supporting nested format specs for ranges. (#2673)
* Supporting nested format specs for ranges.

* I dedicate this commit to Eric Niebler.

* clang-format

* PR comments.

* throw -> FMT_THROW

* Need to map every element too.

* Clarifying uncvref_type

* Trying to add a workaround for MSVC.
2022-01-08 09:48:26 -08:00
0102101acc Make colored print handle UTF-8 (#2701)
* Fix #2681 - Make detail::print handle UTF-8

* Okay, let's do this Windows-only

* drop extra \0

* yay we can throw!
2022-01-06 16:10:53 -08:00
4ac5269b4f Update ChangeLog.rst 2022-01-06 15:03:01 -08:00
b6f4ceaed0 Update version 2022-01-06 14:35:15 -08:00
15f812dae8 Update changelog 2022-01-06 14:13:01 -08:00
6884aab49b Update changelog 2022-01-06 12:38:33 -08:00
88ec4e7061 Bump version 2022-01-06 12:32:43 -08:00
dd3d2490ed Update changelog 2022-01-06 12:07:13 -08:00
739055ae7b Fix apidocs 2022-01-06 11:06:39 -08:00
dbbd711f46 Suppress a warning 2022-01-05 09:41:35 -08:00
98cbb6a43c Fix ABI compatiblity issue 2022-01-05 08:08:38 -08:00
214cf13f17 Fix endianness bug in write_digit2_separated (#2699)
* Fix endianness bug in write_digit2_separated

* Move endianness check to compile time if it possible

* Turn 8 into a constant
2022-01-04 14:23:42 -08:00
17a5c808da Restore FMT_API on error_handler::on_error() (#2696)
this fixes a breaking ABI change that was introduce in the upgrade from
8.0.1 to 8.1.0.

Fixes #2695.
2022-01-04 10:53:44 -08:00
fc1783fcc6 Avoid undefined symbols with mingw-w64 (#2692)
Fixes issue #2691
2022-01-03 15:29:29 -08:00
1b193e7b37 Deprecate more 2022-01-03 11:13:09 -08:00
8e59744b8d Switch to new github auth mechanism 2022-01-02 09:29:42 -08:00
7081a6aa34 Update version 2022-01-02 09:01:32 -08:00
64dc8fbada Bump version 2022-01-02 08:34:01 -08:00
fc8e3de7db Fix manage.py script 2022-01-02 08:22:25 -08:00
57bee9fcdd Fix formating 2022-01-02 08:09:55 -08:00
dce52e491e Update changelog 2022-01-02 08:02:45 -08:00
9405a47245 Update changelog 2022-01-02 07:57:36 -08:00
495b8bf12e Update changelog 2022-01-01 13:56:31 -08:00
e221166fab Update changelog 2022-01-01 11:34:04 -08:00
035cab8da3 Update changelog 2022-01-01 09:36:40 -08:00
89c6ed12bf Clarify in comments (for now) deprecated map functions 2022-01-01 09:29:50 -08:00
e462da828d Add some noexcept (#2684)
I got warnings from -Wnoexcept, fixed them.
2022-01-01 08:44:00 -08:00
79c66d66bd Update changelog 2021-12-29 15:33:30 -08:00
5d37f705f4 Update changelog 2021-12-29 15:31:03 -08:00
6bb370cec1 Update changelog 2021-12-29 15:26:11 -08:00
bb69201578 Fix tuple join 2021-12-29 14:46:45 -08:00
4fac7daaef Cleanup bit_cast 2021-12-29 12:14:51 -08:00
3617c2795a Update changelog 2021-12-29 08:25:12 -08:00
9c0c1bcdbd Simplify tuple formatting 2021-12-29 08:03:12 -08:00
187e8db1be Update changelog 2021-12-28 08:11:03 -08:00
c7f88180f6 add tests for format string compile-time checks 2021-12-27 20:55:06 -08:00
8a2c3fb88f add reverse tests to compile-error-test
to make sure that error tests do not fail because they become outdated
2021-12-27 20:55:06 -08:00
1164eda5af disable compile-error-test on Windows
since it takes too much time to complete, similar to other tests with additional
CMake invocation
2021-12-27 20:55:06 -08:00
4482f6f1f0 rewrite compile-error-test to use non-header-only library 2021-12-27 20:55:06 -08:00
796662a612 Escape range items convertible to std::string_view 2021-12-27 09:38:06 -08:00
33ee4cc516 Improve noexception test 2021-12-26 16:28:41 -08:00
3bbf2c673c Fix throw with exceptions disabled 2021-12-26 16:28:41 -08:00
074c9c52ef Update changelog 2021-12-26 08:36:29 -08:00
3110ec5a23 Update changelog 2021-12-26 08:19:32 -08:00
3014b3d770 Clarify that C strings must be null-terminated 2021-12-26 07:23:43 -08:00
eab2ea9fc2 Replace an assert with an exception 2021-12-26 07:05:45 -08:00
21ed92a6e9 Update changelog 2021-12-24 07:25:23 -08:00
04111dd1e4 Fix issue #2670 (#2671) 2021-12-23 12:38:48 -08:00
817788fbf0 remove incorrect C++20 check from test/CMakeLists.txt (#2663)
It disables entire branch of tests declaration unconditionally because CXX_STANDARD
is not defined there. But even we use CMAKE_CXX_STANDARD here, these tests should
not be disabled with standard >= C++20.
2021-12-23 12:32:03 -08:00
4511030af2 Minor code style tweaks for consistency 2021-12-23 11:55:58 -08:00
7812813a32 Don't explicitly delete copy ctor of dynamic_format_arg_store (#2664)
* Don't explicitly delete copy ctor of dynamic_format_arg_store

Explicitly deleting the copy ctor causes the move constructor to not be
implicitly generated. This behaviour is different than what was in
v8.0.1 and causes code that relied on the move ctor of
dynamic_format_arg_store to break.

* Add test for dynamic_format_arg_store's move ctor

* include <memory>, don't use make_unique
2021-12-23 11:34:16 -08:00
664cd6067d Remove std-format-test 2021-12-23 10:58:02 -08:00
784e2a7b42 Fix an overflow when formatting very large durations 2021-12-23 10:34:32 -08:00
fc2a376d8e Remove two expressions which had no effect (reported by LGTM)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
2021-12-22 16:29:16 -08:00
c5aafd8f90 expose headers as SYSTEM depending on special configuration option 2021-12-19 08:29:51 -08:00
eaddd1e3cd Fix handling of byte 2021-12-19 06:46:24 -08:00
2d44577586 Try fixing byte regression 2021-12-18 08:51:21 -08:00
e46392ea2c deprecate _format UDL in code using FMT_DEPRECATED 2021-12-18 08:33:20 -08:00
c882790a2e Add a set formatter 2021-12-18 07:35:40 -08:00
121002d700 Add a map formatter 2021-12-18 07:12:53 -08:00
be51ee1ceb Disable broken copy ctor of dynamic_format_arg_store 2021-12-17 17:18:18 -08:00
659de779e6 Fix a UB in parse_format_specs when begin is null 2021-12-17 16:51:24 -08:00
51b14b6c0c remove commented out lines 2021-12-17 16:05:56 -08:00
223a0fa55d move gtest-specific check into gtest/CMakeLists.txt 2021-12-17 16:05:56 -08:00
ef72b471fc enable named arguments check in compile-time checks (#2649)
works only if all named arguments are UDL-based
2021-12-17 15:53:05 -08:00
82246b8766 fix throw with exceptions disabled (#2647) 2021-12-17 13:44:36 -08:00
35f60377aa Update ChangeLog.rst 2021-12-17 06:49:29 -08:00
3a951a66cb Avoid qualifying by inline namespace. Fixes #2642. (#2643) 2021-12-10 08:28:25 -08:00
e0136fc8bd Qualify calls to make_wformat_args. Fixes #2639. (#2641) 2021-12-10 06:36:42 -08:00
ac1b5f3da5 Refactor problematic trailing returns in arg_mapper 2021-12-09 18:08:30 -08:00
fd62fba985 Don't convert scoped enums to integers 2021-12-09 12:09:33 -08:00
c652f8243a Make header guard consistent with header name 2021-12-09 10:49:47 -08:00
a9c7b9b8f7 Clarify that _format is deprecated 2021-12-09 10:34:27 -08:00
e4f0564aa6 Disable is_streamable for string[_view] 2021-12-09 10:02:18 -08:00
91533d3c33 Minor tweaks to chrono subsecond formatting 2021-12-09 06:55:31 -08:00
0bbc9708f9 Implement c++20 std::chrono::duration subsecond formatting (#2623)
* Add support for subsecond printing for std::chrono::duration according to the c++20 standard

* Remove assert test that overflows intmax_t

* * Hopefully fix int64_t to int32_t conversion errors.
* Allow proper Duration::rep type to propagate via template argument deduction

* * Hopefully fix int64_t to int32_t conversion errors.
* Allow proper Duration::rep type to propagate via template argument deduction

* Fix sign conversion (-Wsign-conversion) warning treated as error in num_digits()

* Format chrono.h with clang-format

* Remove extra forward slash in doxygen style comment

Co-authored-by: Victor Zverovich <victor.zverovich@gmail.com>

* Apply all suggestions from GitHub, except for replacing the utility subsecond_helper class with a function

* * Move logic of handling subseconds from utility class to function with name write_fractional_seconds()
* Revert write(Rep value, int width) function to previous state

* Fix -Wshadow warning

* Remove unsued get_subseconds() function, its logic has been moved to write_fractional_seconds()

* Change comment from lowercase int to uppercase Int

* Simplify test check

* Integrate suggested changes

* Remove static from detail functions, they are no longer member functions of a class and static is unnecessary.
* Change comment from "amount" to "number"

Co-authored-by: Victor Zverovich <victor.zverovich@gmail.com>
2021-12-09 06:45:13 -08:00
9d5b9defde Enable tzset only on Windows desktop app (#2633) 2021-12-07 15:22:36 -08:00
215f21a038 Detect overflow on large precision 2021-12-05 07:26:58 -08:00
c240d98ffd Optimize tm formatting (Non C-locales and %Z) (#2617)
* Move fmt::detail::formatbuf to format.h

* Replace std::basic_ostringstream to std::basic_ostream with custom formatbuf

* Use tm.tm_zone
2021-12-04 11:02:31 -08:00
6ab73113fc Mark grow as FMT_CONSTEXPR20 (#2630)
resolves https://github.com/fmtlib/fmt/issues/2627
2021-12-03 07:13:30 -08:00
713c7c7c62 Cleanup os.cc 2021-12-01 06:47:41 -08:00
9b1807a8a2 fix int -> uint warning (#2611)
* fix int -> uint warning

* change unsigned int to mode_t

* undef + warn uint -> ushort loss presision

* fix mode_t

* mode_t in detail

Co-authored-by: Acretock <George.Goncharov@finch-xr.com>
2021-12-01 06:40:17 -08:00
ec3b097cb9 [doc] FMT_STRING supports C++14 and no-op in C++11 (#2620)
* FMT_STRING supports C++14 and no-op in C++11

* Move requirement to the end. Modify description.
2021-11-28 07:02:15 -08:00
c472a27818 Fix handling of very large precision in fixed format 2021-11-27 08:23:05 -08:00
201971e293 Make MSVC use [[nodiscard]] (#2615)
* Make MSVC use [[nodiscard]]
* Uniformly detect attributes for __cplusplus and _MSVC_LANG
2021-11-26 07:32:50 -08:00
acad8cfab1 Reformat all source code; no functional changes
Before adding the format checker, the mainline should be clean, to
avoid false failures.
2021-11-25 09:15:25 -08:00
491ba2dda5 Annotate fmt::format and fmt::formatted_size as [[nodiscard]]
This prevents accidentally writing fmt::format when fmt::print was
intended. Other than running tests, there's not a good use case for
discarding the formatted output.
2021-11-25 07:30:30 -08:00
5abe9e8266 Add platform-specific 'z' formatter 2021-11-25 06:52:39 -08:00
be3a3a5aed Use predefined formats for C-locale 2021-11-25 06:52:39 -08:00
a3ab36c803 Formatting of function pointers, member function pointers, member object pointers... (#2610) 2021-11-23 12:55:22 -08:00
19cac63fe4 Broken link in README.rst
Added src directory to link
2021-11-19 09:24:38 -08:00
43419a4ada Workaround a bug in gcc 2021-11-19 07:32:42 -08:00
c089f7d497 Simplify std::tm formatter 2021-11-14 07:16:22 -08:00
aa5517f6b9 Reuse tm_writer in chrono_formatter 2021-11-14 07:16:22 -08:00
50140be7ae Reuse tm_writer in weekday formatter 2021-11-14 07:16:22 -08:00
8b89454994 Improve consistency 2021-11-13 08:59:56 -08:00
5380ff4d88 Detect types convertible to unformattable pointers 2021-11-13 08:26:27 -08:00
094b66e81d changed locale retrieval way to a fancy one 2021-11-12 12:46:38 -08:00
b69ae4854c Reorder classes (#2591) 2021-11-10 17:09:23 -08:00
0b843af56b sped up chrono.h formatting for cases without providing locale (#2576) 2021-11-07 08:52:57 -08:00
12b1d8b14a Fix precision 0 with std::chrono::duration and added additional tests. (#2588) 2021-11-06 08:57:22 -07:00
e67f92c55c Cleanup warnings with nvhpc/21.9. (#2582)
* Cleanup warnings with nvhpc/21.9.

* Move __NVCOMPILER check.

* Be more explicit.

* Immediately executed lambda.

* Fix shadowing warning.
2021-11-05 12:17:11 -07:00
812733cc96 const qualify format function for systen_clock 2021-10-31 09:41:16 -07:00
028f227752 Handle implicit conversions in write 2021-10-31 08:58:54 -07:00
5b0aa638cf Minor grammar fix 2021-10-30 09:14:13 -07:00
6eaceb5f73 Fix incompatible between docutils 1.18.0 and sphinx 3.3.0 (#2575) 2021-10-30 09:12:36 -07:00
0697c5edb6 FMT_USE_FCNTL can be predefined (#2573)
'os.h' accepts a predefined FMT_USE_FCNTL override so using FMT with e.g. the NXP toolchain for ARM (e.g. for FreeRTOS) does not have a fcntl() call, but the detection routine does not detect this correctly.
2021-10-30 08:35:48 -07:00
1031eedf27 Replacing strftime with std::time_put (#2550)
* Fix unicode test

* Add xchar support to chrono formatter

* Replace strftime with std::time_put

* Add std::locale support to std::tm formatter

* Use predefined names and formats for C-locale

* Performance improvement

* Make locale-independent and C locale formats consistent among platforms
2021-10-30 08:25:45 -07:00
90034e4c4b Add FMT_ASSERT and validation of values of struct tm members (#2564)
Switch internal year calculations to long long
2021-10-27 13:29:07 -07:00
df40e94673 Upgrade module-test to msvc 16.11.5 and 17.0-pre5 (#2558) 2021-10-24 08:12:39 -07:00
e6d5059cbb Simplify js tag in basic-bootstrap theme (#2562)
When build the docs for debian package, it uses a sphinx building
helper, which does a sanity check for the output.

The sanity check complains missing data-url_root attribute in the
js tag. So this patch changes the js tag to use the same function like
the origin basic theme, which adds additional information like
data-url_root.

Ref: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=997437
2021-10-24 06:36:10 -07:00
3b6e409cd8 Enable consteval for msvc 17.0-pre5 (#2559) 2021-10-23 07:19:57 -07:00
249f03bbb7 do not detect LLVM based IBMXL compiler (on ppc) as clang (#2555) 2021-10-20 06:21:49 -07:00
7463c83205 Fix overflow for very bigger years (>2*10^9) (#2551) 2021-10-19 07:04:55 -07:00
1266c2b600 Fix handling of exotic character types 2021-10-17 09:07:48 -07:00
684e2fdc94 Minor cleanup 2021-10-17 06:33:27 -07:00
a1d586302f Minor cleanup 2021-10-17 06:07:03 -07:00
7a604cdd98 Cleanup 2021-10-16 15:03:57 -07:00
aeb54b0dd9 Fix bug on '%Y' and '%C' formats with negative years
Requested changes
2021-10-16 15:03:57 -07:00
f88c020fc0 Generalization of strftime/wcsftime function calls in tests 2021-10-16 15:03:57 -07:00
2eeddba756 Renaming, splitting of functions 2021-10-16 15:03:57 -07:00
2754546080 Fix errors in ISO week-base-year formatter 2021-10-16 15:03:57 -07:00
218cecb6d1 Fix error in test 2021-10-16 15:03:57 -07:00
e9f4453b0e Fix Microsoft Visual Studio 14.0 build 2021-10-16 15:03:57 -07:00
27c3674ce1 Improve performance 2021-10-16 15:03:57 -07:00
5dc3dd3d4a New tests 2021-10-16 15:03:57 -07:00
f8542cd988 Unified formatters for std::chrono::time_point<std::chrono::system_clock, Duration> and std::tm 2021-10-16 15:03:57 -07:00
4707373d33 Fix year formatter 2021-10-16 15:03:57 -07:00
79c00ad8f2 Improve ISO week-base-year formatter 2021-10-16 15:03:57 -07:00
fbaaa5906b Improve week of the year formatter 2021-10-16 15:03:57 -07:00
cde44ddb72 Improve year formatter 2021-10-16 15:03:57 -07:00
b04601b918 Switch from std::strftime/std::wcsftime to internal implementation for locale independent formats 2021-10-16 15:03:57 -07:00
d3d30a46f0 New tests 2021-10-16 15:03:57 -07:00
7911d8d3f5 Add format spec checker 2021-10-16 15:03:57 -07:00
fbbfc3b03c Reorder formatters 2021-10-16 15:03:57 -07:00
509eac9575 Workarounds for implementation-defined std::strftime behavior 2021-10-16 15:03:57 -07:00
85b38190d1 New tests for all C++11 std::strftime format specifiers 2021-10-16 15:03:57 -07:00
7aca36bca4 Extending fmt::join to support C++20-only ranges. (#2549) 2021-10-16 10:02:03 -07:00
f5371a75f4 locale.h -> format.h 2021-10-14 15:57:10 -07:00
febdef43f5 fix: add workaround for intel parameter pack bug 2021-10-14 10:44:24 -07:00
f56756986b fix: check to make sure both 'if constexpr' and return type deduction are available
fix: remaining ifdefs
2021-10-14 10:44:24 -07:00
dcd282bb26 Namespace qualify calls to get 2021-10-09 07:15:14 -07:00
9c14474d30 Include <bit> when using std::bit_cast 2021-10-09 06:11:36 -07:00
1e96e01766 Fix compiler flag check (#2540) 2021-10-09 06:05:05 -07:00
7e4bc94510 Speeding up write_significand() (#2499) 2021-10-09 05:27:38 -07:00
26c1ca4c3e Replaced default spec with equivalent one, which is potentially more optimizable (#2537) 2021-10-08 07:09:54 -07:00
1e865b3539 Fix docs 2021-10-03 07:05:31 -07:00
4a85db1ce1 Change default open mode to -rw-r--r-- (#2530) 2021-10-03 06:36:40 -07:00
0a985fd4c6 Move size_ initialization to initializer list (#2529) 2021-10-02 17:20:33 -07:00
012cc709d0 Workaround gcc _Pragma bug 59884 2021-10-02 15:41:47 -07:00
d6590e3bd2 Fix compiler check 2021-10-02 08:46:18 -07:00
134aec40f0 Fix search in docs 2021-10-02 07:58:08 -07:00
48a476ae0f Update example (#2522) 2021-10-02 07:33:33 -07:00
023c2018f7 Don't use strlen in constexpr 2021-10-02 07:17:05 -07:00
800d4c8ac8 Refactor Windows workarounds 2021-10-02 06:06:08 -07:00
32865aeaab changed detection of Intel Compiler Classic to distinguish MS-Windows (#2510)
* changed detection of Intel Compiler Classic to distinguish MS-Windows

* replaced !FMT_ICC_ON_WINDOWS by FMT_ICC_POSIX
removed #pragma manged

* replaced FMT_ICC_POSIX with FMT_ICC_INTRINSIC_BUG to be crystal clear about the macro's purpose
2021-10-02 05:43:41 -07:00
7b339795a1 Describe a better approach of how to use {fmt} as a depency in a Bazel project (#2516) 2021-10-02 05:36:43 -07:00
ae9bbe1169 Suppress warning C4127 in chrono.h (conditional expression is constant) (#2518) 2021-09-30 09:14:38 -07:00
927dbd134d Misplaced comma in README.rst (#2515) 2021-09-28 09:53:37 -07:00
2a9a77dd8c Remove misplaced comment 2021-09-26 18:01:39 -07:00
1aee4bc90a Refactor FP formatting 2021-09-26 14:37:33 -07:00
e1bd6cc913 Refactor FP formatting 2021-09-26 10:25:46 -07:00
027fcaf05e Replace use_grisu with fallback since Grisu is only one of multiple implemented algorithms 2021-09-26 08:44:05 -07:00
716d69f27e Refactor FP formatting 2021-09-26 08:27:18 -07:00
ff7e73af66 Always run grisu_gen_digits before fallback_format 2021-09-26 07:54:25 -07:00
2976e31ac9 Refactor format_float 2021-09-25 11:20:56 -07:00
807ee5ec31 Disable consteval in Apple clang 2021-09-25 05:55:05 -07:00
d9a731d486 Add basic support for Bazel (#2505) 2021-09-24 13:17:26 -07:00
9c57357e05 Add static to a table (#2509) 2021-09-24 06:25:08 -07:00
2742611cad Fix formatting 2021-09-18 11:09:24 -07:00
5092b198bc Document group_digits 2021-09-18 10:50:30 -07:00
b4d9d82e1d make FP formatting available to be used at compile-time (#2426)
* works only with FMT_HEADER_ONLY
* works only with float and double types (not long double)
2021-09-18 08:03:23 -07:00
d9fd695ac7 Fix wchar_t tm formatting 2021-09-15 07:33:24 -07:00
92614ecbf9 Optimize %T in tm formatting 2021-09-15 07:33:24 -07:00
aaeca12d89 Move FMT_MAYBE_UNUSED to format.h where it is used 2021-09-13 07:51:36 -07:00
3d0c7ae385 Move data to format.cc 2021-09-13 06:23:57 -07:00
04e3a79f76 Use memcpy in more cases in copy2 2021-09-12 12:23:45 -07:00
e47e99bb09 Simplify format_decimal (#2498)
* Add copy2() constexpr

* Removed redundant format_decimal implementation for constexpr context
2021-09-12 10:36:06 -07:00
9b6b0e403c Remove data 2021-09-12 09:46:00 -07:00
4d1c6034eb Deprecate basic_data 2021-09-12 09:37:23 -07:00
a3348eccdd Deprecate most of basic_data 2021-09-12 08:59:39 -07:00
3a04481485 Remove data::hex_digits 2021-09-11 17:54:40 -07:00
ad77331c04 Move log10_2_significand to format-inl.h 2021-09-11 09:36:23 -07:00
d9ebc4e821 Add a function to get sign char 2021-09-11 09:17:59 -07:00
c00eb4f4c6 Add missing inline 2021-09-10 09:01:18 -07:00
25af02f21a positive -> nonnegative (#2493) 2021-09-10 08:52:54 -07:00
67cb2dad37 Optimize %F in tm formatting 2021-09-10 07:48:50 -07:00
1aa98f8b93 Eliminate double copying in vformat_to_n (#2489) 2021-09-09 08:10:29 -07:00
a58c133821 Improve code_point_length codegen on older gcc 2021-09-07 19:34:13 -07:00
aeee70a815 Remove unnecessary cast 2021-09-07 10:53:43 -07:00
c771ba361c Fix build for the clang-10 / libstdc++-9 couple (#2491) 2021-09-07 08:52:34 -07:00
ab6e2272cc Clarify shifts encoding 2021-09-06 18:45:34 -07:00
e4728409e7 Use throw_format_error in more places to reduce bloat 2021-09-06 16:42:17 -07:00
e3ebf366a6 Inline padding shifts 2021-09-06 16:26:50 -07:00
894faf3fed Refactor presentation types 2021-09-06 13:32:33 -07:00
4eb97fa4e3 Reduce code bloat 2021-09-05 16:24:20 -07:00
6b55c83252 is_const_formattable -> has_const_formatter 2021-09-05 08:35:08 -07:00
2fe94ad7e3 Make specifiers support in tuple_join an opt-in 2021-09-05 07:34:06 -07:00
3940de5952 thousands -> group_digits 2021-09-05 06:47:18 -07:00
c4d0f96a6d Implement format specs in fmt::thousands 2021-09-04 06:56:51 -07:00
3b9c442689 Implement thousands separators without locales 2021-09-04 06:32:46 -07:00
08f98c7fac Simplify get_arg_index_by_name 2021-09-03 21:17:36 -07:00
a151f955a0 Remove FMT_OVERRIDE 2021-09-03 18:15:17 -07:00
42a225cbd9 Remove redundand final 2021-09-03 17:33:26 -07:00
bf20d19901 Simplify the core API 2021-09-03 16:57:33 -07:00
fc0884037e Move FMT_GCC_VISIBILITY_HIDDEN to format.h 2021-09-03 16:34:42 -07:00
1aeed2dbca Require inline namespaces 2021-09-03 15:59:23 -07:00
799bea4730 Remove FMT_HAS_GXX_CXX11 2021-09-03 15:49:40 -07:00
60cd5ea3f2 Add support for more formattable types in ranges 2021-09-03 14:55:41 -07:00
4fd9a00f35 Simplify ostream interface 2021-09-03 13:07:54 -07:00
5681563898 Cleanup ostream interface 2021-09-03 10:35:19 -07:00
20931baf1d Disable fallback_formatter for arrays 2021-09-03 08:59:36 -07:00
d58d19ba32 Fix an odr violation in ranges.h (#2483)
* Add a testcase demonstrating ODR violation in ranges.h

* Fix ODR violation in ranges.h

* Fix comments

Co-authored-by: Pierre-Antoine Lacaze <pa.lacaze@gmail.com>
2021-09-02 08:47:44 -07:00
ee0659f8b6 Fix formatting of abstract classes via ostream 2021-09-02 08:19:12 -07:00
8029bf955c Fix copy_str performance (#2477) 2021-09-02 07:25:26 -07:00
Max
2520f410c8 Workaround for #2478 (#2482)
_MSC_VER 1911 (Visual Studio 2017 15.3)
2021-09-02 07:13:30 -07:00
ee63f5f04e Workaround to MSVC bug (#2474) (#2476) 2021-08-31 07:54:42 -07:00
1aaf72fb6d Add an example to fmt::runtime 2021-08-29 12:10:40 -07:00
c1313c2057 Clarify that format_to[_n] do not append a terminating null 2021-08-29 12:07:35 -07:00
cb0f177c35 Improve docs 2021-08-29 11:30:35 -07:00
71677e5204 Improve docs 2021-08-29 11:21:38 -07:00
4db5723525 add fuzzers for chrono timepoint and localtime,gmtime (#2469)
* add fuzzers for chrono timepoint and localtime,gmtime

* reorder cases to improve throughput

mutating the first byte of the input now always results in picking
on of the two paths. Before, two of the four possible outcomes resulted
in doit() not being invoked.

* drop the localtime fuzzer

* inline aliases

* only fuzz std::chrono::system_clock
2021-08-29 06:58:23 -07:00
dc7f3ef2bb Fix header name 2021-08-28 20:34:45 -07:00
419ba86a91 Improve docs 2021-08-28 16:54:58 -07:00
6a5b4d5faf Document format_string 2021-08-28 16:51:48 -07:00
2599163b8a Document format_string 2021-08-28 15:20:56 -07:00
8ef22f7740 Update docs 2021-08-28 12:05:30 -07:00
c0c4d1adab Update docs 2021-08-28 11:52:13 -07:00
729a44e67d Depreate strtod and remove problematic tests 2021-08-28 09:20:36 -07:00
74c1118964 Apply force inline 2021-08-26 21:17:35 -07:00
596508a928 Cleanup 2021-08-26 20:56:28 -07:00
043e3b3429 Remove static_assert from arg_mapper 2021-08-26 20:45:01 -07:00
8b0cb944da Fix error reporting when mixing character types 2021-08-26 18:16:05 -07:00
117fc67077 CI: replace g++ C++20 build to test FP formatting at compile-time 2021-08-26 17:16:45 -07:00
c79a3841e8 make detail::fp and detail::bigit constexpr 2021-08-26 17:16:45 -07:00
5888de9f34 make detail::make_checked() constexpr 2021-08-26 17:16:45 -07:00
04b4b69b11 make detail::bit_cast() constexpr with C++20 2021-08-26 17:16:45 -07:00
fd34a3d246 make detail::basic_memory_buffer constexpr with C++20 2021-08-26 17:16:45 -07:00
6d597e39c3 Fix overload ambiguity in arg_mapper 2021-08-26 16:54:27 -07:00
b9ce56d936 Improve comments 2021-08-26 16:30:58 -07:00
f889e52a15 Improve error reporting 2021-08-26 15:47:44 -07:00
34caecd6b6 Use consistent initialization style 2021-08-23 10:10:56 -07:00
a44c8f651b reimplement formatter<tuple_join_view> (#2457)
* reimplement `formatter<tuple_join_view>`

1. completely reimplement `formatter<tuple_join_view<Char, T...>, Char>`
2. Add some tests

* use FMT_THROW
2021-08-23 09:51:19 -07:00
4b8bda25c0 Fix 2462
Signed-off-by: owent <admin@owent.net>
2021-08-23 06:31:10 -07:00
6b5e6119ee set clang in one place 2021-08-22 17:52:45 -07:00
7af1dc1d27 fix UB in fuzzer common (memcpy on nullptr) 2021-08-22 17:52:45 -07:00
e77686f7a8 clang format
using clang format 11
2021-08-22 17:52:45 -07:00
2207ea0b36 More escaping 2021-08-22 16:54:26 -07:00
a212ff757f Escape invalid code points 2021-08-22 15:51:33 -07:00
a76031e11d check -> is_printable 2021-08-22 13:23:38 -07:00
a7f280765c Improve naming 2021-08-22 12:44:00 -07:00
07d033ecb4 Fix is_printable 2021-08-22 10:37:18 -07:00
cdb4299acb Add Unicode support to is_printable 2021-08-22 09:11:35 -07:00
7df2c82a8a Rewrite printable.py codegen to emit C++ 2021-08-22 09:10:10 -07:00
6cf90d7cee Add script license and fix python version 2021-08-22 08:17:58 -07:00
2f1ad8ed3c Add printable codegen from Rust 2021-08-22 08:15:34 -07:00
371d8e2ee0 Escape Unicode 2021-08-22 07:55:59 -07:00
6397095ca4 More escaping 2021-08-21 16:36:25 -07:00
f69a572538 Don't overescape wide strings 2021-08-19 17:25:16 -07:00
11b07a56b2 We should escape 2021-08-19 14:50:59 -07:00
b559cfd4c0 Implement basic escaping 2021-08-19 14:12:26 -07:00
11d49491cb Handle global locale 2021-08-14 09:38:41 -07:00
6ea6cf9464 Add decimal separator support to float 2021-08-14 09:16:26 -07:00
9730a2af0a Update ChangeLog.rst 2021-08-13 10:07:48 -07:00
c2ed5f6863 Update ChangeLog.rst 2021-08-13 10:07:20 -07:00
7b66e72e2c Use builtin intrinsics on intel (#2450) 2021-08-11 06:22:02 -07:00
d57b2a6525 Suppress a warning 2021-08-08 09:18:46 -07:00
bdfbd794e3 Cleanup begin/end usage 2021-08-07 08:55:01 -07:00
111de881fa Don't copy non-const-iterable ranges 2021-08-07 07:34:02 -07:00
d6e882ed84 Undo the move because the doc is not a GH template 2021-08-06 11:22:33 -07:00
f488eed101 Resolve default constructor error in Xcode 7.2.1 and 8.2.1
Fix issue that produces the error 'default initialization of an object
of const type 'const detail::buffer_size' without a user-provided
default constructor'
2021-08-06 11:17:02 -07:00
652c3653bb Move CONTRIBUTING.md to .github 2021-08-06 10:56:05 -07:00
fb19faa31b Improves README with svg badge (#2446)
Looks much better now!
2021-08-05 06:50:15 -07:00
07211701f4 Disable the -Wstringop-overflow warning from GCC 7 (#2442) 2021-08-02 14:20:18 -07:00
bba0a9d962 Make flush public 2021-07-30 07:02:49 -07:00
f1794a8853 Switch to threadsafe death test style 2021-07-29 06:56:38 -07:00
brm
0544a2279b Exclude fallback functions when FMT_BUILTIN_CLZ(LL) is not defined (#2434) 2021-07-25 10:37:18 -07:00
5c222f0561 Add support for nonconst formattable types 2021-07-24 09:53:53 -07:00
3def950b84 Set FMT_CAN_MODULE=OFF for MSVC 19.29.30035+ 2021-07-23 09:35:09 -07:00
63fe2d5bd2 Add copy constructor for dynamic_format_arg_store, and test 2021-07-23 09:35:09 -07:00
561834650a Improve digit count 2021-07-18 09:14:56 -07:00
f20f50368f Replace throw with FMT_THROW (#2427)
Using `throw` results in compile errors with `-fno-exceptions`. gcc seems fine with it, but arm-gcc and clang would complain.
2021-07-18 07:08:24 -07:00
00235d8a99 fix module test odr violations (#2414) 2021-07-17 09:16:49 -07:00
2038bf6183 Update format_to usage 2021-07-13 07:56:24 -07:00
e41ac1f875 Don't use deprecated API in docs 2021-07-10 13:42:51 -07:00
8465869d7b Move ignore_unused to detail 2021-07-09 08:24:11 -07:00
3d53d1539d Warning removals in test code (#2399)
* Warning removals in test code.

Mostly 0 to nullptr and adding override to virtual function implementations.

* Fix module-test.
2021-07-09 08:05:02 -07:00
20e4ef8b4c Pass significand_size by value 2021-07-05 08:51:43 -07:00
c4a3c2342a Refactor locale handling 2021-07-05 08:25:12 -07:00
7a0d301753 Update README.rst 2021-07-04 07:03:20 -07:00
f2b03facd9 Include test sources to pick up functions and classes from the module rather than from the non-modular library which is baked into the test-main library. (#2356)
This averts linker problems:
 - strong ownership model: missing linker symbols
 - weak ownership model: duplicate linker symbols

Simplify `gtest-extra.cc` while at it.
2021-07-03 07:21:54 -07:00
02ad5e11da Add faint, blink, reverse and conceal to the emphases (#2394) 2021-07-02 20:03:55 -07:00
d141cdbeb0 Update version 2021-07-02 16:14:33 -07:00
cfc05e05f0 Bump version 2021-07-02 14:43:31 -07:00
8ea312633b Update changelog 2021-07-02 14:43:00 -07:00
e461f3dbbe Minor consitency and comment tweaks 2021-07-02 13:56:37 -07:00
54014e42e3 silence warning C4100 on MSVC 2019 when exceptions are disabled (#2397) 2021-07-02 13:51:49 -07:00
3e7a29cc92 Workaround clang/gcc incompatibility 2021-07-02 13:29:22 -07:00
00a57a9f8f Update changelog 2021-07-02 08:07:48 -07:00
1d7384530e Add missing presentation type checks for std::string (#2402) 2021-07-02 07:51:04 -07:00
889bbf27a2 Fix missing std::get overload in MSVC (#2407)
This replaces the `std::get` call with an unqualified equivalent to allow
it to be treated as a dependent call.

ranges.h needs std::get overloads from `<tuple>` but does not directly
include it. This causes compilation failures in MSVC with /permissive-.
On other platforms `<tuple>` is included as a dependency from other headers
(specifically from `<memory>`), but there is no such implicit dependency in
MSVC's STL.

Fixes #2401
2021-07-01 10:55:46 -07:00
5f8473914c Remove outdated apidoc 2021-07-01 07:56:53 -07:00
785908ee37 Fix warnings 2021-06-30 06:42:29 -07:00
fbb70eec5c suppress unused variable warnings (#2381)
* suppress unused variable warnings

An arguably better method for suppressing unused variable warnings.   The `(void)var` method does not work on many intel compiilers.
This is from Herb Sutter's blog post https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/

* Format to eliminate long lines

* Run clang-format
2021-06-30 06:33:30 -07:00
002bb759ff Remove unneeded num_result_bigits decrement
For what I see this seems unused?
2021-06-29 06:23:02 -07:00
a3f762c5aa [doc] Minor: fix `code`. 2021-06-29 06:21:15 -07:00
c3c27e5ab5 Fix MSVC warning C4819 2021-06-28 06:14:53 -07:00
c6b1f181aa Fix docs 2021-06-27 09:06:21 -07:00
94564b058e Fix docs 2021-06-27 08:55:16 -07:00
0fc73a2a85 Merge branch 'master' of github.com:fmtlib/fmt 2021-06-27 08:10:49 -07:00
3156fcf5f4 Switch to older breathe version 2021-06-27 08:10:37 -07:00
f85fb9fdff Adjust definition for FMT_HAS_INCLUDE
Adjust definition for FMT_HAS_INCLUDE

Remove check for `!FMT_MSC_VER`
2021-06-27 07:08:29 -07:00
0bc3d664e3 Fix docs 2021-06-27 06:41:54 -07:00
e5c46e13e8 Fix docs: breathe 18 and earlier corrupts trailing return type 2021-06-26 09:55:27 -07:00
49a3b58c8b Specify size for static data arrays 2021-06-26 06:55:24 -07:00
d0c8d45a2e apt update before install 2021-06-26 06:29:53 -07:00
c9a10631cb format: do not use udl_{arg,formatter} return types when UDL is not in use
The udl_{arg,formatter} structs are only defined when
FMT_USE_USER_DEFINED_LITERALS is set, so don't try to define things that
return that struct when it's not defined.
2021-06-26 06:25:16 -07:00
3bd806f12f Eliminate intel compiler warning
The intel compiler defines `__GNUC__`, but does not support the gcc `_Pragma`.  This PR filters out the intel compiler to avoid warnings about an unrecognized function.
2021-06-26 06:16:12 -07:00
fd16bcb20c Fix bug in cmake join function 2021-06-24 09:10:53 -07:00
5221242f6e Instruct msvc to report the _true_ value in __cplusplus and force _full_ C++ conformance
* do this  in _some_ tests to improve test coverage and catch possible problems due to that
 * fix invalid export of `static constexpr` constant
 * fix msvc warnings about unreachable code in high warning levels
2021-06-24 09:10:08 -07:00
31a5f0d399 Bump version in inline namespace 2021-06-22 14:47:59 -07:00
102a4d492a Bump version in inline namespace 2021-06-22 07:04:02 -07:00
f68508b6ce Update ChangeLog.rst 2021-06-21 18:37:56 -07:00
9e8b86fd2d Update version 2021-06-21 05:59:17 -07:00
92fec0f050 Bump version 2021-06-21 05:57:50 -07:00
4749cc930a Update changelog 2021-06-19 08:16:43 -07:00
78a0ba0a6a Improve conversion of paragraphs 2021-06-19 08:02:52 -07:00
7a39837d96 Use a working breathe version 2021-06-19 07:35:09 -07:00
55b6e92db5 Fix docs 2021-06-19 06:31:19 -07:00
69dc3a8535 Fix docs 2021-06-18 12:51:48 -07:00
27f4cdd586 Update changelog 2021-06-18 12:23:16 -07:00
70d61a0ae3 Update changelog 2021-06-18 08:32:43 -07:00
427b534054 Add no_value state to value 2021-06-15 07:53:28 -07:00
e421d52713 Simplify error handling in parse_nonnegative_int 2021-06-14 16:05:37 -07:00
a59678f376 Fix chrono_test.locale
UTF-8: https://datatracker.ietf.org/doc/html/rfc3629
2021-06-14 09:41:08 -07:00
c98254c3d7 Install locales into CI 2021-06-14 09:41:08 -07:00
c123a72844 Fix set locale error in chrono formatter 2021-06-14 09:41:08 -07:00
3c8fad126c Optimize parse_nonnegative_int 2021-06-13 19:20:44 -07:00
f28cf3302d adding a default format for std::chrono::time_point<std::chrono::syst… (#2345) 2021-06-11 10:52:39 -07:00
55010a9d3a Support non-char overloads (module) 2021-06-11 09:38:53 -07:00
0193e7c428 Support compile-time strings and compile-time format string compilation in module
Make just the necessary parts available for lookup from client context.
2021-06-11 09:38:53 -07:00
3423d75475 Remove the msvc workaround (#2351) 2021-06-11 06:20:25 -07:00
f6b5cc9f84 Fix chrono_test.weekday on legacy glibc 2021-06-10 16:17:10 -07:00
59a298f124 Enable enforce-checks-test for MSVC, too 2021-06-10 12:54:54 -07:00
36c2948225 Update docs 2021-06-08 08:25:50 -07:00
c9fe1fa5ba Remove unused flag 2021-06-08 08:00:37 -07:00
dccddc2bdb Apply clang-format 2021-06-07 08:49:47 -07:00
0e36681b8e Cleanup digit count 2021-06-07 07:42:22 -07:00
1de80f5b22 Workaround lack of static constexpr in constexpr functions 2021-06-07 07:27:56 -07:00
2039dce75f Detect consteval 2021-06-07 06:57:43 -07:00
d551b88a6d Move is_char specializations to xchar.h 2021-06-06 15:32:30 -07:00
16c3514d01 wchar-test -> xchar-test 2021-06-06 07:59:18 -07:00
206000a017 Workaround pathological conversion (#2343) 2021-06-06 07:18:44 -07:00
76ee490468 Move wchar/custom char overloads to xchar.h 2021-06-05 22:57:45 -07:00
e77b22d6da Deprecate memory buffer overload of format_to 2021-06-05 14:58:36 -07:00
07039f4b19 Update README.rst 2021-06-05 06:32:22 -07:00
4678192c88 Remove bsr2log10 2021-06-04 21:33:05 -07:00
7c3d3dfa29 Update thousands_sep_impl signature 2021-06-04 21:12:47 -07:00
ef826b86cb Fix docs 2021-06-04 20:34:58 -07:00
5223f552c8 Remove FMT_ALWAYS_INLINE 2021-06-04 20:29:54 -07:00
cfde93afe0 Add FMT_STATIC_CONSTEXPR 2021-06-04 16:50:09 -07:00
986a5a6c2c Fixed join_view formatter for wchar_t 2021-06-04 14:50:45 -07:00
7c8b35ff32 fix MSVC Win32 count_digits 2021-06-04 11:06:25 -07:00
3eeb084e71 Optimize count_digits 2021-06-04 09:14:58 -07:00
2ac0bfe59e Improve handling of thousands separator 2021-06-04 06:12:44 -07:00
024741b476 CI: set up multi-thread build for all platforms 2021-06-04 05:56:55 -07:00
f4c95f6dd9 Improve handling of thousands separator 2021-06-03 18:25:08 -07:00
d4fbeacc33 Fix docs build 2021-06-03 18:25:08 -07:00
0eef389ddb Code style 2021-06-03 18:25:08 -07:00
e27b1ce50c Fix docs 2021-06-03 09:32:12 -07:00
9f8b6daca2 Fix wheel installation 2021-06-03 09:10:07 -07:00
6060bcfc8a Fix docs 2021-06-03 09:03:00 -07:00
ff9673463c Fix docs 2021-06-03 08:43:41 -07:00
1085cc2178 Fix docs 2021-06-03 08:28:02 -07:00
11addaa16e Update docs 2021-06-03 06:24:17 -07:00
760ca5ccc0 Update docs 2021-06-02 19:45:42 -07:00
290d3f8b61 Cleanup ranges API 2021-06-02 17:06:02 -07:00
aa09e0f5dd Update docs 2021-06-02 16:25:21 -07:00
d142579e97 Cleanup the format API 2021-06-02 16:25:21 -07:00
f286139d22 Fix "undefined reference to `fmt::v7::detail::basic_data<void>::digits'"
Remove unused FMT_EXTERN_TEMPLATE_API
2021-06-02 14:33:17 -07:00
7b9d69b827 Add xchar.h to docs 2021-06-02 08:19:54 -07:00
cbd861f188 Update docs 2021-06-02 08:06:52 -07:00
faf972f039 Update docs 2021-06-02 07:46:26 -07:00
622d1c0423 Update changelog 2021-06-02 07:36:27 -07:00
634c948769 Update changelog 2021-06-02 07:13:06 -07:00
a04e3a2dc8 Comment 2021-06-01 20:47:16 -07:00
87876d5474 Cleanup the printf implementation 2021-06-01 20:32:56 -07:00
d338d66324 Cleanup the printf implementation 2021-06-01 19:30:46 -07:00
272660e704 Remove deprecated printf functions 2021-06-01 18:08:31 -07:00
5a95c5ae2c Update changelog 2021-06-01 17:47:23 -07:00
70e67ae018 Re-enable module testing
Prepare for compilation with gcc (modules branch).
2021-06-01 14:49:56 -07:00
ad97258915 Merge branch 'master' of github.com:fmtlib/fmt 2021-06-01 13:38:26 -07:00
ed2a6377e7 Workaround msvc constexpr issues 2021-06-01 13:32:44 -07:00
9976869549 fix custom types formatting at compile-time, add test 2021-06-01 11:16:05 -07:00
8c1b22ba6d Workaround a gcc 9.1 bug (#2334) 2021-06-01 06:43:30 -07:00
2dba1cfac1 Update changelog 2021-05-31 19:19:09 -07:00
d7ba6c3ea8 Use qualified name-lookup in module. (#2324)
Allow lookup of non-exported names from local classes in function templates.
2021-05-31 09:11:24 -07:00
bf9904ee4d Workaround msvc bugs 2021-05-31 08:25:05 -07:00
577bce9029 Apply clang-format 2021-05-31 08:09:10 -07:00
ba4c7f193b Swap parameter order to match #2327 (#2329) 2021-05-31 07:44:33 -07:00
e9e89b355b Update ChangeLog.rst 2021-05-31 07:43:29 -07:00
9bb406d78d Update changelog 2021-05-31 07:37:10 -07:00
11a14db286 Update format_to taking a buffer and remove undocumented vformat_to overload 2021-05-30 07:57:51 -07:00
832ec098fc Fix argument order in locale overload of vformat_to (#2327) 2021-05-30 06:42:09 -07:00
486a80e8ef Move wchar_t overloads to xchar.h 2021-05-30 06:41:39 -07:00
19d45f4b31 Update changelog 2021-05-29 16:56:33 -07:00
5a2b88f6e9 Reduce binary size 2021-05-29 16:45:43 -07:00
00a39ad5f8 Enable Char types other than char (#2323) 2021-05-29 11:42:16 -07:00
ff37e41625 wchar.h -> xchar.h because it handles other code unit types too 2021-05-29 09:37:17 -07:00
0901176fe4 arg_join -> join_view 2021-05-29 08:47:16 -07:00
a9a9018191 Move wmemory_buffer to wchar.h 2021-05-29 08:26:04 -07:00
4a7801c3ec Update changelog 2021-05-29 08:14:25 -07:00
517578f80e Update changelog 2021-05-29 07:48:59 -07:00
85442ed045 Update changelog 2021-05-29 07:43:21 -07:00
6a12b13a85 Update changelog 2021-05-29 07:39:35 -07:00
1cfe3c7382 Update ChangeLog.rst 2021-05-29 07:30:47 -07:00
c06014792b Update changelog 2021-05-29 07:30:07 -07:00
6fe04871f4 Update changelog 2021-05-29 07:20:29 -07:00
9d67988aed FMT_DEPRECATED_WCHAR -> FMT_DEPRECATED_INCLUDE_WCHAR 2021-05-29 06:41:07 -07:00
765b451edd Update changelog 2021-05-29 06:15:49 -07:00
17c993c753 Fixed compilation with CMake < 3.7 (#2321) 2021-05-28 20:24:31 -07:00
dde6937319 Update changelog 2021-05-28 16:20:46 -07:00
272b0f36b3 More module tests (#2309)
core.h, format.h, args.h, chrono.h, color.h, printf.h, os.h
2021-05-28 15:49:39 -07:00
126c8cb46b Export os.h API, too (#2318) 2021-05-28 09:27:45 -07:00
98b9ff47a1 Align hex floats right as default (#2317) 2021-05-28 09:21:01 -07:00
ece4b4b33a Update changelog 2021-05-28 06:53:33 -07:00
a70a4ae053 Ignore zero-padding for non-finite floating points (#2310)
* Ignore zero-padding for non-finite floating points

* keep width for non-finite formatting with 0-padding

* clang-format

* preserve alignment

* align code-style
2021-05-27 14:13:05 -07:00
7612f18dc8 Update changelog 2021-05-27 07:06:13 -07:00
b9f2c27661 Update changelog 2021-05-26 21:12:03 -07:00
4e21baff43 Simplify get_units 2021-05-26 18:26:00 -07:00
683ef11ab9 Update changelog 2021-05-26 18:25:21 -07:00
ca466374bd qualify make_format_args (#2315)
Co-authored-by: John Melas <john@jmelas.gr>
2021-05-26 06:42:02 -07:00
5a2a185682 Make buffers non-movable 2021-05-25 17:30:17 -07:00
ee52a6dc40 add fmt::print() overload to support compiled format (#2304) 2021-05-25 14:54:56 -07:00
82607efb57 Fixed int conversion warning (#2313)
* Fixed int conversion warning

Compiler warns about conversion from int to size_t, thus added explicit cast.

* now using detail::to_unsigned for the cast
2021-05-25 08:13:39 -07:00
35a2c2a743 Refactor chrono formatting 2021-05-25 06:57:47 -07:00
b955e7a6b2 Refactor chrono formatting 2021-05-24 15:33:33 -07:00
883d9595c5 Support alternative locale names in tests 2021-05-24 14:09:19 -07:00
1f308a3cea Update integer presentation types documentation.
Documents that the 'c' type is a valid type for integer types. Since
boolean uses the same types as integer its documentation is
automatically updated.
2021-05-24 10:55:08 -07:00
1cd9899cf3 Add initial support for weekday formatting 2021-05-24 10:21:34 -07:00
069131dc25 Add unicode-test 2021-05-24 06:20:51 -07:00
dd8f38fcbb Cleanup printf API 2021-05-23 20:30:26 -07:00
a216f2562d Remove undocumented and obsolete vprintf overload 2021-05-23 20:15:02 -07:00
0c0926395d Add is_exotic_char trait 2021-05-23 19:50:17 -07:00
bc13c6de39 Update README.rst 2021-05-23 07:45:33 -07:00
8ec0b9e33b Do *not* export namespace detail 2021-05-23 06:49:07 -07:00
b99c2bd345 Remove deprecated locale.h from module interface unit 2021-05-23 06:17:25 -07:00
c04a24399a Update changelog 2021-05-22 20:55:56 -07:00
b099a56f9f Update changelog 2021-05-22 16:12:38 -07:00
703005c8ba Deprecate locale.h 2021-05-22 10:21:17 -07:00
51f0178625 Cleanup the format API 2021-05-22 07:09:09 -07:00
5d59dcf66e Remove deprecated aliases / undeprecate has_formatter 2021-05-22 06:53:34 -07:00
c242dd402c Move cerrno include to where it is used 2021-05-22 06:18:40 -07:00
2216e0b779 Update changelog 2021-05-22 06:04:33 -07:00
1c83a49be9 Simplify buffer extraction 2021-05-21 20:15:56 -07:00
2617384d8e Improve buffer extraction 2021-05-21 19:44:49 -07:00
34b8acaef7 More wchar_t-specific API to wchar.h 2021-05-21 18:24:39 -07:00
6326c18906 Improve code style consistency 2021-05-21 17:29:15 -07:00
5c4b0c86fb Add missing Allocator template argument for basic_memory_buffer in format_to
Remove deduced default template arguments in format_to and moves the
SFINAE check to a non-deduced template parameter.
2021-05-21 12:13:46 -07:00
00149c0b6a Move detail::null to chrono where it is used 2021-05-21 09:16:45 -07:00
c5c968cb22 Improve binary size 2021-05-21 08:50:35 -07:00
128cbdeb2f cmake: hide private symbols by default 2021-05-21 08:25:08 -07:00
18af1dc460 Fix binary size regression caused by b268f88 2021-05-20 18:33:45 -07:00
d1e6f0f8c6 Fix binary size regression caused by b268f88 2021-05-20 18:00:19 -07:00
5a0d99fa0b Add a test for the module 2021-05-20 10:26:31 -07:00
6e2e6b796f Restore support for wchar_t overloads in module 2021-05-20 10:03:58 -07:00
24b677d053 Improve symbol sizes 2021-05-20 07:21:20 -07:00
63271a51c4 Fix ADL issues 2021-05-20 06:31:43 -07:00
61b4c923d7 Reduce code bloat 2021-05-20 05:51:45 -07:00
2a2e4c5801 addressing nits. 2021-05-19 16:09:49 -07:00
be48f4d657 Avoid unwanted sign extensions from MSVC in is_utf8.
Microsoft's constexpr evaluator treats the type of micro[0] and micro[1] as
plain char, and so sign extends before comparing them to ints.
The normal compiler, including the optimizer, does not fail in this way,
so this is merely a "future proof" change in case someone uses is_utf8()
in a constant expression.
2021-05-19 16:09:49 -07:00
13e652939b export missed symbols
Enable `-fvisibility=hidden` and `-fvisibility-inlines-hidden` by default in CI builds to ensure all public symbols are exported correctly.
2021-05-19 16:03:45 -07:00
71fb113818 fix compile error on msvc preview 4 (16.10) involving lookup clash /w STL 2021-05-19 13:17:20 -07:00
08d22503bb Remove outdated comments 2021-05-19 11:47:21 -07:00
56f518a98f Update signatures 2021-05-19 09:45:33 -07:00
b7f2933744 Update signatures 2021-05-19 09:39:32 -07:00
7483dfc652 Update signatures 2021-05-19 09:36:12 -07:00
95c358f721 Improve separation between code unit types 2021-05-19 09:06:57 -07:00
39c3c4ec22 Simplify the core API 2021-05-19 08:32:57 -07:00
e9c1c415b8 Improve compile-time checks 2021-05-19 07:57:57 -07:00
21d93bfd33 Move generic format functions to format.h 2021-05-18 19:01:43 -07:00
9a92eb4158 Move more wchar overloads to wchar.h 2021-05-18 05:53:25 -07:00
0dd91e20d5 Add wchar.h for wide char overloads 2021-05-17 21:59:10 -07:00
ce14eafc24 Simplify format string checks 2021-05-17 19:25:50 -07:00
8d70c0edab Refactor the format API 2021-05-17 18:25:36 -07:00
813ac49543 More API cleanups 2021-05-17 07:58:13 -07:00
4ab01fb198 Cleanup printf API 2021-05-17 07:19:50 -07:00
d5036b11b1 Remove deprecated APIs 2021-05-17 06:59:46 -07:00
2581946231 Cleanup the core API 2021-05-16 13:02:01 -07:00
b35db4e006 Improve handling of 128-bit ints 2021-05-16 11:43:44 -07:00
d35f1ad5c1 Cleanup core 2021-05-16 10:02:33 -07:00
8f1902c05a Move format string checks to core.h 2021-05-16 07:08:49 -07:00
6469b9037c Silence msvc warning about an unused named parameter
Warning C4100 may cause compile failures under strict warning regimes.
2021-05-16 06:14:30 -07:00
7d4c92fb00 Update ChangeLog.rst 2021-05-15 17:19:27 -07:00
0763d8cadf Fix Visual Studio warning 2021-05-15 17:13:15 -07:00
5466373a11 Do *not* export namespace detail
Introduce `FMT_BEGIN_DETAIL_NAMESPACE` and `FMT_END_DETAIL_NAMESPACE` for `namespace detail` sections embedded in that part of the code that contains all declarations that are exported from the module, i.e. which is enclosed by `FMT_MODULE_EXPORT_BEGIN` and `FMT_MODULE_EXPORT_END`. Given a correct implementation of C++20 modules, neither the name `fmt::detail` nor any of its contents will become visible outside of the module.
2021-05-15 12:08:42 -07:00
588bdb5404 Simplify get_arg_index_by_name 2021-05-15 06:47:43 -07:00
54f22a3eef add support for statically named arguments with FMT_STRING 2021-05-14 16:31:10 -07:00
ea94d6d93c Prevent ambiguity in name lookup
Unqualified calls to 'make_format_args' may find the same name by ADL in <format> if this C++20 header happens to be directly or indirectly included in a translation unit. Do a qualified lookup instead.
2021-05-14 07:10:02 -07:00
57280762b6 Move specs checker to core.h 2021-05-13 19:33:09 -07:00
ced3037523 Move dynamic specs to core.h 2021-05-13 19:01:21 -07:00
dd2bc998ab Move specs to core.h 2021-05-13 18:48:15 -07:00
08da1adcf6 Remove unused headers 2021-05-13 17:58:15 -07:00
3be0cc2087 Fix handling of 128-bit ints 2021-05-13 17:53:23 -07:00
9648bdce30 add missing header 2021-05-13 05:39:18 -07:00
d1aebdbde0 Inline format_to 2021-05-12 18:07:59 -07:00
8f0fadfaaa Cleanup docs 2021-05-11 20:20:03 -07:00
02896dabee Avoid use after move (#2278) 2021-05-11 16:58:07 -07:00
0036a1d195 Fix issue #2274. 2021-05-10 15:57:23 -07:00
2a9b314627 Replace fmt::error_code to std::error_code 2021-05-09 12:26:19 -07:00
2165bef4ca Update README.rst 2021-05-09 09:35:44 -07:00
4862930845 Optimize format string compilation 2021-05-09 09:15:55 -07:00
3207a8bbbf Get rid of unnecessary recursion to enable inlining 2021-05-09 07:54:13 -07:00
6214f15a0c Optimize standard formatter specialization 2021-05-09 07:11:35 -07:00
cd2c78fb8a Use write directly in formatter specializations 2021-05-09 07:07:51 -07:00
4211d86539 Add a formatter specialization for std::error_code. 2021-05-09 06:29:39 -07:00
39f28424ca Cleanup tests 2021-05-07 21:27:58 -07:00
84feeb0f36 Remove redundant comments and put common case check first 2021-05-07 17:14:29 -07:00
2665afb515 Cleanup add-subdirectory-test 2021-05-07 16:42:02 -07:00
d0abe7c246 Make chrono formatting locale-independent by default 2021-05-07 16:14:10 -07:00
50fb0b5eae Fix formatting 2021-05-07 08:52:49 -07:00
16f2ef91ab Replace fmt::system_error with std::system_error 2021-05-07 08:33:39 -07:00
4b885c8633 Replace windows_error with system_error 2021-05-07 06:19:03 -07:00
5238055f40 Move esoteric char type support to format.h 2021-05-06 09:02:00 -07:00
9ac088f376 Add fmtlog to projects 2021-05-06 08:39:36 -07:00
849c9f6168 Move is_name_start to core 2021-05-06 08:12:24 -07:00
23892caf53 Move more parsing to core 2021-05-06 07:37:40 -07:00
8e6390c32c Move FMT_STRING to core 2021-05-06 07:19:41 -07:00
51a33713fc Move parsing to core 2021-05-06 07:01:29 -07:00
9c3af11a92 Cleanup tests 2021-05-05 18:31:41 -07:00
9d7b53cb9b Remove redundant formatter specialization for byte 2021-05-05 08:14:12 -07:00
f0095ccd34 Add support for ranges of types without formatters to join (#2262) 2021-05-05 07:43:46 -07:00
4f0eadfce4 Exclude fallback from is_formattable 2021-05-05 06:29:51 -07:00
400b953fbb Use [] instead of {} in ranges for consistency with Python format 2021-05-04 21:04:21 -07:00
38bcc04a11 Drop range limit and cleanup tests 2021-05-04 20:53:56 -07:00
c738c3431f Cleanup tests 2021-05-04 17:23:13 -07:00
ed7c4320f6 Cleanup tests 2021-05-02 09:28:38 -07:00
9155e2de4c Cleanup tests 2021-05-01 17:11:45 -07:00
38127d9ec0 Cleanup tests 2021-04-30 15:50:03 -07:00
c9c0e5077d Cleanup tests 2021-04-30 06:42:38 -07:00
ccf4ccde23 Cleanup tests and format string compilation 2021-04-29 19:50:04 -07:00
e96a92f869 Cleanup tests and format string compilation 2021-04-29 16:21:08 -07:00
fd43e4dcbc gtest: fix std::is_trivially_copy_constructible for GCC 4.8 & 4.9 properly
`std::is_pod<T>` was deprecated in C++20

original (pre `is_pod`) error on GCC 4.8:
```
/fmt/test/gtest/gtest.h: In static member function 'static constexpr bool testing::internal::MatcherBase<T>::IsInlined()':
/fmt/test/gtest/gtest.h:6512:12: error: 'is_trivially_copy_constructible' was not declared in this scope
            std::is_trivially_copy_constructible<M>::value &&
            ^
/fmt/test/gtest/gtest.h:6512:45: error: expected primary-expression before '>' token
            std::is_trivially_copy_constructible<M>::value &&
                                                  ^
/fmt/test/gtest/gtest.h:6512:46: error: '::value' has not been declared
            std::is_trivially_copy_constructible<M>::value &&
                                                   ^
```
2021-04-29 07:11:49 -07:00
3d51ccdaae gtest: remove obsolete GTEST_LANG_CXX11 compile definition setting 2021-04-29 07:11:49 -07:00
833377ff1e gtest: add .clang-format file into test/gtest directory to prevent formatting there 2021-04-29 07:11:49 -07:00
53ca0cbe75 gtest: move GTest/GMock files to separate directory, update GTest/GMock usages
* all GTest/GMock files moved to `test/gtest` directory
* `CMakeLists.txt` created in `test/gtest` from `CMakeLists.txt` in `test`
* GTest/GMock target in CMake renamed to `gtest` (was `gmock`)
* CMake `gtest` target updated to export includes as "gtest/gtest.h" or "gmock/gmock.h" only
* includes in tests updated: "gtest.h" -> "gtest/gtest.h", "gmock.h" -> "gmock/gmock.h"
* removed duplications of `target_include_directories` for GTest/GMock directories (CMake manages them)
2021-04-29 07:11:49 -07:00
342973b349 Make wchar_t overloads usable in module
Bring ''detail::find()' into scope.
2021-04-28 09:37:57 -07:00
355be4b13f Make FMT_COMPILE fallback on runtime without if constexpr (#2261) 2021-04-28 09:11:47 -07:00
0cd0fb9184 C++17: std::char_traits<>::{compare,length} is constexpr - v2 2021-04-28 07:05:32 -07:00
d1a6e5603f Keep defaulted destructors inline
applies to exception classes in case of msvc only
2021-04-28 06:17:26 -07:00
84a36b99bf Move data to functions 2021-04-27 17:21:32 -07:00
ab7c33ede0 Suppress checked iterator warnings 2021-04-27 13:54:39 -07:00
77258f6069 fix FMT_CONSTEXPR_CHAR_TRAITS check for MSVC 2021-04-26 16:35:32 -07:00
d23e315ea2 CI windows: add MSVC C++20 build 2021-04-26 16:35:32 -07:00
f085c3d7a0 use proper check for non-type template parameters 2021-04-26 16:35:32 -07:00
69bdc20a3c Workaround missing std::system on iOS, take 2 2021-04-26 06:21:44 -07:00
847aac4315 Follow naming conventions in tests 2021-04-25 21:26:30 -07:00
39818e7979 Cleanup core-test 2021-04-25 17:59:23 -07:00
0e6f989b0d __THROW warning fix for e2k (#2253) 2021-04-25 08:51:37 -07:00
1678ed6235 simplify field::format() and spec_field::format(), fix typo 2021-04-25 07:53:49 -07:00
ca821982ee use named arg with static name in compile-time API
to get arg index by name at compile-time
2021-04-25 07:53:49 -07:00
ce6e7d8620 use fixed_string to create named arg class with static name for _a literal 2021-04-25 07:53:49 -07:00
fc56af14c2 move fixed_string from compile.h to format.h 2021-04-25 07:53:49 -07:00
bb006f9735 Replace TYPED_TEST_CASE with TYPED_TEST_SUITE 2021-04-24 17:46:49 -07:00
6956b10b2d Fix gcc 4.8 build 2021-04-24 11:04:34 -07:00
b4f9a05894 Update gtest 2021-04-24 11:03:40 -07:00
8f9ddf452d Remove deprecated posix.h 2021-04-24 07:03:11 -07:00
dacd1356e4 Add module interface unit 2021-04-24 06:39:57 -07:00
d3c523e0d2 Export printf-related contexts from printf.h 2021-04-24 06:39:57 -07:00
2c25df089f Export replacement type_traits, too 2021-04-24 06:39:57 -07:00
553022dc56 Don't use std::system on iOS (#2248) 2021-04-24 06:17:05 -07:00
8a040d187a Cleanup core-test 2021-04-23 20:07:48 -07:00
064cac2bf9 Bump version 2021-04-23 16:05:03 -07:00
5b2c740ad8 Remove deprecated APIs 2021-04-23 15:27:25 -07:00
b9ab5c8836 Remove printf.h dependency on ostream.h 2021-04-23 10:42:57 -07:00
c47f211296 Simplify data handling 2021-04-23 06:52:10 -07:00
54d3b1710e Move more data out of basic_data 2021-04-23 06:45:23 -07:00
128f007b25 C++17: std::char_traits<>::{compare,length} is constexpr. (#2246) 2021-04-23 06:11:34 -07:00
841aad95b4 Move data out of basic_data 2021-04-22 15:29:42 -07:00
1d4199f46b fix udl_compiled_string with non-byte chars (e.g. wchar) (#2242) 2021-04-19 08:29:35 -07:00
c5d4fcb119 Appending a space to guarantee non-empty strftime() result. (#2244) 2021-04-18 19:13:51 -07:00
6271406233 Fix a warning (#2233) 2021-04-16 15:58:17 -07:00
52bd62c72f Create separate dllexport marking points for clang and msvc. (#2229)
* add FMT_INSTANTIATION_DEF_API for msvc

This should fix https://github.com/fmtlib/fmt/issues/2228

To fix difference dllexport requirements
msvc:  dllexport at template instantiation definition in format.cc
clang: dllexport at template instantiation declaration (extern template) in format.h
2021-04-16 12:34:18 -07:00
f4bbc54cc4 Tag official API for module export (#2235)
* functions
 * classes
 * UDLs
 * other declarations

Export everything in namespace 'fmt' from core.h and format.h
2021-04-16 11:04:55 -07:00
d8910af80d Use qualified name lookup rather than ADL. (#2239)
Name lookup within exported templates cannot find non-exported entities by ADL when instantiation takes place outside the module.
2021-04-16 09:38:25 -07:00
9260114162 Ranges wide strings support (#2236)
* Ranges copy wchar_t

* arg_join formatter not working for wide strings

* Added ranges wide string tests

Co-authored-by: Cristi <cristi@emailaddressmanager.com>
2021-04-16 06:25:35 -07:00
24c9751558 Try to suppress MVSC warn of narrowing (#2230) 2021-04-13 07:30:43 -07:00
a1c6bfd77b Add a link to llvm diff 2021-04-12 10:05:14 -07:00
42eccac454 Fix clang warning about ignoring __declspec(dllexport) on basic_data<void> template instantitation definition (#2220) 2021-04-12 09:31:44 -07:00
aec504344a Update README.rst 2021-04-10 08:48:11 -07:00
0b41145443 Update README.rst 2021-04-10 08:31:47 -07:00
00f3d16b12 Update docs 2021-04-10 08:07:16 -07:00
99c2f7a349 Allow including fmt/core.h in the header-only mode 2021-04-10 07:44:36 -07:00
b441532396 CI linux: add clang++-11 C++20 (with LLVM libc++) build
* find-package-test fixed by passing CXX_FLAGS, i.e. -stdlib=libc++
 * std::array usage in compile-test.cc replaced with plain array, because
   <array> header was not included
2021-04-10 07:20:05 -07:00
1dbadb6527 CI linux: add clang++-11 C++20 build 2021-04-10 07:20:05 -07:00
09dbad47e1 CI linux: add missing build_type
for g++-8 C++14, g++10 C++17, g++10 C++20
2021-04-10 07:20:05 -07:00
e2facffe4d CI linux: remove excessive clang++-9 include 2021-04-10 07:20:05 -07:00
273d8865e3 Suppress redef warning of _CRT_SECURE_NO_WARNINGS if any. (#2218) 2021-04-08 11:56:35 -07:00
5a8bf1f6a3 Workaround hexfloat inconsistency on windows (#2205) 2021-04-07 11:20:08 -07:00
78776ee4e2 Fix a conditional expression is constant warning #2210 (#2211) 2021-04-07 10:42:11 -07:00
266107f57c constexpr uint128_wrapper (#2215)
* constexpr uint128_wrapper

* change FMT_CONSTEXPR to constexpr

* clang format

Co-authored-by: Jake Staahl <jstaahl@snapchat.com>
2021-04-06 22:07:01 -07:00
2e0d64cf2f specify size for prefixes static data 2021-04-06 17:07:14 -07:00
95da484727 Fix a link 2021-04-03 09:14:52 -07:00
06b3a1000c Add support for time points with arbitrary durations (#2208) 2021-04-02 11:17:14 -07:00
dac42f52b2 Inline fallback is_constant_evaluated 2021-04-01 10:42:09 -07:00
7c43f8b896 Don't use strlen at compile time (#2205) 2021-04-01 10:04:21 -07:00
c62e4c30f4 Make buffer_appender default-constructible when back_insert_iterator is 2021-04-01 09:52:44 -07:00
0d6b70d96b Install gcc 8 2021-04-01 09:19:36 -07:00
15c10b0c66 Add speech synthesis support 2021-04-01 09:19:36 -07:00
308510eb4f "Use" fwrite result (workaround for warn_unused_result)
Fixes #2185
2021-03-31 08:31:35 -07:00
afe23e7f10 Don't call fileno on NULL file in tests (#2196) 2021-03-30 10:41:12 -07:00
b49af043d7 Remove noexcept from file's move assignment 2021-03-30 09:51:25 -07:00
14848875bf Fix: fmt::ostream cannot be moved while holding buffered data #2197 (#2198)
* Add a test case: move ostream while holding data

* Fix moving ostream while holding data

Co-authored-by: Junliang HU <jlhu@cse.cuhk.edu.hk>
2021-03-30 08:43:26 -07:00
7d8c34018e Update pull_request_template.md 2021-03-30 08:42:11 -07:00
b966afcc7a Remove formattable 2021-03-28 14:21:12 -07:00
ec5315a987 Use strlen when possible in fallback basic_string_view 2021-03-28 08:01:55 -07:00
4f8778bab9 Inline basic_format_args's ctor 2021-03-28 07:32:17 -07:00
e2d87548f8 user-defined constructor
user-defined constructor added to prevent Intel compilers
warnings. According to the standard, objects need to have a
user-defined constructor if instances are delcared const.
2021-03-28 06:56:14 -07:00
f7151d384b Extra flag to prevent Intel compiler with Clang front-end warning of 'unknown attribute no_sanitize' 2021-03-28 06:56:14 -07:00
0fb8ef8f79 Inline trivial argument handling functions 2021-03-27 19:05:39 -07:00
1b23e25f95 Simplify formattability check 2021-03-27 18:57:18 -07:00
35c71ff536 Only use -Og with optimizations disabled 2021-03-27 11:35:01 -07:00
243d8bebd1 Enable minimal optimizations in debug mode 2021-03-27 08:40:07 -07:00
9b34681d97 Work around xl compiler bug when nvcc preprocesses this file (#2190) 2021-03-27 06:05:49 -07:00
4dc7170d21 Fix C++17 builds: (#2192)
- Fix C++17 Visual Studio builds.
- Use C++17 for `windows-2019` builds.
- Removed options for unsupported compiler (MSVC11).
- Removed options, not needed after enabling C++11+ features in gmock/gtest.
2021-03-26 06:19:43 -07:00
9cb347b4b2 Simplify argument formatters 2021-03-21 09:31:46 -07:00
0f85a4683a add default cases (#2186)
Adding default case for switch statements where the compilation
flag -Wswitch-default is present on the command line when spdlog
is included in external projects.

Signed-off-by: Ryan Sherlock <ryan.m.sherlock@gmail.com>
2021-03-19 16:56:52 -07:00
417e1cee9e Stop using deprecated UDL templates 2021-03-19 08:34:55 -07:00
f7e900e12e Simplify UDL definitions 2021-03-19 08:10:58 -07:00
d9661c8f3b Mark grouping as deprecated 2021-03-19 07:54:57 -07:00
14a2a64df4 Fix handling of formattable types with to_string_view (#2181) 2021-03-19 06:43:38 -07:00
6ae402fd0b Fix handling of types with to_string_view and formatter specialization (#2180) 2021-03-18 11:25:43 -07:00
a6408a3b09 Add args-test 2021-03-18 09:04:17 -07:00
1147782c79 Fix an ambiguous call to check caused by ADL (#2184) 2021-03-17 20:59:36 -07:00
VZ
2f3f3862fa Fix harmless MSVS warning about using undefined _MANAGED symbol (#2183)
Since the changes of 1305cbeb (Fix MSVC2019 error C2049 when compiling
with /clr (#1897), 2020-09-23), compiling fmt with MSVS 2019 resulted in

fmt\include\fmt\core.h(180,32): warning C4668: '_MANAGED' is not defined
as a preprocessor macro, replacing with '0' for '#if/#elif'.

when the (disabled by default) warning C4668 was enabled.

Fix this simply by checking if _MANAGED is defined before testing it.
2021-03-17 11:21:50 -07:00
d0bded5988 Fix MSVC /clr builds (#2179) 2021-03-15 08:17:28 -07:00
8308f52c2a Fix dynamic_format_arg_store::push_back comment 2021-03-15 07:10:28 -07:00
6151d0dc1e Fix the comment 2021-03-14 09:26:18 -07:00
5a1127b726 Don't wrap named arg in cref and clarify docs 2021-03-14 09:08:08 -07:00
b8ff3c1820 optimize append (#2164) 2021-03-13 07:21:23 -08:00
c8d8b88223 fix GCC 7,8,9 warning about unused but set parameter (#2177) 2021-03-13 06:36:53 -08:00
d28101878a Document ostream support limitation 2021-03-12 15:49:22 -08:00
bac14ef985 Simplify integer spec checking 2021-03-12 15:02:01 -08:00
8f9db3fcb8 Make ubsan happy on empty format specs (#2175) 2021-03-12 09:13:47 -08:00
af567538a0 Bitpack integral prefixes 2021-03-11 21:22:33 -08:00
cdf877d4b1 Workaround missed optimization opportunity 2021-03-11 16:44:59 -08:00
eef4ba9c02 Optimize integer formatting without padding 2021-03-11 15:47:58 -08:00
a1ea8a82c3 Unbloat my heart 2021-03-11 08:27:53 -08:00
a457e16360 Simplify integer formatter 2021-03-11 08:14:03 -08:00
05bc87a66f Optimize padding 2021-03-10 17:59:36 -08:00
605b603735 Optimize count_digits for powers of 2 2021-03-10 14:48:07 -08:00
85ba271639 Implement 128-bit count_digits in terms of count_digits_fallback 2021-03-10 12:57:46 -08:00
d9835737f0 spec -> specs 2021-03-10 12:51:03 -08:00
f9e0e90441 Apply clang-format 2021-03-10 12:08:02 -08:00
60f5d24411 Simplify arg_formatter 2021-03-10 09:35:48 -08:00
30e1302e73 Simplify on_format_specs 2021-03-10 08:46:16 -08:00
87c5cd46ac Optimize parsing of argument ids 2021-03-10 07:04:04 -08:00
6a9016ea60 fix formatted_size with "compiled format" as argument (#2161) 2021-03-07 06:44:36 -08:00
6e1fc01752 Move detail::truncating_iterator to fmt/compile.h 2021-03-06 08:35:36 -08:00
e718ec3e93 Make truncating_iterator an output_iterator (#2158) 2021-03-04 15:53:08 -08:00
772aeca338 Don't include <cassert>. (#2148) (#2152)
* Don't include <cassert>. (#2148)

This commit replaces use of the assert() macro in format-inl.h with
FMT_ASSERT(). This allows us to drop the cassert include.

* FMT_GCC_VERSION is not defined when we include test-assert.h, use __GCC__ instead.

* Don't explicitly suppress GCC's -Wterminate in tests' FMT_ASSERT.

Throwing from a separate function is enough to silence the warning, no need to
explicitly suppress it.

* Remove messages from assertions added in 2f699d2.

* Correct formatting around throw_assertion_failure().
2021-03-04 07:28:04 -08:00
684b5b0e40 Fix fallback to runtime API from compile-time API (#2143)
* fix fallback to the runtime API, add FMT_ENABLE_FALLBACK_TO_RUNTIME_API define, add test

* remove `FMT_ENABLE_FALLBACK_TO_RUNTIME_API`

* pass format string to format_to() inside format_to_n() in compile-time API

instead of compiling it inside format_to_n(), to eliminate code duplication
2021-03-04 07:20:57 -08:00
d8b9254301 use simplified void_t for all compilers other than gcc 4.x (#2160) 2021-03-02 14:42:27 -08:00
835b910e7d Add an is_formattable trait 2021-02-28 15:25:33 -08:00
578874033a Revert "Optimize handling of integer constants" (#2147)
This reverts commit 2797588be1.
2021-02-25 05:58:58 -08:00
640acba850 Print x.what() of FMT_THROW when exception is disabled (#2145)
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
2021-02-24 06:29:04 -08:00
d8e1c9f175 fix fmt::get for some GCC versions and legacy Clang (#2144)
fixes https://github.com/fmtlib/fmt/issues/2140

- some GCC versions decay function pointers to `const void*`, exactly like
  MSVC does
- legacy Clang (prior to 7.0) treats function pointers also as `const T*`
  pointers, but unable to convert them
2021-02-23 07:18:30 -08:00
2797588be1 Optimize handling of integer constants 2021-02-21 11:11:57 -08:00
e8eff3b8fd Fix FMT_STATIC_THOUSANDS_SEPARATOR (#2142) 2021-02-21 07:42:12 -08:00
ab0f7d7fdc use const& for arguments 2021-02-20 11:50:12 -08:00
29cc8282b1 update chrono duration formatter (constness), use it in compile-test for specs checks 2021-02-20 11:50:12 -08:00
3f69af3aaf update wording in the error inside arg_id_handler, use FMT_ASSERT instead of throw 2021-02-20 11:50:12 -08:00
499047e132 fix incorrect indexing mode for named args, update tests 2021-02-20 11:50:12 -08:00
78c67157c1 prepare tests, fix incorrect handling of named args with simple {} replacement fields 2021-02-20 11:50:12 -08:00
b31bc2dc9f simplify try_format_argument(), make manual_indexing_id() a variable 2021-02-20 11:50:12 -08:00
95e1aa2dc5 add support for manual indexing and named fields, add tests 2021-02-20 11:50:12 -08:00
7e72673d87 Improve width estimation (#2033) 2021-02-13 09:30:29 -08:00
13b117b5bc Improve code point computation 2021-02-13 08:46:19 -08:00
ee0fed639c Fix handling of the + flag with locales (#2133) 2021-02-13 07:08:01 -08:00
c5979d564e Fix fmt::localtime formatting not working in wide-char string contexts 2021-02-13 06:53:30 -08:00
e6ef927e6b fmt::ptr: Support function pointers (#2131)
Passing a function pointer to fmt::ptr results in:

 In file included from /home/mac/git/fmt/test/gmock/gmock.h:238,
                  from /home/mac/git/fmt/test/format-test.cc:31:
 .../fmt/test/format-test.cc: In member function ‘virtual void FormatterTest_FormatPointer_Test::TestBody()’:
 .../fmt/test/format-test.cc:1486:56: error: no matching function for call to ‘ptr(void (&)(int, double, std::__cxx11::string))’
              format("{}", fmt::ptr(function_pointer_test)));

with GCC and Clang. Let's add an overload to support that usage.

Unfortunately, MSVC would
consider the overload to be ambiguous for unknown reasons:

 D:\a\fmt\fmt\test\format-test.cc(1485,1): error C2668: 'fmt::v7::ptr': ambiguous call to overloaded function [D:\a\fmt\build\test\format-test.vcxproj]
 D:\a\fmt\fmt\include\fmt/format.h(3742,60): message : could be 'const void *fmt::v7::ptr<void,int,double,std::string>(T (__cdecl *)(int,double,std::string))' [D:\a\fmt\build\test\format-test.vcxproj]
           with
           [
               T=void
           ]
 D:\a\fmt\fmt\include\fmt/format.h(3735,42): message : or       'const void *fmt::v7::ptr<void(int,double,std::string)>(T (__cdecl *))' [D:\a\fmt\build\test\format-test.vcxproj]
           with
           [
               T=void (int,double,std::string)
           ]
 D:\a\fmt\fmt\test\format-test.cc(1486,1): message : while trying to match the argument list '(overloaded-function)' [D:\a\fmt\build\test\format-test.vcxproj]

but luckily this means that the overload is unnecessary in that case
anyway, so we can just make it conditional.
2021-02-09 07:35:16 -08:00
58aa04573f Fix ordering of install commands for CMake (#2122)
the library itself needs to be installed before
the fmt-targets.cmake file is installed,
otherwise the installed targets file doesn't
actually point to the library using
IMPORTED_LOCATION
2021-01-30 09:03:55 -08:00
1980ca8c4e fix #2118: FMT_COMPILE did not work with tm formatter (#2119)
Co-authored-by: summivox <summivox@github.com>
2021-01-30 08:44:49 -08:00
2a25e2bf4d Make ranges-test available with C++11 (#2114)
* make ranges-test available with C++11, fix problem with some gcc versions

* potentially fix build for MSVC 19.10, a bit reorganizing in test
2021-01-30 07:42:58 -08:00
b0b56b4379 fix #2116 (FMT_COMPILE requires exceptions enabled) (#2117)
Co-authored-by: summivox <summivox@github.com>
2021-01-28 06:58:49 -08:00
373262f9fb Update docs 2021-01-24 09:11:44 -08:00
ce519e939b Fix exception propagation from iterators (#2097) 2021-01-23 17:27:24 -08:00
acef0bb51a use gcc-10.2 instead of gcc-10.1 on CI, also fix one problem (#2110)
the problem was not detected by test because of wrong gcc-10 minor version on CI
2021-01-23 07:52:41 -08:00
8bf28e6bb1 Add support for s format specifier to bool (#2094) (#2109) 2021-01-23 07:32:41 -08:00
9c418bc468 Update README.rst 2021-01-21 07:45:34 -08:00
456efa4666 add missing detail namespace (#2107)
Co-authored-by: Walter Gray <walter.gray@getcruise.com>
2021-01-19 17:44:15 -08:00
80dc7cceb8 Fixed format.h(1465): warning C4702: unreachable code (#2106)
* Fixed format.h(1465): warning C4702: unreachable code

* Fixed format.h(1416): warning C4702: unreachable code
2021-01-19 17:13:10 -08:00
7fd535c6ae Cleanup 'L' handling 2021-01-18 07:57:38 -08:00
b4b8917caf Update docs 2021-01-17 09:36:06 -08:00
e4f2cf455e Make 'L' a modifier 2021-01-17 09:28:46 -08:00
6972b5f3d2 Add build variable: FMT_MASTER_PROJECT (#2100) 2021-01-16 16:56:49 -08:00
ac35208115 Install fmt/args.h (#2096) 2021-01-16 08:13:38 -08:00
532e846b86 Fix width computation in float formatter 2021-01-15 11:07:55 -08:00
f8c2f8480a Fix handling of width when formatting int as char 2021-01-14 08:41:17 -08:00
0fe0b15e71 Fix handling of # in width computation 2021-01-13 16:48:07 -08:00
061e364b25 Document output_file 2021-01-09 07:18:56 -08:00
018688da2a Correct a typo on syntax.rst (documentation) (#2081) 2020-12-31 16:23:42 -08:00
9ec5592bb5 Fix writing to stdout when redirected to NUL on Windows (#2080) 2020-12-30 13:23:37 -08:00
cdc5ef6710 Remove fallback to inline specifier from FMT_CONSTEXPR(20) macro (#2075) 2020-12-30 06:23:20 -08:00
c9dd1eb97d Don't change charset 2020-12-27 07:44:02 -08:00
d09b5c1453 Fix std::byte formatting with compile-time API (#2072)
* add test for byte formatting with `FMT_COMPILE`

* fix byte formatting with `FMT_COMPILE`, use `__cpp_lib_byte` macro

* use is not custom mapped type check

* workaround MSVC bug
2020-12-27 07:23:28 -08:00
bbd6ed5bc5 Add support of most format_specs for formatting at compile-time (#2056) 2020-12-25 06:40:03 -08:00
a750bf3ac6 Update api.rst 2020-12-24 07:09:49 -08:00
1256541d7a Fix formatting 2020-12-24 07:07:15 -08:00
4fa4c9248f Add tests for FMT_ENFORCE_COMPILE_STRING, fix several errors (#2038) 2020-12-24 06:40:46 -08:00
aa89e380d9 add cwchar to format.h for std::fputws (#2073) 2020-12-23 07:02:25 -08:00
5a37e182de Disable warning about format string (#2067)
Reported by MinGW/GCC 10
2020-12-21 08:43:30 -08:00
fa43fd1444 Forward arguments to work with views (#2068) 2020-12-20 07:14:54 -08:00
3551f5d118 Workaround a gcc 10 -Warray-bounds bug (#2065) 2020-12-19 09:34:43 -08:00
e737672614 Remove an old mingw workaround (#2059) 2020-12-10 06:36:04 -08:00
25a41b80fc Fix a link to Android.mk (#2057) 2020-12-09 08:04:58 -08:00
9293f7072e Suppress gcc warning on privates-only class (#2053)
Since gcc 9 it warns about is_streamable to have only private methods.
Add explicit default ctor instead of suppression
2020-12-09 06:55:17 -08:00
c20874c28f Reenable support for fallback formatter in join (#2040) (#2050) 2020-12-08 08:56:53 -08:00
5de0bc1d4f Add UDL as replacement for FMT_COMPILE (#2043) 2020-12-07 15:53:11 -08:00
a6fafe2f01 docs: use https for some links (#2051) 2020-12-05 06:41:38 -08:00
33f9a6d360 Fix handling of enums in to_string (#2036) 2020-12-03 15:18:33 -08:00
aabe0a8473 simplify tests by reordering arguments of EXPECT_EQ (#2044) 2020-12-03 14:21:23 -08:00
1f4a76d2c8 Add a missing include (#2047) 2020-12-03 14:17:09 -08:00
4a6eadbde0 Make std::byte formattabe (#1981) 2020-12-03 08:59:07 -08:00
683a74501f fix formatting with empty compiled format string (#2042) 2020-12-02 07:14:57 -08:00
f43416e1d7 Add a link to contents from index 2020-12-02 06:30:09 -08:00
5a493560f5 Move some code from core.h to format.h where it is used 2020-11-29 09:45:15 -08:00
9ed0a98178 Fix docs build 2020-11-29 09:33:09 -08:00
dac753b81e Basics of formatting at compile-time based on compile-time API (#2019) 2020-11-29 08:59:11 -08:00
119f7dc3d6 Truncate file by default 2020-11-27 08:15:14 -08:00
22a68d1613 Don't emit trailing zeros by default 2020-11-27 07:45:54 -08:00
d0110b7e35 Update README.rst 2020-11-26 19:51:31 -08:00
3f4839ce3d Merge branch 'release' of github.com:fmtlib/fmt 2020-11-25 06:41:05 -08:00
7bdf0628b1 Update version 2020-11-24 17:15:02 -08:00
fc1355114d Update changelog 2020-11-24 17:14:00 -08:00
926233bde8 Fix test 2020-11-24 14:54:15 -08:00
0683fa7d1d Bump version 2020-11-24 08:36:21 -08:00
6ce207b9a5 Fix formatting 2020-11-24 08:29:17 -08:00
07b1c1a15f Update changelog 2020-11-24 08:24:14 -08:00
58992761cf Reintroduce ostream support to range formatters (#2014) 2020-11-24 08:22:29 -08:00
b8957f50c3 Fix an overflow in format_to_n (#2029) 2020-11-24 08:22:12 -08:00
df66516ed3 Workaround an issue with mixing std versions in gcc (#2017) 2020-11-24 08:21:10 -08:00
a57baa69a5 Fix more linkage errors (#2011) 2020-11-24 08:17:31 -08:00
85534a1397 Fix linkage errors when linking with a shared library (#2011) 2020-11-24 08:15:59 -08:00
a2fa5d6288 Update changelog 2020-11-23 10:35:07 -08:00
cd3003683d Fix more linkage errors (#2011) 2020-11-23 10:34:27 -08:00
d1ef29d679 Fix initialization of iterator_buffer (#1996) 2020-11-23 10:28:35 -08:00
5f41bb0f77 clang-format 2020-11-23 10:23:54 -08:00
a58a6b27c3 Add a newline 2020-11-21 16:52:40 -08:00
a036cc97b7 Reintroduce ostream support to range formatters (#2014) 2020-11-21 16:31:22 -08:00
38c7def47a Update clang version to 3.4 since there are ICEs on earlier ones 2020-11-19 10:37:43 -08:00
5533641319 🆕 [CI] Test with C++14 in Windows 2019 (#2020)
Problem:
- Both Windows builds test C++14

Solution:
- Use C++11 for `windows-2016` builds and C++14 for `windows-2019`
  builds.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
2020-11-19 06:04:16 -08:00
55dfdd9299 Update README.rst 2020-11-18 07:33:38 -08:00
2c734c9bca Fix an overflow in format_to_n (#2029) 2020-11-18 06:50:43 -08:00
6cdd1be93e Update build.gradle for latest AGP (#2026)
* update build.gradle for latest AGP

* bump Android Gradle Plugin version to 4.1.1
* ignore .cxx which was externalNativeBuild in old versions

Use variable 'rootDir' instead of using relative path.

* build.gradle copies AAR files to libs/
2020-11-17 06:31:06 -08:00
bcc20b29df Implement compile-time checks by default 2020-11-15 17:24:36 -08:00
befd7d4a2f Always use FMT_STRING internally where possible [Issue #2002] (#2006)
Co-authored-by: Walter Gray <walter.gray@getcruise.com>
2020-11-15 05:19:06 -08:00
f8640d4050 Add more standards 2020-11-14 12:02:46 -08:00
f81c14aa1e Workaround an issue with mixing std versions in gcc (#2017) 2020-11-14 11:41:51 -08:00
5555651ce0 Fix more linkage errors (#2011) 2020-11-14 06:06:10 -08:00
b268f8815d detail::write in one more place relevant to printf with long argument… (#2016) 2020-11-13 12:14:16 -08:00
aa9b09a9e3 🐛 Cannot call non-constexpr function in constexpr context (#2010)
Problem:
- gcc-8 gives the following error when compiling this function on all
  standards:
    test/std-format-test.cc: In member function 'constexpr auto std::formatter<S>::parse(std::format_parse_context&)':
    test/std-format-test.cc:112:17: error: call to non-'constexpr' function 'int isdigit(int)'
        if (!isdigit(c) || (++iter, get_char()) != '}')
         ~~~~~~~^~~

Solution:
- Write a `constexpr` version of `isdigit` for use in this function.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
2020-11-12 10:10:52 -08:00
986fa00406 Printf get container (#1982)
* eliminate one case where basic_print_context would copy a string into a fmt::basic_memory_buffer character by character instead of using fmt::basic_memory_buffer::append

* use detail::write instead of re-implementing it

* use to_unsigned to avoid signedness conversion warnings
2020-11-12 08:37:04 -08:00
7abc3c01e0 Suppress a useless warning (#2004) 2020-11-12 08:18:28 -08:00
6d14f78115 Fix linkage errors when linking with a shared library (#2011) 2020-11-12 06:11:17 -08:00
9534b9fe69 Refactor warning suppression 2020-11-12 05:45:36 -08:00
60dc273513 Simplify on_text 2020-11-11 15:13:44 -08:00
b5dac0f0f8 Reduce <algorithm> usage (#1998) 2020-11-11 09:12:15 -08:00
a07627b1f8 🐛 Implicit sign conversion warning in clang in c++17 and 20 modes (#2009)
Problem:
- On Apple clang version 11.0.3 (clang-1103.0.32.62) in C++17 and C++20
  mode, clang 11.0.0 in C++17 and C++20 mode, and clang 9.0.1 in C++17
  mode, the following error is generated:

    In file included from test/compile-test.cc:16:
    include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion]
      return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
                     ~  ~~~~^~~~~~~~~~~~
    include/fmt/compile.h:538:31: note: in instantiation of function template specialization
          'fmt::v7::detail::parse_specs<int, char>' requested here
          constexpr auto result = parse_specs<id_type>(str, POS + 2, ID);
                                  ^
    include/fmt/compile.h:569:17: note: in instantiation of function template specialization
          'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int>, 0, 0, FMT_COMPILE_STRING>' requested here
            detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
                    ^
    include/fmt/compile.h:648:37: note: in instantiation of function template specialization
          'fmt::v7::detail::compile<int, FMT_COMPILE_STRING, 0>' requested here
      constexpr auto compiled = detail::compile<Args...>(S());
                                        ^
    test/compile-test.cc:140:24: note: in instantiation of function template specialization
          'fmt::v7::format<FMT_COMPILE_STRING, int, 0>' requested here
      EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
                           ^
    In file included from test/compile-test.cc:16:
    include/fmt/compile.h:518:25: error: implicit conversion changes signedness: 'long' to 'unsigned long' [-Werror,-Wsign-conversion]
      return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()};
                     ~  ~~~~^~~~~~~~~~~~
    include/fmt/compile.h:538:31: note: in instantiation of function template specialization
          'fmt::v7::detail::parse_specs<char [4], char>' requested here
          constexpr auto result = parse_specs<id_type>(str, POS + 2, ID);
                                  ^
    include/fmt/compile.h:494:27: note: in instantiation of function template specialization
          'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 5, 2, FMT_COMPILE_STRING>'
          requested here
        constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
                              ^
    include/fmt/compile.h:539:14: note: in instantiation of function template specialization
          'fmt::v7::detail::parse_tail<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 5, 2, fmt::v7::detail::spec_field<char, int, 0>, FMT_COMPILE_STRING>' requested here
          return parse_tail<Args, result.end, result.next_arg_id>(
                 ^
    include/fmt/compile.h:569:17: note: in instantiation of function template specialization
          'fmt::v7::detail::compile_format_string<fmt::v7::detail::type_list<int, int, char const (&)[4], int>, 0, 0, FMT_COMPILE_STRING>'
          requested here
            detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
                    ^
    include/fmt/compile.h:648:37: note: in instantiation of function template specialization
          'fmt::v7::detail::compile<int, int, char const (&)[4], int, FMT_COMPILE_STRING, 0>' requested here
      constexpr auto compiled = detail::compile<Args...>(S());
                                        ^
    test/compile-test.cc:145:18: note: in instantiation of function template specialization
          'fmt::v7::format<FMT_COMPILE_STRING, int, int, char const (&)[4], int, 0>' requested here
                fmt::format(FMT_COMPILE("{:{}}{:{}}"), 42, 4, "foo", 5));
                     ^
    2 errors generated.

Solution:
- Explicitly cast the result of the subtraction to the (unsigned) outer
  type.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
2020-11-11 07:57:52 -08:00
1b8f499ee1 🔧 Silence useless cast warnings (#2008)
Problem:
- gcc-10 is generating the following warning at all standards:

    test/format-test.cc: In member function 'virtual void UtilTest_BitCast_Test::TestBody()':
    test/format-test.cc:108:42: error: useless cast to type 'uint64_t' {aka 'long long unsigned int'} [-Werror=useless-cast]
      108 |   s = fmt::detail::bit_cast<uint32_pair>(uint64_t(~0ull));
          |                                          ^~~~~~~~~~~~~~~
- gcc-8 is generating the following warning at all standards:
    test/format-test.cc: In member function 'virtual void UtilTest_BitCast_Test::TestBody()':
    test/format-test.cc:108:56: error: useless cast to type 'uint64_t' {aka 'long long unsigned int'} [-Werror=useless-cast]
       s = fmt::detail::bit_cast<uint32_pair>(uint64_t(~0ull));
                                                        ^
Solution:
- Cast 0 to a 64 unsigned bit int and then invert.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
2020-11-11 07:56:59 -08:00
f428d286a1 Update README.rst 2020-11-11 07:11:43 -08:00
beb248b6ac Optimize handling of large format strings 2020-11-11 06:11:05 -08:00
1936dddc3c fix gcc warning of missing override (#2001)
Co-authored-by: Lieven de Cock <killerbot@linux-2x3u.suse>
2020-11-10 07:57:21 -08:00
14f6bd0f4e Move one more headers to args.h 2020-11-09 20:35:03 -08:00
e01d26e1a4 Optimize includes 2020-11-09 16:34:54 -08:00
e528d919a8 Merge branch 'master' of github.com:fmtlib/fmt 2020-11-08 12:45:15 -08:00
4881677268 Update signatures 2020-11-08 12:29:26 -08:00
3302fd1088 use memchr for searching for '%' in printf format string (#1984) 2020-11-08 10:36:00 -08:00
4c2d637203 Update signatures 2020-11-08 10:10:44 -08:00
beaff39618 Update signatures 2020-11-08 10:00:08 -08:00
ffa0a0834a Use newer versions of Sphinx and Breathe 2020-11-08 09:46:27 -08:00
038057eb3e Document contexts 2020-11-08 08:16:23 -08:00
5bedcb665b Fix initialization of iterator_buffer (#1996) 2020-11-08 08:08:55 -08:00
2435ea4113 Workaround MSVC mess 2020-11-08 07:48:03 -08:00
8c6215f5de Fix fmt/color.h 2020-11-08 07:24:07 -08:00
10ebe6cb48 Document color 2020-11-08 07:18:01 -08:00
1ac50fcb5a Suppress more bogus warnings 2020-11-08 07:04:42 -08:00
e098be8e88 Fix warning filtering 2020-11-08 06:58:41 -08:00
8cf0afaf1c Improve docs 2020-11-08 06:48:34 -08:00
e29f93e8a8 Suppress more bogus warnings 2020-11-08 06:33:42 -08:00
4e8d000f76 Suppress more bogus warnings 2020-11-08 06:29:50 -08:00
7787792e8d Fix re usage 2020-11-08 06:20:53 -08:00
6ee5e507c7 Fix imports 2020-11-08 06:16:49 -08:00
06ee32d1b5 Filter useless doxygen warnings 2020-11-08 06:13:56 -08:00
86bb7fe614 Add a missing import 2020-11-08 05:55:49 -08:00
959a9f5cad Merge branch 'master' of github.com:fmtlib/fmt 2020-11-08 05:50:48 -08:00
4f7df299ea Improve docs 2020-11-08 05:40:39 -08:00
b3ab0bc7e3 🎨 [CI] Specify the exact version of clang to use (#1991)
Problem:
- The version of clang to use is specified only as `clang++`. This is
  inconsistent with the specifications for gcc and exposed to unexpected
  failure if the default changes.

Solution:
- Specify the exact version of clang to use. I chose `clang++-9` as that
  is the version that `clang++` is currently resolving to.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
2020-11-08 05:18:24 -08:00
701ed6c874 Install deps in github actions instead of script 2020-11-07 11:16:38 -08:00
8f2131cf2d Document chrono 2020-11-07 10:51:08 -08:00
32c4af8f0d Document chrono 2020-11-07 10:38:51 -08:00
295a60ec8d Document chrono 2020-11-07 10:30:23 -08:00
a4fae96c96 Document chrono 2020-11-07 10:24:27 -08:00
263bb0e68d Document chrono 2020-11-07 10:19:40 -08:00
0506b328b5 Document chrono 2020-11-07 09:59:57 -08:00
4e426c19d0 Document chrono 2020-11-07 09:47:56 -08:00
9795d87348 Update docs 2020-11-07 09:27:06 -08:00
2eb0be0b73 Remove debug code and fix bot contact 2020-11-07 09:16:55 -08:00
cd95579834 Move less installation to actions 2020-11-07 09:12:54 -08:00
98639d0f6f Debug doc build 2020-11-07 09:04:07 -08:00
ab5e0632fe Debug doc build 2020-11-07 08:54:58 -08:00
b123129f4e Dump the content of html dir 2020-11-07 08:42:13 -08:00
81d2b986af Print less command 2020-11-07 08:24:58 -08:00
7a0b1d5781 Add key 2020-11-07 08:09:01 -08:00
9f0617cbfb Fix branch ref 2020-11-07 08:04:01 -08:00
75b07598fe Chrono docs 2020-11-07 07:56:53 -08:00
dfbb6975b3 Remove travis config 2020-11-07 07:38:20 -08:00
5b3052f999 Switch doc build to github actions 2020-11-07 07:31:15 -08:00
506ff320f2 Fix build failure when not using fcntl with -Werror (#1990) 2020-11-06 15:39:59 -08:00
a30b279bad Apply clang-format and tweak comments 2020-11-04 17:17:23 -08:00
6a2495c840 -Wattributes visibility warning with some GCC versions (#1975) 2020-11-04 17:11:31 -08:00
cba5970cd8 Remove migrated build configs 2020-11-04 10:03:00 -08:00
689081d832 Merge branch 'release' of github.com:fmtlib/fmt 2020-11-04 07:46:02 -08:00
cc09f1a679 Update version 2020-11-04 06:50:09 -08:00
e4eb242ce8 Update changelog and bump version 2020-11-03 21:20:53 -08:00
ce98e0c6a0 Fix fallback float formatter at assymetric bounds (#1976) 2020-11-03 21:18:04 -08:00
49544ea943 Fuzz fallback formatter 2020-11-03 19:34:35 -08:00
6b7bfed40c Fix fallback float formatter at assymetric bounds (#1976) 2020-11-03 19:19:10 -08:00
bcab36da3f Update CI config 2020-11-03 16:01:26 -08:00
1689e73e90 Move PR template 2020-11-03 14:52:47 -08:00
0103408a5c Update CI config 2020-11-03 14:39:43 -08:00
38a16ecba2 Move build config to github actions 2020-11-03 13:35:37 -08:00
205eb3a8f2 Update CI config 2020-11-03 13:27:15 -08:00
fe61b8c630 Update CI config 2020-11-03 11:59:59 -08:00
867b15d77c Update CI config 2020-11-03 11:48:20 -08:00
98cb9f9931 Update CI config 2020-11-03 11:43:00 -08:00
95077d60c9 Update CI config 2020-11-03 11:41:25 -08:00
bc49f094e7 Update CI config 2020-11-03 11:02:49 -08:00
cef6dfb422 Update CI config 2020-11-03 10:46:03 -08:00
c8703ba40b Update CI config 2020-11-03 10:45:16 -08:00
ab4405bea5 Update README.rst 2020-11-03 10:42:06 -08:00
78a55e2898 Update CI config 2020-11-03 10:37:30 -08:00
d0a2494a99 Update cmake.yml 2020-11-03 10:17:38 -08:00
89d009ba6e Update cmake.yml 2020-11-03 10:14:38 -08:00
1f4ff47b41 Create cmake.yml 2020-11-03 10:04:28 -08:00
eb52ac7a35 🆕 Enable -Wshadow in pedantic mode
Problem:
- All `-Wshadow` warnings are fixed but there is nothing stopping them
  from being reintroduced.

Solution:
- Fail pedantic builds on `-Wshadow` warnings. This allows CI to prevent
  reoccurrence of the warning.

Notes:
- Not enabling `-Wshadow` for gcc versions 4 or lower because the
  warning is much more aggressive there to the point that it's mostly
  just noise.
2020-11-03 07:30:27 -08:00
e904e891bd 🎨 🐛 Rename all shadowed types and variables 2020-11-03 07:30:27 -08:00
771292c328 Remove sizeof from unused variable silencer (#1974)
Using sizeof causes some compilers to complain:
'operand of sizeof is not a type, variable, or dereferenced pointer'

static_cast itself should be enough to silence unused variable warning

Co-authored-by: Łukasz Mitka <lukasz.mitka@aptiv.com>
2020-11-03 06:48:19 -08:00
86bf6045c6 Merge branch 'release' of github.com:fmtlib/fmt 2020-11-02 06:27:49 -08:00
5f7f7b954d Update version 2020-11-01 06:30:39 -08:00
5d3f0741e3 Update changelog and bump version 2020-11-01 06:28:06 -08:00
563cbb6c21 Add a macro to workaround clang/gcc ABI incompatibility on ARM 2020-11-01 06:10:04 -08:00
425778aa67 Fix ABI compatibility (#1961) 2020-11-01 06:09:31 -08:00
69a84198b0 Remove accidental parenthesis (#1968)
fails only when FMT_BUILTIN_CTZLL is not defined
2020-11-01 06:09:25 -08:00
5c04504932 Removed [-Wsign-conversion] warning in GCC 2020-11-01 06:09:11 -08:00
556a1cfb34 Instantiate to_decimal to make gcc lto happy (#1955) 2020-11-01 06:08:57 -08:00
28a8eae850 Cleanup 2020-11-01 06:08:50 -08:00
236fea1f00 Workaround bugs in gcc 8 2020-11-01 06:08:28 -08:00
e50ced88c6 Add a macro to workaround clang/gcc ABI incompatibility on ARM 2020-10-31 07:52:08 -07:00
112755cf91 Remove FMT_SAFEBUFFERS (#1966) 2020-10-29 17:42:45 -07:00
4081b2fe94 Fix ABI compatibility (#1961) 2020-10-29 11:29:47 -07:00
2d9311e860 Remove accidental parenthesis (#1968)
fails only when FMT_BUILTIN_CTZLL is not defined
2020-10-29 07:08:06 -07:00
b3a4f28ad1 Fix implicit signedness conversion warning (#1963)
Problem:
- On Apple clang 11.0.3 (clang-1103.0.32.62), pedantic mode compilation
  generates the following error:

    test/std-format-test.cc:114:22: error: implicit conversion changes
          signedness: 'int' to 'size_t' (aka 'unsigned long')
          [-Werror,-Wsign-conversion]
        width_arg_id = c - '0';
                     ~ ~~^~~~~

Solution:
- Use a `to_unsigned` to make the conversion explicit. This is
  guaranteed to be safe due to the check before the ASCII-to-int
  conversion.
2020-10-29 06:26:18 -07:00
97c8873214 Allocator::max_size support in basic_memory_buffer (#1960) 2020-10-29 06:17:00 -07:00
bb68f6089b Removed [-Wsign-conversion] warning in GCC 2020-10-28 06:02:17 -07:00
f4ca065cfb Range support 2020-10-28 05:35:37 -07:00
cb224ecaa3 Instantiate to_decimal to make gcc lto happy (#1955) 2020-10-27 07:46:40 -07:00
7977c2b4d0 Cleanup 2020-10-27 07:19:28 -07:00
e54eb67639 Workaround bugs in gcc 8 2020-10-27 06:11:31 -07:00
4fe0b11195 Update version 2020-10-25 10:44:22 -07:00
df4bd60f42 Bump version 2020-10-25 10:43:03 -07:00
764fb35e1f Always install the required version of breathe 2020-10-25 10:34:47 -07:00
e1bdc0ecaf Use the correct version of sphinx 2020-10-25 09:52:21 -07:00
39bde329bd Tweak markup 2020-10-25 09:19:38 -07:00
204d299abb Tweak markup 2020-10-25 09:12:22 -07:00
e0995b1c14 Update readme 2020-10-25 09:04:39 -07:00
4af178bdfe Remove outdated build config 2020-10-25 09:01:44 -07:00
aa41dc02b1 Remove unused script 2020-10-25 09:00:25 -07:00
6a77ea3c93 Tweak markup 2020-10-25 08:59:36 -07:00
62c72059d9 Update changelog 2020-10-25 08:56:46 -07:00
c10e3f7f4f Update changelog 2020-10-25 07:29:24 -07:00
e542e6953e Update changelog 2020-10-25 06:46:45 -07:00
530cf316b8 Point to the release, not dev documentation 2020-10-24 12:02:12 -07:00
740385d636 Update changelog 2020-10-24 11:18:33 -07:00
cd4651116e Update changelog 2020-10-24 09:24:47 -07:00
46291be348 Update changelog 2020-10-23 07:38:01 -07:00
90071c1df0 Update ChangeLog.rst 2020-10-22 09:30:27 -07:00
25293d7ac6 Update ChangeLog.rst 2020-10-22 09:28:23 -07:00
5024742f8a Update ChangeLog.rst 2020-10-22 09:27:49 -07:00
0452a4e71f Update changelog 2020-10-22 09:08:30 -07:00
8de96817ce Woraround bugs in gcc 8 2020-10-22 07:33:32 -07:00
47e167679a Simplify arg formatter 2020-10-21 19:04:02 -07:00
f0a42346a4 Move parsing optimization one level up 2020-10-21 18:18:53 -07:00
86287b8d56 Optimize common case in parse_format_specs 2020-10-21 17:16:58 -07:00
8924211f3b Update README.rst 2020-10-21 14:02:55 -07:00
525e7649cf Update CONTRIBUTING.md 2020-10-21 14:02:33 -07:00
0ecb3d1829 Optimize alignment parsing 2020-10-21 12:45:11 -07:00
9755307842 Optimize format_uint 2020-10-21 08:19:21 -07:00
7446818f98 Simplify vformat_to 2020-10-21 07:15:11 -07:00
280b5612c0 Add option to force usage of inline namespaces
Detection of inline namespaces is imperfect as some compilers
don't provide __has_feature

This option allows to override it if needed.
2020-10-21 06:38:59 -07:00
e57ec7d563 Merge vformat_to overloads 2020-10-20 17:39:50 -07:00
2a3f4de3f4 Remove iterator_category 2020-10-20 16:44:49 -07:00
27fdb4ead2 Unshadow floaty 2020-10-20 15:05:00 -07:00
297e0bad8c Apply clang-format 2020-10-20 14:10:28 -07:00
e3b4c22ec9 Simplify is_output_iterator 2020-10-20 14:09:57 -07:00
da8278e1e3 Update changelog and bump version 2020-10-19 14:37:14 -07:00
17fba753c4 added position independent documentation (#1939)
* added position independent documentation

* suggested fixes to usage

* linebreaks

Co-authored-by: Adnan Yunus <adnan@opus.ai>
2020-10-19 14:20:54 -07:00
71e705a273 Update README.rst 2020-10-19 08:54:55 -07:00
74654c8cbb Fix compilation for systems without fcntl.h (#1942)
Co-authored-by: darklukee <no-reply@hidden>
2020-10-19 07:43:06 -07:00
f468b203ad Avoid conversion from long long to size_t (#1935) 2020-10-18 09:25:33 -07:00
20d4f2e836 Fix handling of weird character types when parsing sign (#1932) 2020-10-17 09:40:30 -07:00
08370c39ff Update README.rst 2020-10-17 08:27:21 -07:00
bd3c792507 Fix float fuzzer 2020-10-16 07:35:53 -07:00
8d3fd86d6d Merge branch 'master' of github.com:fmtlib/fmt 2020-10-16 07:35:02 -07:00
4034715713 Update README.rst 2020-10-16 06:47:16 -07:00
37d738fa6b Update README.rst 2020-10-16 06:46:39 -07:00
271eff149f Make classes derived from buffer<T> final to silence the virtual destructor warning. (#1937)
Co-authored-by: Bart Siwek <bsiwek@cisco.com>
2020-10-15 17:41:56 -07:00
010efc310f Add float fuzzer and cleanup 2020-10-14 20:13:09 -07:00
811c8b58c5 Add float fuzzer and cleanup 2020-10-14 07:39:51 -07:00
82c4e2236a Cleanup fuzzing 2020-10-13 09:08:04 -07:00
63e40c9614 Fix naming of fuzzers 2020-10-12 16:48:25 -07:00
2f448ed565 Fix fuzzer timeouts 2020-10-12 16:46:21 -07:00
af28305961 Cleanup 2020-10-11 10:13:42 -07:00
48ea8193df Explain why assert-test is a separate test 2020-10-11 10:13:42 -07:00
1d112bdd1e Remove old test 2020-10-11 10:13:42 -07:00
5eb292a653 Update README.rst 2020-10-11 09:57:21 -07:00
7e56b6b6cb Fix coding style and remove duplicate fuzzer 2020-10-11 08:07:52 -07:00
41d97e1ef4 Fix a UB on ridiculously large precision 2020-10-11 08:07:52 -07:00
01c37e0a4b Added check for -mbig-obj and ref qualifier check (#1929)
* Added check whether mingw has -mbig-obj flag
* Removed ref qualifiers
2020-10-11 07:49:54 -07:00
a5e7e7db95 Fix handling of thousand separator (#1927) 2020-10-10 07:23:36 -07:00
bf19051a9f Optimize floating point formatting 2020-10-09 15:29:56 -07:00
3c13a88b14 Optimize floating point formatting 2020-10-09 11:01:01 -07:00
f6d75c534c Refactor write_float 2020-10-09 09:11:39 -07:00
e9c0b2d69e Merge write_float overloads 2020-10-08 20:00:38 -07:00
7eddbfed53 Cleanup exponent handling in write_float 2020-10-07 15:58:43 -07:00
b347b3023f Update dynamic_formatter comment (#1923) 2020-10-07 12:15:07 -07:00
3541880efd Fix integer overflow when using max int precision 2020-10-07 11:27:02 -07:00
7b50dc0b24 Don't exclude all detail symbols from docs 2020-10-07 09:07:39 -07:00
2805243103 Fix the doc config 2020-10-07 08:11:59 -07:00
34f22e88a1 Cleanup CMake config 2020-10-07 08:11:42 -07:00
a18b3fbbdc Fix fixed precision handling when rounding (#1917) 2020-10-07 07:42:23 -07:00
7277035736 Fix long lines in usage.md 2020-10-06 06:26:11 -07:00
7612c1ea87 Add reference to lhelper package manager in usage 2020-10-06 06:26:11 -07:00
b91d39f20b Get rid of float_writer 2020-10-05 06:34:04 -07:00
b4b64b9cce Refactor float formatting 2020-10-04 14:44:25 -07:00
712abe40f2 Workaround a bug in gcc 7.5 (#1912)
Thanks Martin Janzen.
2020-10-04 09:20:37 -07:00
af8a180aed Make GetCachedPower test more precise 2020-10-04 08:00:47 -07:00
a581e9e5d8 Fix warning C4018: '<=': signed/unsigned mismatch (#1908) 2020-10-02 06:30:57 -07:00
05a28312cf Update docs 2020-09-30 17:38:28 -07:00
4d0aa4d8fe Update link 2020-09-30 17:21:07 -07:00
575f401896 Simplify FP formatting and follow coding conventions 2020-09-30 06:36:17 -07:00
6f3536f974 Move zero-check to an earlier branch (#1906) 2020-09-29 06:24:53 -07:00
90ef46df0b Fix dragonbox integration 2020-09-28 18:10:46 -07:00
3ae88147e2 Fix declaration 2020-09-28 06:50:09 -07:00
6417952574 Improve dragonbox integration 2020-09-27 20:49:37 -07:00
79694d424c Fix WriteConsole signature 2020-09-27 14:26:28 -07:00
51f2e2ca27 Move nan test to where it belongs 2020-09-27 12:50:18 -07:00
68555fdbd2 Make format-test not depend on color.h 2020-09-27 09:17:57 -07:00
63e0c35412 Make dragonbox::to_decimal available in format.h 2020-09-27 07:27:44 -07:00
2213a7110c Update README.rst 2020-09-26 11:46:39 -07:00
79ba37f3bf Update README.rst 2020-09-26 10:13:04 -07:00
a905d8f704 Merge grisu-test into format-test 2020-09-26 08:23:16 -07:00
762c33a964 Simplify windows handling (#1903) 2020-09-26 08:20:38 -07:00
253d63159f Remove dependency on windows.h (#1900) 2020-09-26 07:03:16 -07:00
c156093ffd Fix carry in fallback_format 2020-09-25 10:12:44 -07:00
34179b3354 Update format.h (#1898) 2020-09-24 08:16:16 -07:00
0651e4598b Minor tweaks to get_cached_power 2020-09-23 16:04:40 -07:00
6c025520aa Test that max_k is correctly defined 2020-09-23 15:44:37 -07:00
51f8d0cc21 Reuse log10_2_significand constant 2020-09-23 13:19:21 -07:00
1305cbeb6f Fix MSVC2019 error C2049 when compiling with /clr (#1897)
'fmt::v7': non-inline namespace cannot be reopened as inline
2020-09-23 09:55:41 -07:00
2d4fde3a2e Don't emit trailing zero for consistency with std::format 2020-09-23 09:19:12 -07:00
5fd89d50e4 Minor simplifications 2020-09-23 08:05:31 -07:00
605ce5e429 Simplify divisible_by_power_of_2 2020-09-22 20:44:29 -07:00
085171e7e6 Remove grisu_count_digits 2020-09-22 19:36:52 -07:00
aa729bf25b Remove dead code 2020-09-22 16:58:02 -07:00
aa2ddf9b86 Simplify Dragonbox integration 2020-09-22 16:20:40 -07:00
c1654ce487 Simplify uint32_or_64_or_128_t definition 2020-09-22 15:08:37 -07:00
33712dc07a Combine pragmas 2020-09-22 14:47:35 -07:00
e5942ac9dd Tweak comments 2020-09-22 14:36:10 -07:00
aae7a1338c Remove unused pragmas 2020-09-22 14:00:41 -07:00
6bcde9aab2 https://github.com/fmtlib/fmt/pull/1882#issuecomment-696823912 (#1894) 2020-09-22 10:33:52 -07:00
bb0db5e51e clang-format 2020-09-22 08:19:37 -07:00
16410056bf Optimize copy_str for counting_iterator 2020-09-22 07:56:09 -07:00
2591ab91c3 MSVC optimizations for count_digits. (#1890)
Changed the clz implementations to use xor instead of subtraction so that when
count_digits "undoes" the BSR -> CLZ translation, the optimizer is more
willing to recognize the equivalence.
Changed the data array in bsr2log10 to static since otherwise MSVC generates
code to build the array every time the function is called.
2020-09-21 11:38:06 -07:00
d5b8002dcb Update README.rst 2020-09-21 09:40:49 -07:00
821471e1d1 qkw: generalizing aliasing | using fmt library and it's features (#1888)
I make extensive use of this library for building qkw targeting linux users. Please add this to your list.
https://github.com/ravijanjam/qkw
2020-09-21 09:39:07 -07:00
2e620ddbcd Small improvements that should have zero to negligible impact on the runtime (#1887) 2020-09-20 09:34:44 -07:00
2f7e08856b Disable range formatter if value type is not formattable (#1885) 2020-09-20 08:37:49 -07:00
c46a8de4e1 Simplify test 2020-09-20 07:24:24 -07:00
2696dc9273 add forgotten template argument to make_format_args which made some u… (#1877)
* add forgotten template argument to make_format_args which made some uses of FMT_COMPILE not work anymore after 54daa0864a, add more elaborate test cases to compile-test as regression tests

* fix old-style cast which gcc on travis thankfully doesn't accept anymore

* hopefully last forgotten (void*)
2020-09-20 06:51:11 -07:00
0016da7ab3 Don't generate zeros and fix UB on huge precision 2020-09-19 16:01:43 -07:00
ce3f76994a Merge intrinsic blocks 2020-09-19 07:54:45 -07:00
3b6248f602 Change formatting 2020-09-19 07:23:41 -07:00
2d9b1dd0ad Fix sign mismatch 2020-09-19 07:23:41 -07:00
1f0600a23b Fix bug regarding FMT_SAFEBUFFERS 2020-09-19 07:23:41 -07:00
2ecdbb986d Fix a bug in ctzll 2020-09-19 07:23:41 -07:00
6f81ea151a Fix typo (and thus bug) 2020-09-19 07:23:41 -07:00
0c8ffe9b0f Implement Dragonbox (first version) 2020-09-19 07:23:41 -07:00
42699bf408 Fix msvc version of clz & clzll (#1880)
Change msvc version of clz & clzll to match __builtin_clz & _builtin_clzll
2020-09-18 11:07:01 -07:00
bc51a8df04 Disable fallthrough attributes for the Intel compilers on Linux and MacOS (#1879)
* Disable fallthrough attributes for the Intel compilers

On MacOS and Linux the Intel compilers may be identified as the
host compilers (Clang or GNU) but do not support the corresponding
compiler specific fallthrough attributes.

* Rearrange ifdef logic for excluding pre-C++17 fallthrough attributes

This puts Intel and PGI compilers into a separate group
and thus makes the intent and logic more obvious.
2020-09-18 09:57:00 -07:00
45da432d60 fix compiler warnings in public header files 2020-09-17 15:53:53 -07:00
d55e61f120 Improve FMT_ALWAYS_INLINE (#1878)
1. FMT_ALWAYS_INLINE should imply inline; otherwise, there might be
   linkage problems
2. Add specialization for MSVC (__forceinline)
2020-09-17 15:21:17 -07:00
7e6827521a Remove trailing zeros when using fallback formatter (#1873) 2020-09-17 08:16:21 -07:00
1d696dc280 Handle exotic character types in compilation 2020-09-17 07:12:34 -07:00
f674434a67 Add format_to_n overload that accepts FMT_COMPILE (from #1767) (#1869)
* Add format_to_n overload that accepts FMT_COMPILE

* add FormatToNWithCompileMacro test into CompileTest

Co-authored-by: Dmitriy Kurkin <Dmitriy.Kurkin@itiviti.com>
2020-09-15 07:28:06 -07:00
5b5a597198 Fix handling of wide alignment 2020-09-15 06:53:06 -07:00
f80ed64dd9 Update README.rst 2020-09-14 11:13:51 -07:00
3813966497 Simplify fallback format 2020-09-13 11:27:34 -07:00
dce8e49b4f Handle float in fallback formatter 2020-09-13 09:28:40 -07:00
78b5944313 Spelling 2020-09-12 13:14:49 -07:00
f233b56cdd Don't generate insignificant digits 2020-09-12 09:19:50 -07:00
595902f8a0 Update test 2020-09-11 07:57:40 -07:00
4f2ee8921d Use built-in FP formatter for any precision 2020-09-11 07:20:16 -07:00
58a044be5d Use built-in FP formatter for any precision 2020-09-11 07:19:45 -07:00
efe3694f15 Macro tweak and clang-format 2020-09-07 14:43:00 -07:00
9f312fe87e Implement fallback FP formatting with given precision (#1526) 2020-09-07 09:34:30 -07:00
fb289cf56b Fix coding conventions 2020-09-06 09:26:32 -07:00
86f0a7046e Fix formatting 2020-09-06 08:58:19 -07:00
bff4d18efb Add color format_to overloads
* Fix variable size basic_memory_buffer colorization
* Fix an unused arguments warning on GCC that blocks the CI otherwise
* Ref #1842
* Ref #1593
2020-09-06 08:24:15 -07:00
f19b8885f2 Fixed a warning in mingw32/mingw64 (#1860) 2020-09-06 06:27:37 -07:00
f8e00a084a NOMINMAX not handled properly (#1855) 2020-09-03 09:45:47 -07:00
6cccdc24bc Fix move constructor (#1844) 2020-09-01 08:48:56 -07:00
69902c1787 Allow use of <fcntl.h> in Linux when __has_include is not available (#1848) 2020-09-01 06:29:34 -07:00
1edd38b96e Add append mode. (#1847) 2020-08-31 15:48:39 -07:00
e66ba16923 Added build2 usage instructions. (#1838)
The `fmt` package have been available for `build2` users for several version, see: https://cppget.org/fmt

This simply add the minimum instructions for making a `build2` project depend on it.

There are other ways to do it, but they need more understanding of `build2`.
2020-08-28 15:15:15 -07:00
f39e6fb617 Add formatters for chrono::time_point<system_clock> (#1837)
Add formatters for chrono::time_point and helper overloads for localtime/gmtime(time_point)
Fixes #1819
2020-08-28 07:41:38 -07:00
77b627be20 Fix bogus MSVC warnings (#1825) 2020-08-26 12:33:54 -07:00
5dff01d31b Add complex tests 2020-08-26 11:48:50 -07:00
d16d585e64 Update signatures 2020-08-26 09:35:19 -07:00
c7e6d8afb0 Fix usage of override (#1836) 2020-08-23 11:01:46 -07:00
92bff2fe2c Revert "Add missing includes"
This reverts commit 06895a7687.
2020-08-21 16:24:53 -07:00
a0dcfbc57b Add ptr to docs 2020-08-21 06:54:05 -07:00
1651b2d433 Fix detail::write with fallback formatter (#1829)
* add support for fallback_formatter in detail::write

* add ToString test into OStreamTest

to check fmt::to_string() with class that has output stream operator

* add WithOstreamOperator test into CompileTest

to check fmt::format() with FMT_COMPILE() and class that has output stream operator

* use conditional_t inside detail::write instead of 2 overloads

* Revert "add WithOstreamOperator test into CompileTest"

* remove Context from template parameters in detail::write
2020-08-20 06:41:09 -07:00
06895a7687 Add missing includes 2020-08-19 20:33:04 -07:00
92a448a071 Apply clang-format 2020-08-19 10:42:22 -07:00
6be6544668 Fixing buffer_appender's ++ slicing (#1822)
* Fixing buffer_appender's ++ slicing.

* This test requires C++14.

* Removing string_view dependency.

* Simplifying test case.

* Adding message to static_assert
2020-08-18 12:37:56 -07:00
951e0d2333 CMakeLists.txt: Added Wundef warning to clang and gcc. (#1823)
Co-authored-by: Martin Wührer <martin.wuehrer@artech.at>
2020-08-18 07:04:44 -07:00
f9f02df719 CMakeLists.txt: Clang-warnings: removed -Wno-sign-conversion (#1817)
* CMakeLists.txt: Clang-warnings: removed -Wno-sign-conversion

* test/ranges-test.cc: changed type of integer literals to unsigned

* test/format-test.cc: fixed implicit conversion changes signedness warning in clang

Co-authored-by: Martin Wührer <martin.wuehrer@artech.at>
2020-08-14 13:58:20 -07:00
76e97dc4df Eliminate shadowed variable warnings on intel (#1816)
The intel-19 compiler warns about hidden variables:
```
/s/dev/nightly/libraries/ioss/src/fmt/format.h(2689): warning #1599: declaration hides variable "begin" (declared at line 2668)
      FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) {
                                                ^
          detected during:
            instantiation of "Context::iterator fmt::v7::vformat_to<ArgFormatter,Char,Context>(ArgFormatter::iterator, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<Context>, fmt::v7::detail::locale_ref) [with ArgFormatter=fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, Char=char, Context=fmt::v7::format_context]" at line 3492
            instantiation of "fmt::v7::detail::buffer_appender<Char> fmt::v7::detail::vformat_to(fmt::v7::detail::buffer<Char> &, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<fmt::v7::type_identity_t<Char>>, fmt::v7::type_identity_t<Char>>>) [with Char=char]" at line 1413 of "/s/dev/nightly/libraries/ioss/src/fmt/format-inl.h"

/s/dev/nightly/libraries/ioss/src/fmt/format.h(2689): warning #1599: declaration hides variable "end" (declared at line 2669)
      FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) {
                                                                   ^
          detected during:
            instantiation of "Context::iterator fmt::v7::vformat_to<ArgFormatter,Char,Context>(ArgFormatter::iterator, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<Context>, fmt::v7::detail::locale_ref) [with ArgFormatter=fmt::v7::detail::arg_formatter<fmt::v7::detail::buffer_appender<char>, char>, Char=char, Context=fmt::v7::format_context]" at line 3492
            instantiation of "fmt::v7::detail::buffer_appender<Char> fmt::v7::detail::vformat_to(fmt::v7::detail::buffer<Char> &, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<fmt::v7::type_identity_t<Char>>, fmt::v7::type_identity_t<Char>>>) [with Char=char]" at line 1413 of "/s/dev/nightly/libraries/ioss/src/fmt/format-inl.h"
```
Rename the second set of variables to `pbegin` and `pend` to eliminate warning.
2020-08-13 18:58:31 -07:00
e204df0e66 nvcc compiler should be EDG-based, but fails test (#1818)
Our nvcc compilers (10.1.243 and 9.2.X) do not define the correct value for `FMT_USE_UDL_TEMPLATE` and then end up with an error later on in the build.  Explicitly search for `__NVCC__` symbol not being defined.   Might want to instead use `FMT_NVCC` or some other check, but the raw `__EDG_VERSION__` check is not working correctly for nvcc.
2020-08-13 15:18:57 -07:00
1c8bb54703 small changes to reduce clang-9 warnings (#1808)
* include/fmt/format.h: int_writer: removed unnecessary iterator type re-declaration (prevents shadow-waringing in clang)

* include/fmt/format.h: int_writer: correctly cast signed integer to unsigned to prevent 'implicit conversion changes signedness'-warnings in clang.

Co-authored-by: Martin Wührer <martin.wuehrer@artech.at>
2020-08-13 11:56:03 -07:00
4b69c78751 fix: warning C4100: unreferenced formal parameter (#1814)
Add [[maybe_unused]] to fix it.
2020-08-12 06:57:22 -07:00
fb0aeb8209 fix: disabled UDL templates for PGI (#1811) (#1812)
* fix: disabled UDL templates for PGI (#1811)

* fix: insert defined auround __PGI

Co-authored-by: n16h7hunt3r <n16h7hunt3r@nixos>
2020-08-11 15:27:27 -07:00
54daa0864a Add dynamic width support to FMT_COMPILE (#1809) 2020-08-10 09:40:11 -07:00
6fb7c6fb25 Workaround a bug in gcc10 (#1810) 2020-08-10 07:20:34 -07:00
16985fdadf Update README.rst 2020-08-09 08:56:51 -07:00
1378ddaefd Update README.rst 2020-08-08 18:01:56 -07:00
4fd95e4b4d Don't remove trailing zeros with # 2020-08-08 08:14:39 -07:00
e06ae32294 Avoid warnings on functions with external linkage that don't have declarations 2020-08-08 07:58:13 -07:00
7fc3d1f54c Add override to grow 2020-08-08 07:23:11 -07:00
065889a593 Use correct capacity in iterator_buffer (#1807) 2020-08-08 07:01:21 -07:00
d0dd678693 Adding convenience append(range) 2020-08-08 06:33:46 -07:00
0e7cef069b Merge commit 'c13f79e0' 2020-08-08 06:28:45 -07:00
e2c8c4557a Update README.rst 2020-08-07 20:58:29 -07:00
e4c954ff0e Update README.rst 2020-08-07 16:03:15 -07:00
c13f79e09e Merge release branch 2020-08-07 07:01:21 -07:00
d7921d649a Update README.rst 2020-08-06 19:41:17 -07:00
cd4af11efc Update version 2020-08-06 08:51:01 -07:00
1ebc2f7cc6 Bump version 2020-08-06 07:41:04 -07:00
f4c997062a Fix changelog 2020-08-06 07:40:46 -07:00
72920ba30a Update changelog 2020-08-06 07:39:37 -07:00
0907c08ae5 Fix handling of default alignmment with locale (#1801) 2020-08-06 07:39:09 -07:00
37c8f4eaf3 Don't use 128 bit integers with clang-cl (#1800)
clang-cl currently has a long-standing bug that using 128 bit integers
generates references to symbols that are provided neither by its own nor
by the Microsoft runtime: https://bugs.llvm.org/show_bug.cgi?id=25305
2020-08-06 07:38:57 -07:00
eaaaec9992 Workaround a bug in msvc 2020-08-06 07:38:51 -07:00
ccf8561cb3 Workaround broken numeric_limites, part 2 (#1787) 2020-08-06 07:38:32 -07:00
0cc73ebf79 Report error on missing named argument (#1796) 2020-08-06 07:38:18 -07:00
33efc3c94f Fix handling of iterators in locale-specific formatting (#1782) 2020-08-06 07:38:08 -07:00
4a4fc225ed Update changelog 2020-08-06 07:34:56 -07:00
61602a75db Remove -Wno-shadow 2020-08-05 10:55:09 -07:00
2f8fc29e9b Update README.rst 2020-08-05 10:53:49 -07:00
717b226b59 include/fmt/format.h: explicit cast to std::size_t for parameter to buffer.resize() in order to get rid of warning 'implicit conversion changes signedness:' in clang-8 (#1802)
Co-authored-by: Martin Wührer <martin.wuehrer@artech.at>
2020-08-05 09:37:10 -07:00
2a69f56769 Tweak buffer size 2020-08-05 08:22:12 -07:00
ea76933802 Simplify ostream 2020-08-04 20:11:43 -07:00
5413713c95 Remove unused function 2020-08-04 19:08:06 -07:00
57f462428d Increase the default buffer size 2020-08-04 08:19:19 -07:00
0b6e7cc60a Update README.rst 2020-08-03 21:51:48 -07:00
e587adb4e9 Simplify count_digits 2020-08-03 15:45:48 -07:00
279d698e1b Fix handling of default alignmment with locale (#1801) 2020-08-03 10:51:42 -07:00
76cfb50b2d Test complex formatter 2020-08-03 10:05:18 -07:00
208291205d Optimize count_digits 2020-08-02 07:58:36 -07:00
8d9ab96736 Cut a few cycles from count_digits 2020-08-01 18:33:53 -07:00
734344931f Simplify ostream_params 2020-08-01 18:33:53 -07:00
2a47a1e48f Update README.rst 2020-08-01 12:00:01 -07:00
7c4c5c79d2 Make buffer size configurable 2020-08-01 10:53:58 -07:00
f0b84da5ff Don't use 128 bit integers with clang-cl (#1800)
clang-cl currently has a long-standing bug that using 128 bit integers
generates references to symbols that are provided neither by its own nor
by the Microsoft runtime: https://bugs.llvm.org/show_bug.cgi?id=25305
2020-07-30 17:21:35 -07:00
a3dfd6f927 Workaround a bug in msvc 2020-07-30 11:13:54 -07:00
51d05521e9 Workaround broken numeric_limites, part 2 (#1787) 2020-07-30 09:42:24 -07:00
21c8b5c142 Report error on missing named argument (#1796) 2020-07-30 07:16:15 -07:00
d82fdcc9e2 Fix handling of iterators in locale-specific formatting (#1782) 2020-07-30 07:03:11 -07:00
633213d96f Merge release branch 2020-07-29 08:52:53 -07:00
b9d749095e Update version 2020-07-29 07:30:55 -07:00
86b63bb71a Bump version 2020-07-29 07:14:25 -07:00
cbf6be9604 Update changelog 2020-07-29 07:07:56 -07:00
229ee9b469 Workaround broken numeric_limits (#1725) 2020-07-29 07:06:45 -07:00
2b7a146fa1 Fix a regression in handling digit separators (#1782) 2020-07-29 07:04:11 -07:00
89d0c7124b Fix compatibility with CMake 3.4 (#1779) 2020-07-29 07:03:59 -07:00
e8f2580a43 Bump version 2020-07-28 09:25:15 -07:00
6cefe55ac7 Update changelog 2020-07-28 09:15:02 -07:00
64e2da15cd Update README.rst 2020-07-28 08:35:28 -07:00
1c8c810f88 Update README.rst 2020-07-28 08:32:37 -07:00
c2399ccfca Update README.rst 2020-07-28 08:21:04 -07:00
a7c5db06d5 Update README.rst 2020-07-28 08:18:10 -07:00
a4c22acd0a Update README.rst 2020-07-26 12:12:31 -07:00
0c1f4b5a0d Update README.rst 2020-07-26 10:57:59 -07:00
63b422ee5e Update README.rst 2020-07-26 10:37:00 -07:00
26e81a6731 Update README.rst 2020-07-26 10:29:03 -07:00
de5fc6af3b Update README.rst 2020-07-26 10:19:55 -07:00
9c2edfd1aa Partially revert 638db5 because it breaks the doc build 2020-07-26 09:44:37 -07:00
810357c014 Document color 2020-07-26 08:22:56 -07:00
0a7032a400 Update README.rst 2020-07-26 08:14:18 -07:00
95d3abf95c Make format_to_n part of the core API 2020-07-24 09:25:26 -07:00
98626093d2 Correct the locale format specifier in api.rst (#1792) 2020-07-23 21:01:54 -07:00
47f8d7a345 Make formatted_size part of the core API 2020-07-23 08:51:38 -07:00
46a63b7087 Update docs 2020-07-23 07:12:19 -07:00
430f393d6f Disabled __attribute__((deprecated)) usage for LCC (#1790) 2020-07-23 06:34:03 -07:00
febffa4e64 Make join() handle non-const-only begin/end ranges (#1786)
See fmtlib/fmt#1784.

Add tests that demonstrate the problem and check obvious variations.
2020-07-21 12:13:00 -07:00
d69e2da221 Fix apidoc 2020-07-20 10:38:14 -07:00
ce73ea37fb Reorder functions 2020-07-20 09:42:14 -07:00
d39d661b18 Workaround broken numeric_limits (#1725) 2020-07-20 08:39:15 -07:00
c228bfe882 Improve docs 2020-07-20 07:56:20 -07:00
38ce19f738 Update README.rst 2020-07-20 07:29:57 -07:00
d11849bc0b Add FMT_REDUCE_INT_INSTANTIATIONS flag (#1781)
* Remove <typename UInt> from int_writer

Reduce code bloat by removing multiple instantiation of int_writer based
on the <typename UInt> parameter.

Rationale:
- The only functions that gains a speedup by int size would be
  int_writer::on_dec()'s call to count_digits which uses CLZ. Thus to
  still take advantage of this speedup, we store the size of the int
  so we can use a switch statement to call the correct count_digits.
- All other implementations of count_digits require some sort of looping
  that terminates when the value hits zero regardless of what sized int
  it is.

Caveats:
- There is a performance hit when dealing with and passing around
  64-bit/128-bit values compared to 32-bit values on 32-bit platforms,
  and with 64-bit values on 64-bit systems. But this should not reduce the
  performance that dramatically.
- There is also a performance hit for on_dec() due to the addition of a
  switch case. But, due to it size, this should reduce to a jump table.

Resolves #1778

* Add FMT_USE_SMALLEST_INT flag

When defined and set to zero, will use the largest available integer
container for writing ints. The has the benefit of reducing instances
the of int_writer class which will reduce the binary cost.

* Rename flag to FMT_REDUCE_INT_INSTANTIATIONS

Add comment above FMT_REDUCE_INT_INSTANTIATIONS definition describing
why a developer would use it.

* Move FMT_REDUCE_INT_INSTANTIATIONS to format.h

Co-authored-by: Khalil Estell <kammce@google.com>
2020-07-19 13:09:10 -07:00
c08518a25b Move make_args_checked to the public API 2020-07-19 10:23:46 -07:00
e2837084ee Add a color section 2020-07-19 09:51:52 -07:00
9f0c003371 Simplify format string checks 2020-07-19 09:24:11 -07:00
d615137ca0 Improve handling of buffer iterator 2020-07-19 09:02:26 -07:00
26b47b6fb5 Bump tested CMake version to 3.18
Use the version range feature introduced in 3.12. On CMake <3.12 the extra dots are simply interpreted as extra version number separators.
The fallback for ancient CMake versions is kept.
2020-07-19 08:50:34 -07:00
7a01c9c523 Update README.rst 2020-07-18 09:17:10 -07:00
b17d5c4f5d Fix a regression in handling digit separators (#1782) 2020-07-18 08:31:47 -07:00
eb90da2e82 Type erase output iterators 2020-07-18 07:50:29 -07:00
9d3cd0afb2 Type erase output iterators 2020-07-17 12:57:50 -07:00
18024853b6 Fix compatibility with CMake 3.4 (#1779) 2020-07-17 06:41:25 -07:00
f5d4215b7c Trying to clear ambiguous compile time claims (#1775)
* Trying to clear ambiguous compile time claims

Documentation was a bit misleading.
Many people assume that fmt does compile time checks by default, while it requires the use of `FMT_STRING`.
It was also unclear that FMT_COMPILE does the same checks.

https://github.com/fmtlib/fmt/issues/1772

* Update api.rst
2020-07-16 06:19:49 -07:00
c26349f4d2 Improve error reporting 2020-07-14 12:06:12 -07:00
f4b11ef6e2 Add a short anchor 2020-07-14 09:39:22 -07:00
0097cf113d Report unformattable type name more prominently 2020-07-13 08:46:53 -07:00
8fa20b471b dev -> latest 2020-07-13 06:15:47 -07:00
a03bd3ddb0 Autodetect MSVC static runtime (#1770)
* Autodetect MSVC static runtime

* Update condition (MSVC)
2020-07-13 06:11:23 -07:00
c108ee1d59 Clarify a comment 2020-07-12 10:59:33 -07:00
a8074a865a Update README.rst 2020-07-12 09:57:02 -07:00
5f62954864 Update README.rst 2020-07-12 09:55:24 -07:00
bd903f96ac Clarify precedence 2020-07-12 09:02:31 -07:00
16cac46a09 Improve handling of streamable and convertible to bool types (#1766) 2020-07-12 08:34:45 -07:00
415cd51913 direct_buffered_file -> ostream 2020-07-11 17:29:17 -07:00
e1bfb59619 Fix handling of code units in compile 2020-07-11 09:03:21 -07:00
ba8d98cbb7 Cleanup direct_buffered_file 2020-07-11 08:27:37 -07:00
04a1f6e991 Improve handling of single code units in compile 2020-07-11 08:21:14 -07:00
e4f57bfd7f Add an overload of write for buffer_appender 2020-07-11 08:20:30 -07:00
d870468159 Make append work with fixed-size buffer 2020-07-11 07:27:20 -07:00
e8ec09ae83 Cleanup core-test 2020-07-10 21:25:27 -07:00
a2c4fed981 Double buffering no more 2020-07-10 20:35:14 -07:00
36406509d9 Add a fixed buffer 2020-07-10 06:30:37 -07:00
60c43e8703 Apply clang-format 2020-07-09 09:06:24 -07:00
b998e0f30b Reduce symbol sizes and simplify iterator use 2020-07-09 08:51:43 -07:00
c5adfc51c5 Update README.rst 2020-07-09 06:21:02 -07:00
c4ad94ce26 Update README.rst 2020-07-08 18:17:26 -07:00
c1429651eb Fix image source link 2020-07-08 13:34:47 -07:00
638db5ca5e Use Cmake to find Python and Sphinx-doc.
Signed-off-by: Vitaly Zaitsev <vitaly@easycoding.org>
2020-07-08 08:06:57 -07:00
c090569751 Update readme 2020-07-08 08:01:36 -07:00
1efdb2dde4 Simplify readme 2020-07-08 07:47:18 -07:00
dc69afad14 Cleanup example 2020-07-08 07:44:36 -07:00
445f5d392b Break long lines 2020-07-08 07:36:07 -07:00
23063c3444 Update readme 2020-07-08 07:11:13 -07:00
f57b62575c Move PR template to the top level 2020-07-08 07:01:19 -07:00
f19b1a521e Update version 2020-07-07 07:47:44 -07:00
5c67fefb26 Fix a changelog entry 2020-07-07 06:58:44 -07:00
1d2a556e1b Fix undefined reference error 2020-07-07 06:37:17 -07:00
04c9b62fb4 Merge release branch 2020-07-07 06:34:39 -07:00
6be6762e57 Fix date 2020-07-07 06:32:19 -07:00
f1dd2eb3c0 Bump version 2020-07-07 06:24:32 -07:00
fbf3b943cc Workaround a bug in gcc 2020-07-07 06:06:50 -07:00
a29a01d304 Fix docs 2020-07-07 06:05:00 -07:00
9f0b3afb79 Bump version in namespace 2020-07-06 09:47:27 -07:00
86b2f99f8c Fix the docs 2020-07-06 07:53:07 -07:00
c472ff12d8 Update version 2020-07-06 06:45:20 -07:00
5173a76ba4 Update version 2020-07-05 08:43:47 -07:00
1614af3520 Minor corrections in the changelog 2020-07-05 08:43:01 -07:00
569a9b3a7f Bump version 2020-07-05 07:59:11 -07:00
4e7e3c65a3 Update docs 2020-07-05 07:32:43 -07:00
0f7a6bfa12 Add a section on std::format compatibility 2020-07-05 07:07:29 -07:00
4faec5a5ee Update README.rst 2020-07-05 06:41:51 -07:00
7dbc8ac716 Update changelog 2020-07-05 06:29:05 -07:00
c87dd746fa Update changelog 2020-07-05 06:21:54 -07:00
372175caf8 Revert changelog changes 2020-07-05 06:21:54 -07:00
9047548766 Add ClickHouse to the list of projects (#1751) 2020-07-05 05:57:04 -07:00
d30bca64e3 Revert changelog conversion since GFM is not supported there 2020-07-04 17:43:30 -07:00
d6047cdc4a Update changelog 2020-07-04 15:46:48 -07:00
810241b36e Convert changlog to markdown 2020-07-04 15:20:33 -07:00
661c474739 Rename changelog 2020-07-04 15:14:42 -07:00
7c33059fad Update ChangeLog.rst 2020-07-04 10:16:55 -07:00
9e20883ab3 Update README.rst 2020-07-04 09:37:27 -07:00
41899d5225 Update changelog 2020-07-04 09:31:12 -07:00
f42f459089 Update changelog 2020-07-04 08:40:42 -07:00
2381df654f Update readme 2020-07-04 08:27:57 -07:00
7ae816563e Update README.rst 2020-07-04 08:20:45 -07:00
c56cf3d074 Update changelog and readme 2020-07-04 08:20:10 -07:00
01309a34ab Deprecate arg_formatter 2020-07-04 07:29:11 -07:00
a62d060554 Update changelog 2020-07-04 07:24:49 -07:00
23e3a2eee8 Update changelog 2020-07-03 19:39:08 -07:00
d8e0554b97 Disable numeric formatting by default 2020-07-03 10:35:49 -07:00
1e8eea4f44 Update changelog 2020-07-03 10:31:14 -07:00
44bd5384a9 Fix formatting 2020-07-03 09:18:18 -07:00
20e19387a2 Update changelog 2020-07-03 09:14:11 -07:00
56fed78149 FMT_NUMERIC_ALIGN -> FMT_DEPRECATED_NUMERIC_ALIGN 2020-07-03 08:53:01 -07:00
56e63078ff Make the n specifier an opt-in 2020-07-03 08:02:48 -07:00
31ce6bc702 Fix a conversion warning with Clang10 on Windows (#1750)
Fixes #1747
2020-07-03 05:53:42 -07:00
c9c5b90da7 Fix a typo. Thanks Tracy Chapman from TripleChecker 2020-07-02 15:09:34 -07:00
1f3f84631c Fix a typo 2020-07-02 07:29:38 -07:00
5de62af604 Fix possible infinite recursion in FMT_ASSERT (#1744)
Use std::fprintf for assertion message output preventing infinite
recursion when output to stderr is limited or broken.
2020-07-01 08:28:27 -07:00
cbddab2fe2 Use consistent include style 2020-06-29 09:59:25 -07:00
f69b6eaabd Add a simple buffered stream with no sync 2020-06-28 09:55:29 -07:00
ba363b3a24 Use digit pairs as in unrolledlut 2020-06-27 12:05:38 -07:00
a6f8e7d860 Update changelog 2020-06-27 09:35:02 -07:00
e753244ab6 Update changelog 2020-06-27 06:02:34 -07:00
98a7a8b405 Update changelog and disable internal 2020-06-26 19:07:33 -07:00
3135d95fd9 Don't use non-portable attribute 2020-06-26 10:21:14 -07:00
8630a8f5ff Tweak the docs 2020-06-25 11:29:49 -07:00
cc3a88e6b3 Extract docs from compile.h 2020-06-25 08:36:07 -07:00
79c4b6bd70 Apply clang-format 2020-06-25 08:12:10 -07:00
d130ee070f Document format string compilation 2020-06-25 08:12:10 -07:00
d0f90b5be7 Spelling fixes 2020-06-24 06:29:54 -07:00
6e080660dc Update README.rst 2020-06-24 06:26:58 -07:00
31c3a24266 Spelling fixes 2020-06-23 15:56:16 -07:00
613b3b459d Spelling fixes 2020-06-23 15:55:31 -07:00
978521bb81 Fix a compile error introduced in #1738 2020-06-23 15:17:43 -07:00
4e94c649f9 Deprecate compile 2020-06-23 14:03:37 -07:00
1a83443e6c Add user-defined type support to compilation 2020-06-23 12:45:57 -07:00
8bef1c3b3a Tweaks for EDG based compilers (Intel, nVidia, MCST/Elbrus, etc).
Using the __EDG_VERSION__ macro for checks related to EDG-based
compilers instead of a macros specific for each of ones.
2020-06-23 05:50:25 -07:00
b287c37c65 Do not use -Wl,--as-needed with emscripten.
On some platform, fmt is using the following link flag:
```cmake
  target_link_libraries(fmt -Wl,--as-needed)
```

This is not supported by wasm-ld as of today.
This patch stop using it when compiling using emscripten.

Bug: https://github.com/fmtlib/fmt/issues/1736
2020-06-21 11:46:04 -07:00
2cac8a9d2e Reintroduce UDT support to fmt::to_string and test ADL 2020-06-21 09:21:07 -07:00
9a4cc88426 Add FMT_COMPILE support to format_to 2020-06-20 15:15:41 -07:00
5ddf9ee1bd Streamline default FP formatting 2020-06-20 07:12:50 -07:00
0b3a83f7f4 Update README.rst 2020-06-20 05:37:58 -07:00
5aa5c98738 Added #define WIN32_LEAN_AND_MEAN before including windows.h (#1729)
Co-authored-by: gabime <gmelman1@mgail.com>
2020-06-17 07:44:03 -07:00
397ad1bec3 Optimize common case 2020-06-15 18:30:31 -07:00
7431165f38 Make to_string bypass format 2020-06-15 17:55:16 -07:00
ee4d4c7fd0 Inline compiled format 2020-06-14 11:38:39 -07:00
ab2f8484e0 Finish text::format 2020-06-14 11:04:41 -07:00
e900d735bb Re-enable assert in format_decimal 2020-06-14 09:30:03 -07:00
f4de7b684a Fix ambiguity 2020-06-14 08:26:12 -07:00
1f8f5450b5 Reuse format_decimal 2020-06-14 07:42:52 -07:00
d702a68df2 Fix formatting of bool with FMT_COMPILE and add more tests 2020-06-14 07:16:50 -07:00
e956a14e9e Use write instead of format_int in to_string 2020-06-13 20:07:08 -07:00
98dcc251eb Undo branching reduction 2020-06-13 18:23:52 -07:00
5b8641dddf Undo branching reduction 2020-06-13 16:50:55 -07:00
8c88abde64 Fix sign handling in 'L' 2020-06-13 06:57:19 -07:00
23b976a615 Reduce branching 2020-06-12 19:46:00 -07:00
9edee0e727 Optimize small string parsing 2020-06-12 19:22:33 -07:00
a909d42b76 Fix a warning 2020-06-12 13:49:31 -07:00
16637341b9 Enable compilation for all types 2020-06-12 13:27:21 -07:00
2d71d7e030 Add a simple format string compilation API 2020-06-12 08:37:15 -07:00
d259fcfb05 Tweak comments 2020-06-12 06:22:05 -07:00
704ed557a1 Move project in order to solve a CMake warning
CMake Warning (dev) at /usr/share/cmake-3.17/Modules/GNUInstallDirs.cmake:225 (message):
  Unable to determine default CMAKE_INSTALL_LIBDIR directory because no
  target architecture is known.  Please enable at least one language before
  including GNUInstallDirs.
2020-06-12 06:04:31 -07:00
8603bd20d0 Update README.rst 2020-06-11 17:25:20 -07:00
547f12ae63 Fix a warning (#1722) 2020-06-11 15:02:42 -07:00
f904e8a1b4 c++11 use formatting user-defined types (#1721) 2020-06-11 10:10:39 -07:00
100e8af08a Update README.rst 2020-06-10 07:46:01 -07:00
c11d0f056e Update README.rst 2020-06-10 07:02:12 -07:00
2453ee576a Improve default formatting 2020-06-09 08:59:01 -07:00
47ae521557 MINGW cross compiler fixes 2020-06-09 06:19:22 -07:00
936a1833c2 Add default_arg_formatter 2020-06-08 08:14:34 -07:00
f2c9cb6244 Fix a UB 2020-06-08 06:32:11 -07:00
d3107f8551 Cleanup arg_formatter_base 2020-06-07 20:55:38 -07:00
5e7c70e206 Simplify arg_formatter_base 2020-06-07 19:38:43 -07:00
38cc68b3e5 Inline visitor 2020-06-07 08:36:33 -07:00
6732ea5000 Make symbols readable 2020-06-07 07:49:11 -07:00
57ddc77ce7 Make advance_to a noop for back_insert_iterator 2020-06-06 19:36:39 -07:00
50bad7d62d Optimize format string parsing 2020-06-06 10:15:19 -07:00
8f7a824e47 Inline visit 2020-06-06 09:02:32 -07:00
f11e968708 Optimize format string parsing 2020-06-06 08:15:33 -07:00
09737dd83b Optimize format handler 2020-06-06 07:17:02 -07:00
d9e3d6e6ed Move format_handler to detail 2020-06-06 06:38:48 -07:00
795b47a7b5 Fix a warning (#1712) 2020-06-05 08:24:09 -07:00
95c6ac0cc8 fix typo which caused the loss of the counting information when using a printf context with a truncating_iterator 2020-06-05 07:37:54 -07:00
21409cfdda Fix warnings 2020-06-04 07:50:07 -07:00
88c8d534e7 Move digits10 to where they belong and add comments 2020-06-04 06:39:18 -07:00
0f3eaeac0a Fix a warning 2020-06-04 06:33:11 -07:00
344218510d Ignore /doc/node_modules directory 2020-06-04 05:19:39 -07:00
16aec06179 Cleanup arg_formatter_base 2020-05-31 10:58:52 -07:00
1e1193590d Fix format_decimal overloads 2020-05-31 10:12:34 -07:00
0893c9c2ef Inline parse_format_string 2020-05-30 20:30:18 -07:00
3245145a41 Remove undocumented buffer_range and output_range 2020-05-30 13:07:52 -07:00
57fc44907f Increase VM disk size 2020-05-30 11:25:40 -07:00
7d22bebb6f Remove uses of buffer_range 2020-05-30 06:50:45 -07:00
8f2b5fe74d Don't install sphinx cache files
When building documentation sphinx creates cached files in the .doctrees
directory and aren't required for viewing documentation only for
building. As added benefit this makes fmt reprodcubile as the cached
files are different when the build environment is varied.
2020-05-30 06:14:02 -07:00
f095c67b6a Remove uses of buffer_range 2020-05-29 18:14:03 -07:00
5aabf1f715 Simplify copy_str 2020-05-29 17:59:08 -07:00
19c5b5d159 Simplify arg_formatter 2020-05-29 16:53:12 -07:00
519571edec Simplify arg_formatter_base 2020-05-29 14:44:18 -07:00
ac8dfd841f Improve handling of separators 2020-05-29 08:15:44 -07:00
2c6165a22b Reduce the number of comparisons 2020-05-29 05:42:35 -07:00
28639969ef Use memcpy for copying digits 2020-05-28 22:33:08 -07:00
f5fa1dee54 Support custom FMT_INC_DIR in pkgconfig and cmake configs (#1702)
* Support custom FMT_INC_DIR in pkgconfig and cmake configs

When CMAKE_INSTALL_INCLUDEDIR or FMT_INC_DIR override the header
installation directory, they should be used instead of
${CMAKE_INSTALL_PREFIX}/include in fmt-targets.cmake and fmt.pc.

* Put headers into FMT_INC_DIR/fmt rather than directly into FMT_INC_DIR

This makes FMT_INC_DIR an alias for CMAKE_INSTALL_INCLUDEDIR and
simplifies generation of pkgconfig and cmake configs.

* Do not split target_include_directories
2020-05-28 08:17:34 -07:00
51bf9cfacb Fix Mingw support
If the ``_POSIX_`` flag is set, _fdopen will not be defined by
Mingw headers, which is addressed by this commit.

For what is worth, as opposed to ``fdopen``, ``_pipe`` *will*
actually have the ``_`` prefix when ``_POSIX_`` is set.
2020-05-26 06:39:22 -07:00
1a716caf5d Optimize common case 2020-05-25 19:16:35 -07:00
98d4bbf813 Update README.rst 2020-05-24 06:28:35 -07:00
8c8f74a870 fix zero flag for char types and make zero flag ignored if a precision is specified 2020-05-23 12:46:26 -07:00
bc1b89da26 Temporarily revert parsing changes 2020-05-22 15:39:33 -07:00
a7fb321ac6 Remove a redundant branch 2020-05-22 15:39:33 -07:00
8cadb96506 fix max/min macro (#1697) 2020-05-22 06:38:43 -07:00
297c3b2ed5 Fix an example (thanks Alexey Kuzmenko) 2020-05-20 15:52:19 -07:00
943532fece Make ostream formatter work with compile-time format strings (#1692) 2020-05-20 14:59:57 -07:00
bd8804019b Update README.rst 2020-05-19 19:25:46 -07:00
f230300ac5 Knuth is using fmt library (#1691) 2020-05-19 18:08:32 -07:00
a265e25b79 Optimize small string parsing 2020-05-19 13:44:22 -07:00
2aa2526f64 Optimize small string concatenation 2020-05-19 11:45:09 -07:00
8d78045e7c Move void_t to where it's used 2020-05-18 10:46:25 -07:00
7aafa6bc64 Update analytics 2020-05-18 10:26:22 -07:00
c66aae1652 Adding sentinel support to fmt::join(). (#1689) 2020-05-18 06:31:01 -07:00
6d66de3805 Add c specifier support to integral types (#1652) 2020-05-17 08:44:59 -07:00
6b219a58db fix interaction of space flag and '+' flag, as well as '-' flag and '0' flag (#1687) 2020-05-17 04:27:18 -07:00
eee2023c2a Update signatures 2020-05-15 15:25:02 -07:00
c5ed73aab2 Add fmt::detail::buffer to the docs (#704) 2020-05-15 14:35:55 -07:00
ea1cd9638c Fix apidoc 2020-05-15 10:03:02 -07:00
d3964d7b1e Merge branch 'master' of github.com:fmtlib/fmt 2020-05-15 09:43:38 -07:00
d18c6723a2 Update docs 2020-05-15 09:43:35 -07:00
96c18b26c2 make plus flag for printf not be ignored for char argument (#1683)
* make plus flag for printf not be ignored for char argument

* clarify overwriting of alignment specifiers for printf with char argument
2020-05-15 06:45:51 -07:00
ba25baeb97 Apply doc patch to 6.2.1 2020-05-14 19:11:40 -07:00
981b517ccf nested replacement fields may omit arg_id (#1681)
syntax.html already has examples like `fmt::format("{:.{}f}", 3.14, 1)` using this, 
and https://en.cppreference.com/w/cpp/utility/format/formatter#width_and_precision shows that this is the case for the C++20 std::format

The Format Specification Mini-Language grammar seems to be the only one not showing this; update it to match.
2020-05-13 17:20:05 -07:00
922ea924bf Make dynamic_format_arg_store reusable and add reserve() (#1677)
Implemented #1674: make dynamic_format_arg_store reusable and add
reserve() for better memory menagement.
2020-05-12 11:00:42 -07:00
e0d98923c7 Update version 2020-05-10 18:05:46 -07:00
8069265373 internal -> detail (#1538) 2020-05-10 07:34:30 -07:00
963ee08310 Simplify named arguments 2020-05-09 16:43:31 -07:00
02a6fe59fb Named arguments go brrr 2020-05-09 13:22:38 -07:00
de290f5c4c Ditch internal::arg_map 2020-05-09 12:43:11 -07:00
d0623de510 Bump version 2020-05-09 10:57:04 -07:00
73e335ed38 Make implicit capture explicit for C++20 (#1669) 2020-05-09 10:55:37 -07:00
b4d46e3988 Update changelog 2020-05-09 10:05:16 -07:00
a182f7341e Update changelog 2020-05-09 08:30:31 -07:00
68201831a5 Support named args in dynamic_format_arg_store (#1655). (#1663)
Dynamic arguments storage. Implementation of enhancement from issue
#1170.
2020-05-09 06:25:03 -07:00
7f723fbcb8 Consistently namespace qualify size_t 2020-05-07 15:59:46 -07:00
c06851456d Purge basic_writer 2020-05-07 15:04:48 -07:00
2f05054dd3 Purge basic_writer 2020-05-07 11:35:41 -07:00
f0ce21164c Revert enum change 2020-05-07 07:25:33 -07:00
44639b11fe Fix some warnings (#1667)
* Fix sign-conversion warning

* Add missing "extern template" declarations for non-header-only build

* Use typed enums to fix Wsigned-enum-bitfield warnings

* Consolidate FMT_HEADER_ONLY code
2020-05-07 06:14:07 -07:00
1c86a99e8f Purge basic_writer 2020-05-06 18:46:01 -07:00
8f511fc12f Make copyfmt not throw (#1666) 2020-05-06 17:38:46 -07:00
59fe455f36 Remove compatibility stubs 2020-05-06 07:31:35 -07:00
b0f47a13e6 Separate nonfinite formatting 2020-05-06 07:19:37 -07:00
d6cea50d01 Remove deprecated APIs 2020-05-05 20:03:48 -07:00
40bc7163fb Move FMT_MAYBE_UNUSED to where it's actually used 2020-05-05 19:41:07 -07:00
080e44d0bf Fix inconsistent type detection (#1662) 2020-05-05 19:09:21 -07:00
7e57cace5d Exclude std::abort from compilation when compiling CUDA with Clang (#1661) 2020-05-04 06:21:21 -07:00
7b66e2f219 Inherit arg_formatter_base from basic_writer 2020-05-03 21:05:45 -07:00
bab3f58003 Refactor pointer formatting 2020-05-03 20:33:25 -07:00
9cc7edfddc Move int_writer to the namespace scope 2020-05-03 17:34:48 -07:00
8d9d528bf5 Improve handling of alignment 2020-05-03 10:58:18 -07:00
8efd1a8ef6 Improve handling of alignment 2020-05-03 10:08:57 -07:00
a71bc9c825 Use '0' fill with numeric align for consistency with std::format 2020-05-03 09:52:31 -07:00
60d85d598c Suppress ubsan warning 2020-05-03 08:43:10 -07:00
c3099beb6f Cleanup 2020-05-02 22:00:34 -07:00
cbb4cb8991 Remove undocumented deprecated APIs 2020-05-02 21:34:44 -07:00
b85e9ac38b Simplify vformat_to 2020-05-02 21:34:44 -07:00
e3710ab972 FMT_CONSTEXPR -> constexpr 2020-05-02 21:34:44 -07:00
d59751f0f0 Update date formatting example to use threadsafe localtime 2020-05-02 09:04:31 -07:00
d6abb2fa03 Reduce library size 2020-05-01 17:23:45 -07:00
e9fdea90b5 Update README.rst 2020-05-01 10:40:07 -07:00
44b6584f22 Update README.rst 2020-05-01 10:39:28 -07:00
78f041ab5b build: Fix installation paths
It is not generally true that `CMAKE_INSTALL_<dir>` variables are relative paths:

https://github.com/jtojnar/cmake-snips#concatenating-paths-when-building-pkg-config-files
2020-05-01 10:27:24 -07:00
7ca89bf87a Reduce template bloat in write_int 2020-05-01 07:56:57 -07:00
3c114d091b Fix a shadowing warning (#1658) 2020-05-01 07:00:25 -07:00
e2ef12a8c0 Allow to avoid inclusion of os.cc in fmt target
- Allows to avoid part of #1654
- Not possible to use with MASTER_PROJECT as testing uses it a lot
2020-05-01 06:24:22 -07:00
bca82719ab Pass iterator by value 2020-04-30 21:06:17 -07:00
99da389627 Make write_padded non-members 2020-04-30 16:05:30 -07:00
f19d667943 Bump fuzzer allocation limit 2020-04-30 08:45:50 -07:00
3e69847616 Reduce branching in write_padded 2020-04-30 06:33:45 -07:00
9ac1eebd47 Reduce library size 2020-04-29 17:37:05 -07:00
e2ff910675 Replace FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION with fmt-specific macro (#1650)
Signed-off-by: Asra Ali <asraa@google.com>
2020-04-29 09:12:43 -07:00
f2ed03b919 Fix a warning (#1649) 2020-04-28 06:39:24 -07:00
9dde9f0131 Reduce library size 2020-04-27 20:43:30 -07:00
b1af642d1d Reduce library size 2020-04-27 18:50:49 -07:00
4a617f25c6 Clarify encoding conversion in chrono 2020-04-27 09:57:08 -07:00
6f435f55c8 Improve compile time by using extern template (#1452) 2020-04-26 14:02:15 -07:00
cb475cb884 Clarify why we don't check argument id 2020-04-26 13:38:42 -07:00
1e1ac6e964 Check dynamic width/precision id at compile time (#1614) 2020-04-25 08:36:24 -07:00
e51c449fe6 Revert "Check dynamic widht/precision id at compile time (#1614)"
This reverts commit 7d748a6f82.
2020-04-25 07:43:56 -07:00
0463665ef1 Don't access a C string past precision in printf (#1595) 2020-04-22 17:10:23 -07:00
7d748a6f82 Check dynamic widht/precision id at compile time (#1614) 2020-04-22 14:45:37 -07:00
2b75bd7ce6 Get rid of do_check_format_string 2020-04-22 12:15:29 -07:00
4a1d5931cb Simplify udl_formatter with FMT_STRING 2020-04-22 11:26:05 -07:00
811b0f9054 Enable compile-time error tests 2020-04-22 11:00:20 -07:00
450e8eed97 Fix markup 2020-04-22 09:30:09 -07:00
b8fbcec1be Clarify formatter reuse 2020-04-22 09:15:52 -07:00
56bc86ffac Suppress bogus MSVC analysis warnings 2020-04-22 07:51:25 -07:00
3f79357ef0 Fix a recent regression in handling max packed arguments 2020-04-22 07:15:19 -07:00
8a11148f99 Add Facebook Folly to the list of projects 2020-04-22 06:16:07 -07:00
e371e8b686 Tweak readme 2020-04-22 06:13:36 -07:00
813732fede Improve readme formatting 2020-04-22 06:07:12 -07:00
3670d5b3f6 README: add vectorized.io/redpanda in the list of users 2020-04-22 06:04:09 -07:00
9e2ad7cf68 Add windows terminal to the projects using {fmt} 2020-04-21 15:47:04 -07:00
63479c8519 Use a delegating ctor and add inlines 2020-04-20 19:17:16 -07:00
5944fcad37 Remove remaining wchar_t instantiation 2020-04-19 16:48:15 -07:00
e253b371b2 Don't generate RTTI for allocator 2020-04-19 15:57:48 -07:00
0c86f467bc Fix build on ancient gcc 2020-04-19 09:52:40 -07:00
1929df4bc2 Simplify format_args 2020-04-19 09:21:39 -07:00
a138221813 Always inline arg_data functions 2020-04-19 08:20:00 -07:00
04e0dfd4bd Always inline value ctors 2020-04-19 08:05:02 -07:00
04cde756bc Simplify checks 2020-04-19 07:35:19 -07:00
c9a57b9a81 Fix incorrect assumptions about nul termination 2020-04-18 06:51:52 -07:00
f46f5ecaf0 Reenable constexpr _compile on GCC 9 2020-04-17 06:10:57 -07:00
6e8d7e2776 Don't use constexpr on Intel compiler (#1628) 2020-04-16 07:08:04 -07:00
567ed03f88 Merge arg overloads and cleanup 2020-04-15 08:44:58 -07:00
c3fa333140 Remove warning in core.h with when compiling with gcc and -Wshadow
In file included from build/_deps/fmt-src/include/fmt/format.h:44:0,
                 from src/main.cpp:5:
build/_deps/fmt-src/include/fmt/core.h: In member function ‘const T& fmt::v6::internal::dynamic_arg_list::push(const Arg&)’:
build/_deps/fmt-src/include/fmt/core.h:1256:10: error: declaration of ‘node’ shadows a member of ‘fmt::v6::internal::dynamic_arg_list’ [-Werror=shadow]
     auto node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
          ^~~~
build/_deps/fmt-src/include/fmt/core.h:1236:37: note: shadowed declaration is here
   template <typename = void> struct node {
2020-04-15 07:31:24 -07:00
84898b4626 Remove warning in format.h when compiling with gcc and -Wshadow
build/_deps/fmt-src/include/fmt/format.h: In member function ‘decltype (ctx.out()) fmt::v6::formatter<fmt::v6::bytes>::format(fmt::v6::bytes, FormatContext&)’:
build/_deps/fmt-src/include/fmt/format.h:3251:58: error: declaration of ‘writer’ shadows a global declaration [-Werror=shadow]
     internal::basic_writer<range_type> writer(range_type(ctx.out()));
                                                          ^~~
build/_deps/fmt-src/include/fmt/format.h:2741:53: note: shadowed declaration is here
 using writer FMT_DEPRECATED_ALIAS = internal::writer;
2020-04-15 07:31:24 -07:00
538d83fd08 Cleanup named arguments 2020-04-15 06:28:41 -07:00
8a4630686e Improve handling of named arguments 2020-04-14 11:56:55 -07:00
a9d62d3f35 Add check for CompiledFormat to avoid ambiguous call 2020-04-14 05:59:02 -07:00
fdcf7870a2 Add stack-based named argument storage 2020-04-13 08:03:51 -07:00
5899267c47 Fix a clang-tidy warning 2020-04-12 08:27:39 -07:00
07b4c246ea Fix a typo 2020-04-12 08:18:47 -07:00
e99809f29d Fix ostream support in sprintf (#1631) 2020-04-12 07:53:17 -07:00
3cd5179f32 Fixed clang tidy warning -multiple declarations in a single statement reduces readability 2020-04-12 06:29:09 -07:00
7404e33a73 Fix clang warning about explicit ctor 2020-04-12 06:19:16 -07:00
3aab2171ed Clean up basic_format_args 2020-04-11 08:22:53 -07:00
7645ca0724 Clean up printf 2020-04-11 08:01:00 -07:00
e30d8391e4 Suppress an MSVC warning (#1622) 2020-04-11 07:49:00 -07:00
8cd8ef03eb Simplify warning suppression 2020-04-11 06:17:31 -07:00
bbb6b357c7 Add floating-point L specifier (#1624) 2020-04-10 07:16:20 -07:00
36ea32640f Suppress a bogus MSVC warning 2020-04-10 06:44:07 -07:00
141a00d642 Define FMT_EXTERN_TEMPLATE_API on export 2020-04-09 11:54:55 -07:00
3860edc5d9 Bump version 2020-04-08 14:48:14 -07:00
7d01859ef1 Fix handling of unsigned char strings in printf 2020-04-08 13:05:42 -07:00
63b23e786a Merge branch 'master' of github.com:fmtlib/fmt 2020-04-08 13:03:44 -07:00
4999796c15 Fix the docs 2020-04-08 07:52:36 -07:00
34b3f7b7aa Avoid windows issue with min() max() macros
Including the ``windows.h`` file without defining ``NOMINMAX`` will define the `min()` and `max()` macros which will result in issues compiling any C++ code that uses any variant of `max`, for example `std::numeric_limits<std::streamsize>::max()` and many others.  Although max() isn't used in Fmt anywhere, it is often used in codes that include a format include file so simply upgrading to the current version of lib::fmt will break the windows build which worked prior to the update...
2020-04-07 08:34:34 -07:00
27e3c0fe9b Update signature in the docs 2020-04-06 07:17:41 -07:00
9bdd1596ce Update version 2020-04-05 06:46:41 -07:00
d151562bdd Fix punctuation in changelog 2020-04-04 12:49:56 -07:00
346500e70b Fix gcc version check 2020-04-04 11:23:40 -07:00
a434a8f778 Update changelog 2020-04-04 06:34:23 -07:00
9eb47d951a Fix markup 2020-04-03 08:49:29 -07:00
51c58a56ba Bump version 2020-04-03 08:32:45 -07:00
3fc33f6273 Update changelog 2020-04-03 08:29:02 -07:00
2e32db5b99 Update changelog 2020-04-03 07:42:02 -07:00
c1ce6e01f7 Update changelog 2020-04-02 08:18:42 -07:00
1c3c80dc1f Update changelog 2020-04-02 07:27:58 -07:00
d1d653d895 Implement the L specifier 2020-04-02 06:58:38 -07:00
73c8437485 Follow naming conventions 2020-04-01 09:30:28 -07:00
e588b02b17 Fix posix-mock-test 2020-04-01 08:42:14 -07:00
1a62711d01 Reduce binary size 2020-03-31 08:07:11 -07:00
5b02881582 Merge branch 'master' of github.com:fmtlib/fmt 2020-03-28 09:46:44 -07:00
a133187a8c Update changelog 2020-03-28 09:44:27 -07:00
80ce222ca6 Fix wide print overload (#1609) 2020-03-28 09:44:18 -07:00
770a94edef Use FMT_THROW macro where applicable 2020-03-27 12:17:22 -07:00
2864e8432a Update readme and add compatibility option 2020-03-26 07:18:27 -07:00
21a295c272 Undo comment change 2020-03-25 08:14:31 -07:00
96c68afe69 Fix -Wsign-conversion warnings 2020-03-25 07:46:00 -07:00
664dd88e31 Enable FMT_STRING() use with types other than string literals 2020-03-24 12:56:21 -07:00
69779b4ed6 Fix handling of small precision in general format 2020-03-24 09:01:57 -07:00
01a172c969 Add .vs to .gitignore 2020-03-23 15:01:02 -07:00
08ca40ea91 Detect /utf-8 in MSVC 2020-03-22 08:19:38 -07:00
dd97f4920c Improve exception safety in dynamic_format_arg_store 2020-03-21 08:58:50 -07:00
2951169481 Move FMT_USE_FLOAT and friends to fmt/format.h 2020-03-20 07:55:43 -07:00
d3e668418f Allow disabling floating point support (#1590)
* Allow disabling floating point support

Add FMT_USE_FLOAT, FMT_USE_DOUBLE and FMT_USE_LONG_DOUBLE to allow a
user of the library to configure the float types they want to allow.
This is specially useful in embedded environements where code size is
important.

* Avoid conditional macros to disable float support

* Add is_supported_floating_point constexpr function

* Fix empty-body warning
2020-03-20 06:46:31 -07:00
52d0e1bbe3 Don't use properties when setting FMT_LIB_NAME 2020-03-19 08:35:09 -07:00
5d32ccfc31 Add back missing OUTPUT_NAME in target properties. (#1598) 2020-03-19 07:01:51 -07:00
3cf619de55 Simplify dynamic_format_arg_store 2020-03-17 07:13:46 -07:00
2559983e7a Color formatting fixed for wide strings (fixes issue #1594) (#1596)
* Use std::char_traits::length for ansi_color_escape::begin

-Fixes issue #1594 https://github.com/fmtlib/fmt/issues/1594
2020-03-17 06:24:42 -07:00
026f99178e Simplify dynamic store 2020-03-16 19:10:41 -07:00
9f70fc3e7a Minor tweaks for dynamic_format_arg_store 2020-03-16 07:58:15 -07:00
6012dc9ab4 Dynamic arguments storage. Implementation of enhancement from issue #1170. (#1584) 2020-03-16 07:00:29 -07:00
85050aa2e6 Ability to join elements of std::initializer_list was added 2020-03-15 16:10:00 -07:00
ff486a72a7 Allow leading zeros in precision (#1579) 2020-03-14 11:37:38 -07:00
678341275b Deprecate fmt::char8_t 2020-03-14 10:32:34 -07:00
6f01b6ebb6 Fix a typo in CMake config: STRINGS -> STRING 2020-03-14 09:50:25 -07:00
61c5a51604 Fix handling of empty tuples (#1588) 2020-03-14 07:41:08 -07:00
02bfd8a9a5 Add FMT_HAS_CPP14_ATTRIBUTE / FMT_HAS_CPP17_ATTRIBUTE to test for language-specific attributes.
FMT_DEPRECATED is now defined as FMT_HAS_CPP14_ATTRIBUTE(deprecated), as this attribute was introduced in C++14.

FMT_FALLTHROUGH is now defined as FMT_HAS_CPP17_ATTRIBUTE(fallthrough), as this attribute was introduced in C++17.

FMT_MAYBE_UNUSED is defined as FMT_HAS_CPP17_ATTRIBUTE(maybe_unused), as this attribute was introduced in C++17.

FMT_MAYBE_UNUSED has been applied to fix a couple of -Wunused-member-function warnings from clang.
2020-03-13 09:03:52 -07:00
3c24052cf1 Workaround 'cannot call member function without object' error on gcc 4.9 2020-03-11 17:39:32 -07:00
f72a905eb3 Fix handling of volatile enums 2020-03-11 08:40:57 -07:00
941d5e147a Workaround broken fallthrough attribute in the PGI compiler (#1583) 2020-03-11 07:56:23 -07:00
ee2b828b9a Tweak a comment 2020-03-09 11:27:14 -07:00
5bb8856655 Workaround for broken [[deprecated]] in PGI compiler (#1581)
* Workaround broken [[deprecated]] in PGI compiler
  - similar to Intel and NVCC, add workaround for PGI compiler
2020-03-09 11:25:38 -07:00
1c0c59d4a0 Fix empty debug postfix 2020-03-09 08:34:02 -07:00
b1adaa9881 Remove gcc 4.4 workaround 2020-03-07 14:50:52 -08:00
48e8d0ebef set_doc -> set_verbose 2020-03-07 14:31:39 -08:00
ce00979152 Cleanup CMake config 2020-03-07 08:18:01 -08:00
db4a6cfbf9 is_static_compiled_format -> is_compiled_format 2020-03-06 07:25:34 -08:00
29a1ea795a Fix clang -Wdisabled-macro-expansion warning from FMT_STRING_IMPL.
FMT_STRING_IMPL has an internal helper named FMT_STRING, however FMT_STRING is also the name of the macro that invokes FMT_STRING_IMPL.

Renaming this helper avoids the appearance of a recursive macro.
2020-03-06 07:00:47 -08:00
8a06ca84c7 Fix ambiguous overloads of format & format_to 2020-03-05 12:22:43 -08:00
153f753bde Deprecate undocumented _u suffix 2020-03-04 19:20:19 -08:00
eafd079868 Improve width computation 2020-03-04 17:17:34 -08:00
0c6919ec72 Make FMT_DEBUG_POSTFIX a cache variable (#1566) 2020-03-04 08:37:11 -08:00
197a5c3721 Apply clang-format 2020-03-04 08:37:00 -08:00
68742e1d87 Fix clang -Wsign-conversion warning in grisu_count_digits. (#1573)
grisu_count_digits is only used by grisu_gen_digits, which assigns the unsigned result to a (signed) int.

Although grisu_count_digits always returns a positive integer this keeps its return type in sync with the type its result is assigned to.
2020-03-04 06:48:41 -08:00
1e8493196e Make compile-time checks in format_to handle references 2020-03-01 07:57:34 -08:00
58e6c84f5a Fix simple -Wsign-conversion cases. (#1571)
* Fix -Wsign-conversion in bigint::subtract_aligned.

n is assigned a size_t, and only used for comparisons with j.

j is assigned 0, compared to n (size_t), and passed to basic_memory_buffer::operator[] (size_t).

* Fix -Wsign-conversion in bigint::assign.

num_bigits is initialised to 0, is only ever incremented, and is passed to basic_memory_buffer::operator[] (size_t) and basic_memory_buffer::resize (size_t).
2020-03-01 07:22:15 -08:00
75a4525e5f Move FMT_CLANG_VERSION definition to core.h (#1568)
Previously format.h defined FMT_CLANG_VERSION after including core.h, however core.h tests FMT_CLANG_VERSION when it defines FMT_API.
2020-02-29 17:19:34 -08:00
6ccb2e241b Add FMT_NORETURN to assert_fail prototype. (#1569)
When building with -Werror,-Wmissing-noreturn clang identifies that assert_fail could be declared with the 'noreturn' attribute.
2020-02-29 17:17:55 -08:00
bed134a4aa Tentative fix for default template param in friend error 2020-02-27 15:29:46 -08:00
b2d3a86ec0 Make FMT_ASSERT work in constexpr on clang 4.0.1 2020-02-26 06:26:46 -08:00
13d82e32bd Don't use internal GTest API 2020-02-24 11:32:34 -08:00
2161a73f2b Fix FMT_FORMAT_AS const specifier position (#1554)
The current `FMT_FORMAT_AS` macro will make `formatter<Char *>::format`
have the first argument type `const Char *&` which is incorrect an
should be `Char *const &`.  This pull request fixes that by changing the
first argument type in the macro definition body from `const Type &` to
`Type const &`.
2020-02-23 07:27:22 -08:00
e00997b004 improved use of find (#1560)
* improved use of find

*begin is supposed to be different from '{' when this find is used, so we can avoid checking it.
2020-02-21 14:43:06 -08:00
0415cf2350 add const begin and end overload to buffer (#1553)
* add const begin and end overload to buffer

since there is a const overload for data I think there should also be one for begin and end
2020-02-19 14:59:50 +01:00
3bafd0749b Fix to_string docs 2020-02-15 09:51:35 +01:00
f733882b55 Remove misleading FMT_USE_WINDOWS_H 2020-02-14 14:09:27 +01:00
dc22360c34 Workaround broken UDL templates in GCC < 6.4 2020-02-10 17:08:14 +01:00
1f1b50707c Make formatter override implicit conversion to a C string 2020-02-07 19:24:36 -08:00
24924128e3 Fix a link error in gcc8 (#1548) 2020-02-07 18:34:05 -08:00
c54cd71800 only modify CMAKE_RUNTIME_OUTPUT_DIRECTORY if it is not already set 2020-02-07 07:10:03 -08:00
43e9b29e50 Only use compiler features if available 2020-02-06 15:43:33 -08:00
b55ea58705 string_view::char_type -> value_type (#1539) 2020-02-01 12:27:44 -08:00
4098970db2 Update README.rst 2020-01-31 11:33:51 -08:00
314e15001f Fix symbol visibility on Linux when compiling with -fvisibility=hidden (#1535)
Make FMT_API symbols use the default visibility on non-Windows
platforms. Otherwise, one cannot use the generated fmt library when
compiling globally with -fvisibility=hidden.

Fixes compile errors like:

```
../3rdParty/fmt/include/fmt/core.h:757: error: undefined reference to 'fmt::v6::internal::assert_fail(char const*, int, char const*)'
```

Note that the symbol exists, but is local:

```
$ nm -C libfmtd.so.6.1.3  | grep assert_fail
                 U __assert_fail
0000000000233ffa t fmt::v6::internal::assert_fail(char const*, int, char const*)
```

With this patch, the compile error is gone and the symbol is properly
exported:

```
$ nm -a bin/libfmtd.so -C | grep assert_fail
                 U __assert_fail
00000000002366ba T fmt::v6::internal::assert_fail(char const*, int, char const*)
```

Change-Id: I96054e622d9a2ae81907e1b01a1033e629767a91
2020-01-30 06:26:18 -08:00
f499b393d1 Apply coding conventions 2020-01-26 19:48:48 -08:00
6c30f41443 Configure fmt.pc library name correctly.
Simplify getting library name.

Add FMT_DEBUG_SUFFIX variable.
2020-01-26 19:48:14 -08:00
1acb73f970 Fix formatting std::chrono::duration types to wide strings (#1533)
* Fix formatting chrono durations to wide strings

* Make format buffers const correct

* Add FormatWide chrono test case

* Fix incorrect wide encoding of 'µs'
I think might be a source file encoding issue, so I used \u00B5 instead.

* Update FormatWide test to use proper encoding of µs

* Revert changes to format_localized's parameters

* Use different overload of `std::time_put<T>::put` to avoid needing a format string

* Use utf8_to_utf16 instead of having redundant overloads of get_units

* Revert some minor changes

* Remove FMT_CONSTEXPR from expression

This should hopefully fix compilation on VS <2019

* Make suggested changes from code review

* Run clang-format on chrono.h

* Make sure unit isn't null before constructing a string_view from it
2020-01-23 18:48:36 -08:00
09a13244c8 Disallow passing non-string-literals to FMT_STRING 2020-01-22 21:05:46 -08:00
419db8baa1 Fix length computation of constexpr C strings 2020-01-22 18:25:07 -08:00
9fc4161f5e fix interal compiler error when building with mingw 2020-01-22 18:14:46 -08:00
25d6916b3a Fix so can work without locale defined
If `FMT_STATIC_THOUSANDS_SEPARATOR` defined, then locale is not included or defined, so this call will be unresolved.  I think this is the correct fix based on the code in `format-inl.h` and `format.h`
2020-01-22 07:26:03 -08:00
0b2eb6501c Add locale example 2020-01-20 08:42:16 -08:00
fd1cabe464 Workaround a bogus MSVC warning 2020-01-20 06:56:22 -08:00
a844d7ab81 Add namespaces 2020-01-19 19:20:48 -08:00
47d3968092 Add more examples 2020-01-19 19:15:54 -08:00
7800173eb1 Update fill docs 2020-01-19 18:57:32 -08:00
b4218aa0f8 Test invalid fill 2020-01-19 16:52:36 -08:00
8a3a8177d6 Bump version 2020-01-19 15:34:30 -08:00
e5f2f8ce7a Add variable-width fill support (#1109) 2020-01-19 14:49:51 -08:00
75765bfad5 Avoid unnecessary unsigned overflows (#1515) 2020-01-18 08:19:27 -08:00
9bd9738da0 Remove static and simplify names 2020-01-18 07:43:59 -08:00
bd5f903f28 Add a locale example 2020-01-18 07:11:45 -08:00
06e437fd98 Move docs to the proper place 2020-01-18 06:59:21 -08:00
1bd4f54fa6 update format 2020-01-17 11:07:55 -08:00
11cc2903e4 re-fix url link 2020-01-17 11:07:55 -08:00
b124e3e8e7 fix url link 2020-01-17 11:07:55 -08:00
ffd5f3469f Correct display format 2020-01-17 11:07:55 -08:00
0f0e5ddf5f Add vcpkg installation instructions 2020-01-17 11:07:55 -08:00
1f110702a1 Remove redundant braces 2020-01-15 15:07:30 -08:00
4ccbe4b5f2 Avoid namespace clash for fmt
## Problem

In the case of an existing `fmt` namespace (in my project this looks like `Project::fmt`) it is possible to get a namespace clash in debug builds (MSVC 2017)

## Proposed Solution

When referencing `fmt` internally, be explicit that it is relative to the global namespace using `::fmt`
2020-01-15 11:23:24 -08:00
40638a75b3 Use C++11 compatible std::is_same operations
The `operator()` member function of `std::is_same` was added in C++14.  For C++11, the `::value` needs to be used instead.
2020-01-15 11:20:47 -08:00
c8dd9cc99d Use type_identity to block unnecessary template argument deduction (thanks Tim Song) 2020-01-15 10:27:50 -08:00
4bbe57cebf Work-around for nvcc
The nvcc compiler (at least up to 9.2) defines `__SIZEOF_INT128__`, but doesn't support 128-bit integers on device code:
```
error: "fmt::v6::format_arg_store<fmt::v6::basic_format_context<std::back_insert_iterator<fmt::v6::internal::buffer<char>>, char>, const char *, int, const char *>" contains a 128-bit integer, which is not supported in device code
```
2020-01-15 07:31:58 -08:00
55b6130055 Use C++11-compatible operations
The `std::is_base_of<T,U>()` and `std::is_reference<T>()` member functions were added in C++14.  To maintain C++11 compatibility, use the `::value` instead.

Current code fails on intel-17 and other compilers if using strict C++11
2020-01-15 07:23:39 -08:00
ae3ea156ea Fix for older versions of intel compiler
The intel-17 and intel-18 compilers seem to require that `u` be `const`:
```
/src/fmt/format.h(226): warning #437: reference to local variable of enclosing function is not allowed
        char data[sizeof(u)];
```
If `u` is declared as `const auto u =1u` instead of just `auto u=1u`, the file compiles with no warnings.
2020-01-14 17:56:06 -08:00
77165fdf85 Use FMT_NOEXCEPT instead of noexcept directly
Otherwise breaks on compilers without noexcept support
2020-01-14 09:31:31 -08:00
65ac626c58 Improve join docs 2020-01-12 07:26:16 -08:00
cd0b3f9695 check if _SECURE_SCL is defined not equal to 0 2020-01-09 15:01:48 -08:00
cef1e4354b Optimize grisu_gen_digits 2020-01-07 16:11:18 -10:00
0201c8db21 Restructure float_format 2020-01-07 14:41:30 -10:00
9e3f3e8cff Fix handling of output iterators in format_to_n (#1506) 2020-01-05 09:59:01 -10:00
aa07c57654 Move vprint_mojibake to the internal namespace 2020-01-04 08:31:18 -10:00
a73d89e9c7 Catch invalid uses of fmt::arg 2020-01-04 07:11:35 -10:00
cb8e7caf7c Convert 'char8_t' character sequences to 'char' sequences
Otherwise, Google Test will insist on inserting 'char8_t' NTBS into 'char' streams, but basic_ostream<char>::operator<< overloads taking 'char8_t' arguments are defined as deleted by P1423.
Handling individual 'char8_t's is done inline.

This fixes the compilation errors seen in C++20 mode beginning with VS2019 Update 2.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2020-01-04 07:01:48 -10:00
b3fd0005dd Suppress a bogus -Wdouble-promotion warning 2020-01-03 06:57:14 -10:00
7b478f9dec Simplify example 2020-01-02 07:31:45 -10:00
c85efef312 More showpoint fixes and tests (#1498) 2019-12-30 13:08:35 -10:00
455a7c0787 Clarify lifetime of basic_format_args 2019-12-30 08:51:47 -10:00
674c326d7c Update syntax.rst 2019-12-29 07:25:34 -10:00
061a9897fe Update syntax.rst 2019-12-26 16:49:40 -10:00
d2d1c9c560 warning C4267: 'argument': conversion from 'size_t' to 'DWORD', possible loss of data 2019-12-26 08:07:24 -08:00
b6e19e5953 Update apidoc 2019-12-24 12:08:37 -08:00
f219dcd59b Add fmt::bytes 2019-12-24 10:45:15 -08:00
dea7fde8b7 Deprecate u8string_view 2019-12-24 09:44:57 -08:00
5390e29d42 Enable mojibake 2019-12-24 08:42:29 -08:00
9f6434dcde Improve UTF-8 handling on Windows 2019-12-23 16:19:11 -08:00
dac9a7f99d Improve UTF-8 handling on Windows 2019-12-22 12:05:28 -08:00
3ca9533f38 Flatten forward 2019-12-22 08:23:54 -08:00
7eec036d9a Improve UTF-8 support 2019-12-21 19:53:52 -08:00
e6b37b4aff Handle block boundaries in utf8_to_utf16 2019-12-21 16:33:34 -08:00
8cf4c52068 Apply clang-format 2019-12-21 13:10:45 -08:00
74532c23a3 Make type a scoped enum 2019-12-21 12:22:17 -08:00
b308159be5 Make round_direction a scoped enum 2019-12-21 09:24:42 -08:00
162995fedd Add os.h to docs 2019-12-18 14:17:49 -08:00
8b41362a0a Add trailing decimal point if # is specified (#1476) 2019-12-18 12:41:56 -08:00
1b1c70108a trailing_zeros -> showpoint 2019-12-18 12:12:09 -08:00
d7e72a09e0 Simplify FMT_STRING_IMPL 2019-12-18 11:50:47 -08:00
2201890d7a Apply clang-format and update inclusion guards 2019-12-18 11:17:36 -08:00
6100ed4bb3 Eliminate NVCC NVidia compiler emits unreachable code warnings
Similar to the MSC Compiler, the NVidia NVCC compiler also
emits unreachable code warnings when there is a return
statement following an exception.  These changes eliminate
those warnings.
2019-12-18 10:39:40 -08:00
1afe201ae8 Handle block boundaries in utf8_to_utf16 2019-12-18 10:35:51 -08:00
cd2b99032f Chore(readme): use https (#1481) 2019-12-17 06:48:27 -08:00
9acf89fef6 Mitigate MSVC issue with min/max macros (#1480) 2019-12-16 08:24:00 -08:00
9ea42fb26e Rename posix-test to os-test 2019-12-15 16:43:40 -08:00
da2569827e posix.cc -> os.cc 2019-12-15 12:36:15 -08:00
35959a31d7 Move OS-specific APIs to a separate header 2019-12-15 11:46:45 -08:00
ec2463c905 Implement utf8_to_utf16 using utf8_decode 2019-12-15 09:35:26 -08:00
0012917f69 Add a UTF-8 decoder 2019-12-15 07:28:19 -08:00
9e450911fa Give an error on precision overflow 2019-12-14 07:45:27 -08:00
068d20bc31 Avoid shadowing warnings in FMT_STRING 2019-12-14 07:00:08 -08:00
a99fbe67b9 Apply a typo fix retroactively 2019-12-14 06:50:53 -08:00
adbed11ed4 Fix a typo 2019-12-13 15:49:40 -08:00
8ab1c5c6e8 Squelch MSVC warning exporting subclasses of runtime_error (fix for PR #1433) (#1470)
* Squelch MSVC warning exporting subclasses of runtime_error

When compiling {fmt} as a DLL, MSVC complains that we are exporting
classes that inherit from "std::runtime_error", which we are not
exporting.

In this case, it's not really a problem because that symbol is already
exported via the C++ stdlib. So we just add a pragma to silence the
warning.

* Fix compilation with MinGW

Commit 3bc28fcc6b ("Squelch MSVC warning exporting subclasses of
runtime_error", 2019-11-29) silenced a MSVC warning under. The MinGW
compiler also defines _WIN32, but does not support the "warning" pragma.

Introduce a helper macro to squelch the MSVC warning only when using the
Microsoft compiler.

Signed-off-by: Beat Bolli <dev@drbeat.li>

* Fix compilation with VS2015 (#1450)

VS2015 does not support the __pragma(...) syntax in the midst of a
class declaration, so move it to just before the declaration.
2019-12-13 12:16:36 -08:00
a770009fcc Improve error reporting 2019-12-13 11:34:03 -08:00
598e6042d1 warning C4468: 'fallthrough': attribute must be followed by a case label or a default label 2019-12-12 06:25:33 -08:00
e09814dc93 Merge branch 'master' of github.com:fmtlib/fmt 2019-12-11 15:44:44 -08:00
b272fb3605 Extend FMT_FALLTHROUGH compatibily to gcc and clang pre-C++17 (#1469) 2019-12-11 14:28:20 -08:00
f94b7364b9 Update version 2019-12-11 06:16:42 -08:00
7abec071b5 Update changelog 2019-12-11 06:15:06 -08:00
b7eb8c8921 Prepare for the next release 2019-12-10 21:50:14 -08:00
ae7c50185d Reintroduce sprintf_format for ABI compatibility 2019-12-10 20:44:08 -08:00
9f2e7edaeb Fix handling of types convertible to std::string_view 2019-12-09 13:25:08 -08:00
fd52de0c6b Add FMT_CUDA_TEST CMake option to enable cuda-test 2019-12-09 07:30:34 -08:00
f675cb887e Remove redundant cast 2019-12-08 18:01:59 -08:00
73a16b827f Fix handling of int128_t in format-impl-test (#1461) 2019-12-08 17:07:20 -08:00
72879db40e Clean-up sign-conversion warnings in public headers 2019-12-08 16:07:55 -08:00
d3aa0c3a28 Clean-up sign-conversion warnings in test code 2019-12-08 16:07:43 -08:00
31de9a1b80 Revert "Clean-up sign-conversion warnings in test code"
This reverts commit 227bfe62dd.
2019-12-08 15:47:24 -08:00
227bfe62dd Clean-up sign-conversion warnings in test code 2019-12-08 15:21:38 -08:00
95dfdc6cc4 Update README.rst 2019-12-07 10:12:56 -08:00
5916ff63c4 Update README.rst 2019-12-07 10:12:15 -08:00
1ab80aa92c Fix handling of types with custom formatters that are convertible to std::string_view 2019-12-06 11:40:21 -08:00
4f4d876616 Remove '%' from the docs 2019-12-06 07:06:19 -08:00
f443bd3baf Ditch decimal_formatter (#1363) 2019-12-05 19:07:45 -08:00
1219b65f21 Relax fallthrough attribute detection 2019-12-05 10:40:15 -08:00
071794ec65 Update version 2019-12-04 12:21:48 -08:00
d22e4ad85b Remove trailing comma 2019-12-04 12:20:52 -08:00
983806b0c1 Update changelog 2019-12-04 12:03:44 -08:00
02af5beb8a Bump version and update changelog 2019-12-04 10:22:07 -08:00
123e7f7fc3 Revert #1433 because of build failures (#1450) 2019-12-03 09:24:15 -08:00
168460f02c Remove TYPES 2019-12-03 06:45:00 -08:00
a64f60c849 Remove unneeded FMT_API. 2019-12-03 05:55:04 -08:00
1a599117d8 Export assert_fail with FMT_API. This fixes dll build. 2019-12-03 05:55:04 -08:00
b160123e39 Update ChangeLog.rst 2019-12-02 16:18:06 -08:00
5981588565 Fix compilation with MinGW
Commit 3bc28fcc6b ("Squelch MSVC warning exporting subclasses of
runtime_error", 2019-11-29) silenced a MSVC warning under. The MinGW
compiler also defines _WIN32, but does not support the "warning" pragma.

Introduce a helper macro to squelch the MSVC warning only when using the
Microsoft compiler.

Signed-off-by: Beat Bolli <dev@drbeat.li>
2019-12-02 12:56:46 -08:00
8bbe76af3a Add a missing decimal point in exponent notation with trailing zeros 2019-12-02 11:36:33 -08:00
4ca6821e8f Update version 2019-12-01 16:58:40 -08:00
7111a1eb9f Bump version 2019-12-01 16:50:07 -08:00
ae00bbdc91 Update changelog 2019-12-01 16:39:58 -08:00
e71e07d9fb Update changlog 2019-12-01 16:26:07 -08:00
0184df7020 Update docs 2019-12-01 14:49:56 -08:00
1cbae6e9ba Put vprint declarations in one place 2019-12-01 14:43:51 -08:00
159f89e2b8 Fixing installation directory of '*.dll' files on Windows 2019-12-01 14:36:21 -08:00
4b120b68ae Clean up includes 2019-12-01 10:19:07 -08:00
186b225d9d Update changlog 2019-12-01 10:16:01 -08:00
4cbf4888ea Update changelog 2019-12-01 10:04:38 -08:00
e31f2b3d03 Update changelog 2019-12-01 09:27:28 -08:00
62da1db62a Avoid wchar_t instantiations 2019-12-01 07:34:09 -08:00
3bc28fcc6b Squelch MSVC warning exporting subclasses of runtime_error
When compiling {fmt} as a DLL, MSVC complains that we are exporting
classes that inherit from "std::runtime_error", which we are not
exporting.

In this case, it's not really a problem because that symbol is already
exported via the C++ stdlib. So we just add a pragma to silence the
warning.
2019-11-30 12:00:25 -08:00
3c05fa46c6 Update changelog 2019-11-30 09:18:16 -08:00
ba6e330fd3 digits -> num_bits 2019-11-30 08:41:07 -08:00
6037b3cae9 Fix dangling else problem in FMT_ASSERT 2019-11-30 07:52:33 -08:00
fafb03fa6d Fix handling of fallback_uintptr 2019-11-30 07:31:38 -08:00
2f9acd1838 Remove dependency on <cassert> 2019-11-29 09:37:18 -08:00
aaf829bfb1 Fix fallback pointer formatting on big endian, take 2 2019-11-29 07:07:08 -08:00
b994a0ab13 Fix handling of missing fraction in snprintf_float 2019-11-29 06:17:29 -08:00
bb205d940d Fix fallback pointer formatting on big endian 2019-11-29 05:15:59 -08:00
ef7369ce90 Update docs 2019-11-28 08:09:46 -08:00
40e4c227db Update changelog 2019-11-28 07:43:22 -08:00
ea54b21e78 Remove invalid noexcept annotation
buffered_file& operator=(buffered_file&& other) calls close which can
throw.
2019-11-28 06:43:08 -08:00
9cbf4b087c Fix -Wconversion warnings 2019-11-28 06:43:08 -08:00
1200a34e10 Update changelog 2019-11-27 16:15:42 -08:00
9c7e2a6c6f Add missing newline 2019-11-27 11:06:40 -08:00
34e921f6fe Update docs 2019-11-27 09:26:32 -08:00
c3be0f593d Refactor floating-point formatting 2019-11-27 08:08:22 -08:00
c68703c9f4 float_spec -> float_specs 2019-11-26 15:53:24 -08:00
9a21728b0a Remove gen_digits_params 2019-11-26 11:27:53 -08:00
3de36e9348 Enable -Wswitch-enum in CI 2019-11-26 10:17:48 -08:00
4afb39bc24 Update README.rst 2019-11-26 08:33:16 -08:00
7ffa62db18 Fix precision handling in snprintf_float 2019-11-25 20:00:10 -08:00
0d07db1234 Fix handling of streamable and convertible to string types 2019-11-25 16:46:33 -08:00
d19ed6716d Fix hexfloat buffer reallocation 2019-11-25 15:54:04 -08:00
99b6e928d4 Fix handling of types with deleted rvalue conversion to string (#1421) 2019-11-25 08:30:47 -08:00
57cd3f72e9 Update comment 2019-11-24 15:34:33 -08:00
111fc127fe Remove fp::operator- 2019-11-24 13:28:15 -08:00
6003ec3f25 Simplify Grisu implementation 2019-11-24 13:24:28 -08:00
8877a67724 Instantiate snprintf_float 2019-11-24 08:57:39 -08:00
75fff1db64 Minor cleanup 2019-11-24 08:43:56 -08:00
28d7191c27 Don't print trailing zero with fixed, precision=0, and showpoint (#1417) 2019-11-24 08:23:10 -08:00
43271ba8e8 Handle null terminator at the end of the buffer 2019-11-24 07:15:25 -08:00
63a9f3fcd4 fix bad oss fuzz link in the oss-fuzz badge 2019-11-23 12:37:59 -08:00
4cf59ce734 Integrate Grisu and sprintf digit generators 2019-11-23 06:56:29 -08:00
7395472dde Refactor floating-point formatting 2019-11-22 18:49:19 -08:00
9108b25da9 Merge branch 'float' 2019-11-22 08:54:28 -08:00
4d366c68b7 Merge branch 'master' of github.com:fmtlib/fmt 2019-11-22 08:53:58 -08:00
ded1e7679e Refactor floating point formatting 2019-11-22 08:22:22 -08:00
c7edd8e570 Cleanup FP formatting 2019-11-20 13:17:03 -08:00
75108a56f6 Don't print % for nan and inf 2019-11-20 12:26:48 -08:00
3e1f70fe02 Merge write_fp into write 2019-11-20 12:20:17 -08:00
125fc5e520 Update comment 2019-11-20 11:45:25 -08:00
6793ffc1d6 Update README.rst 2019-11-20 09:33:59 -08:00
f4fcc5fd28 Update README.rst 2019-11-20 09:31:11 -08:00
4de41aa655 Move basic_writer::write_fp to where it belongs 2019-11-20 08:22:34 -08:00
404a880bd4 Make parse_arg_id more readable 2019-11-20 08:12:23 -08:00
092d2dc7b2 Merge safe-duration-cast.h into chrono.h 2019-11-20 08:05:18 -08:00
093e554211 Remove redundant qualification 2019-11-20 07:44:34 -08:00
d0696b0aa6 warning C4456: declaration of 'num_digits' hides previous local declaration 2019-11-20 06:43:46 -08:00
66d7746bb3 Use grisu for exponent notation 2019-11-19 16:55:11 -08:00
e9bff78814 Don't parse % unless FMT_DEPRECATED_PERCENT is set 2019-11-19 11:54:18 -08:00
57b6f2966d Deprecate the fmt macro 2019-11-19 11:28:17 -08:00
d79493e5ee Remove Grisu2 2019-11-19 09:50:59 -08:00
78842ce0d6 test: add default constructor for a const value
This fixed a compilation error of the OS X 10.11.6 C++ compiler:

    ./fmt/test/format-test.cc:1861:16: error: default initialization of an object of const type 'const Answer' without a user-provided default constructor
      const Answer const_answer;
                   ^
                               {}
2019-11-19 08:32:35 -08:00
5420bcce2d Make % an opt-in to improve compatibility with std::format 2019-11-18 08:04:43 -08:00
56a2e2075c Refactor float spec parsing 2019-11-18 07:37:36 -08:00
ed117baa4f Replace bool with float_format and add exponential 2019-11-17 15:52:13 -08:00
f26446290b Move float_spec_handler to internal namespace and update asserts 2019-11-17 13:47:00 -08:00
7e1cb3237a Fix indentation 2019-11-17 13:17:43 -08:00
f67783d7e6 Clarify that numeric alignment is deprecated 2019-11-17 10:24:55 -08:00
1c6d85f7bb Apply coding conventions to examples 2019-11-17 10:15:16 -08:00
4a1da44f91 Apply coding conventions to examples 2019-11-17 10:14:06 -08:00
080b6899d2 Tweak the docs 2019-11-17 10:10:32 -08:00
c01ec54fde Document and clean basic_format_parse_context 2019-11-17 09:28:26 -08:00
b0c2ab93fa Bump version 2019-11-17 08:35:26 -08:00
9b7fe2a4a1 Don't use POSIX API on UWP 2019-11-17 08:29:08 -08:00
c58b7d9c2f Use overridden locale in ostream 2019-11-17 06:22:22 -08:00
ceff9b0b2e Tweak the docs 2019-11-16 07:14:57 -08:00
3dc8639f8a [docs] Added conda 2019-11-16 06:19:33 -08:00
dcde089b4e Improve POSIX API detection 2019-11-15 07:28:02 -08:00
2145a7bdcc Move has_formatter into the public fmt namespace. (#1407)
* Move has_formatter into the public fmt namespace.

This will allow users to do SFINAE-friendly checks for
the formattability of a type.

Fixes #1369
2019-11-14 07:08:24 -08:00
52ae134f84 Remove broken CI config 2019-11-14 07:06:38 -08:00
0d6dd0cc6a Correct basic_string_view from string ctor 2019-11-14 05:57:23 -08:00
1f918159ed [clang-tidy] Replace deprecated C headers
Found with modernize-deprecated-headers

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
6868f888b2 [clang-tidy] Add missing override
Found with hicpp-use-override

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
87cd545a1e [clang-tidy] Replace {} with = default
Found with hicpp-use-equals-default

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
12f9437e22 [clang-tidy] Use auto
Found with hicpp-use-auto

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
bb0c8bfea8 [clang-tidy] Add noexcept where move is used
Found with performance-noexcept-move-constructor

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
e6e8298904 [clang-tidy] Add parentheses to macro arguments
Found with bugprone-macro-parentheses

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
0f0848e4f4 [clang-tidy] Use braced init list
Found with modernize-return-braced-init-list

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
a1fb5c7337 [clang-tidy] Changes suffixes to uppercase
Found with hicpp-uppercase-literal-suffix

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
8a411c2bca [clang-tidy] Turn deleted function to public
Found with modernize-use-equals-delete

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-08 09:35:26 +00:00
0047dc10a2 Mark apidoc as rst 2019-11-06 15:16:02 +00:00
263cdef8a0 Merge branch 'master' of github.com:fmtlib/fmt 2019-11-06 13:19:56 +00:00
d4ca54253a Update docs 2019-11-06 12:48:21 +00:00
5bb7b28e15 Document members 2019-11-05 10:43:18 +00:00
1409dfe76b Try fix CI 2019-11-05 10:39:14 +00:00
f1559e1d56 Use grouping() from locale for specifier 'n' 2019-11-05 07:22:12 +00:00
ffd05e65ed basic_parse_context -> basic_format_parse_context per standard and document 2019-11-05 07:13:58 +00:00
0889856d61 Fix UTF-8 truncation 2019-11-03 11:53:15 +00:00
d6eede9e08 Remove redundant ctor 2019-11-01 12:09:04 -07:00
213e09644f Workaround X11 madness (#1388) 2019-11-01 08:47:11 -07:00
6bfc9af8c9 Add double support to compile 2019-10-30 20:45:29 -07:00
3487f1b9cd Always inline grisu_gen_digits and disable grisu2 by default 2019-10-30 16:52:00 -07:00
791294d17b Apply get_cached_power optimization by jk-jeon 2019-10-30 08:07:01 -07:00
8e700619b7 Simplify format_handler 2019-10-30 07:02:38 -07:00
58c6f8c7f5 Make unsigned-integer-overflow sanitizer happy (#1377) 2019-10-28 14:41:09 -07:00
40414b3446 Don't emit trailing zeros in exponential notation (#1376) 2019-10-28 12:31:00 -07:00
b7a157401e Simplify grisu_writer 2019-10-23 13:52:09 -07:00
7aa58c30bf Simplify NVCC checks 2019-10-23 11:32:35 -07:00
8e9bffa986 clang-format 2019-10-23 11:20:21 -07:00
ce4d87acd4 Remove obsolete comment and clang-format 2019-10-23 11:15:43 -07:00
21acc2af43 Fix more Visual Studio 2019 pedantic warnings (#1371)
* format-inl.h(444,1): warning C4804: '>>': unsafe use of type 'bool' in operation
format.h(2808,1): warning C4127: conditional expression is constant

* More fixes for VS2019 pedantic warnings

* Fix "conditional expression is constant" VS2019 warning in more specific way

* Use const_check to silence constexpr warning
2019-10-22 17:13:03 -07:00
00669427df Patch compiler error when building using nvcc
If you compile using `nvcc` and pass the option `--expt-relaxed-constexpr` it will crash with an internal compiler error. This modification prevents using `constexpr` in `fmtlib` when compiling using `nvcc` and prevents the crash.
2019-10-22 08:34:52 -07:00
d39ebf3ff2 Optimize counting 2019-10-21 06:57:42 -07:00
6498bc6d31 Simplify grisu_writer 2019-10-20 19:29:24 -07:00
a967dcbe20 Improve handling of signs 2019-10-20 19:05:38 -07:00
8498bc97dd Initialize all the things 2019-10-20 17:53:18 -07:00
e2ea940673 Handle assymetric boundaries 2019-10-20 07:55:05 -07:00
2bc5585ff0 Fix computing lower boundaries for smallest normalized double 2019-10-18 17:56:52 -07:00
bb728a572a packed_arg_bitsize -> packed_arg_bits and remove packed_arg_mask 2019-10-18 10:06:57 -07:00
36d1390e67 Implement round half to even 2019-10-18 07:21:12 -07:00
599e0aef45 Support single precision floats in grisu formatting
Fixes #1336
2019-10-18 07:08:41 -07:00
91f7619cc9 Fix Visual Studio 2019 pedantic warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) 2019-10-14 08:55:18 -07:00
c4dc6bef24 Apply clang-format 2019-10-13 18:31:09 -07:00
646966e973 Reduce bigint capacity 2019-10-13 14:06:38 -07:00
a5abe5d95c Handle negative exponent and nonnegative power 2019-10-13 13:16:09 -07:00
1cbc5fa6cb Handle negative exponent and rename value/pow10 to numerator/denominator 2019-10-13 12:50:48 -07:00
f7a5748fd3 Partially implement (FPP)^2 2019-10-13 09:28:35 -07:00
0e94b931a2 Fix a linkage error introduced by #1360 (#1362) 2019-10-13 08:23:47 -07:00
5e58eb97b1 Implement add_compare 2019-10-13 08:05:06 -07:00
3a15ea3ea5 Rename write_double to write_fp
It handles all floating point types, not just doubles.
2019-10-12 11:41:24 -07:00
b87ac4d840 Distinguish float from double 2019-10-12 11:41:24 -07:00
a927dda9bb Use words for packed constants 2019-10-12 11:41:24 -07:00
dd11d45847 Encode types using 5 bits
This is needed to support more than the current 16 types.
2019-10-12 11:41:24 -07:00
b55551f900 Implement more comparison operators 2019-10-12 09:22:24 -07:00
96f91428c6 Add defaulted copy and move operations to format_error and system_error (#1347)
* Avoid weak vtables by providing a private virtual member function

* Add warning Wweak-vtables to clang when FMT_PEDANTIC is on

* Add defaulted copy and move operations to format_error and system_error

Compiler generated copy operations are deprecated and move operations
are not generated altogether.

* Add warning Wdeprecated to clang when FMT_PEDANTIC is on
2019-10-11 10:44:20 -07:00
b732f28c00 Deduplicate color vformat and vprint
After #1351 they became essentially the same.
2019-10-11 10:42:11 -07:00
a82c1dc6d9 use memory_buffer to make color print behave atomic #1348 (#1351) 2019-10-10 08:28:56 -07:00
2730e90186 Fix compile error in printf with gcc9 (#1354) 2019-10-09 18:58:40 -07:00
e4d6d9d7c8 Implement divmod 2019-10-09 13:40:50 -07:00
a1079e9fd6 Fix undefined in format-test (#1349)
When `MoveCtor` performs `check_move_buffer`, the buffer allocator becomes null,
but then `MoveCtor` attempts to use it to allocate a dynamic buffer. This
succeeds nevertheless because a typical `std::allocator<char>::allocate` does
not use `this`, so it does not crash when `this` is null.

Fixes #1344
2019-10-08 15:42:51 -07:00
b66bb6b71f Fix undefined in core-test and printf-test (#1345)
* Fix undefined in core-test

Fixes "reference binding to null pointer" in BufferTest.Ctor

buffer.operator[] attempts to return a reference to `buffer.ptr_[0]` when `ptr_`
in `mock_buffer<int> buffer` is null.

* Fix undefined in printf-test

Fixes "signed integer overflow" in PrintfTest.Length

This occurs in `TestLength<long long>("ll")`, since its minimum value minus one
does not fit in long long.

* Fix undefined in printf %0$

Printf counts arguments from 1.

Fixes "shift exponent -4 is negative" in PrintfTest.InvalidArgIndex.

`do_get` is called with index -1 when `basic_printf_context.arg` is called with
id 4294967295 when basic_printf_context::get_arg subtracts 1 from arg_index 0 in
the format string "%0$d".
2019-10-08 06:28:39 -07:00
b60114533f Implement more bigint operations 2019-10-06 12:49:23 -07:00
c41cea8b18 Initial implementation of square 2019-10-05 16:37:52 -07:00
0c7650373c Fix handling of types convertible to std::string_view 2019-10-05 06:58:37 -07:00
0571013709 Repoint one more Python 2 link to Python 3
One more python reference, this one acknowledging the `str.format` function.
2019-10-01 11:44:36 -07:00
d2c9276fcd let README point to python 3 instead of 2 2019-09-29 08:30:47 -07:00
0fc7bd1573 Fix ambiguity for types with dodgy conversions 2019-09-28 11:35:20 -07:00
b4f1988c4b Provide overload for fmt::join that handles std::tuples
Address enhancement request #1322.

The overload is provided in `ranges` (original `fmt::join` exists
currently in `format.h` for historical reasons.

Tests for prvalue and lvalue tuple arguments as well as the empty
tuple are provided in `ranges-test.cc`.
2019-09-27 14:05:35 -07:00
4b8f8fac96 Update README.rst 2019-09-25 07:14:45 -07:00
3b2fc033d1 Making CUDA test work with CMAKE_MSVC_RUNTIME_LIBRARY
CMake 3.15 introduced a new way of handling MSVC CRT type definition for
the build: CMAKE_MSVC_RUNTIME_LIBRARY variable.
(https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html)

This is supposed to be the way to go with MSVC CRT selection in new
projects. Using this method however breaks the current CMake script for
CUDA test. The reason is the CUDA test uses "FindCUDA" CMake module to
detect and set up CUDA support in CMake, which is deprecated since CMake
version 3.10, and which does not support CMAKE_MSVC_RUNTIME_LIBRARY
selector correctly (i.e. it does not propagate the compiler option
related to the CRT).

I did not find a way to "patch" in the correct compiler options, so
(while knowing this feature is only available from CMake 3.15 on) I
decided to change also the way CUDA is handled and instead of using
FindCUDA, used enable_language. Apart from having some nice additional
side-effects, it also fixed the problem with CRT selection.

However, the propagation of the compiler options (and in particular the
options related to C++ standard selection) is still a bit flaky on
Windows+MSVC platform, so it had to be done manually.

The patch makes two things in parallel:

1) Introduces MSVC_BUILD_STATIC, which, together with CMake version >=
3.15, allows building static version of the 'fmt' lib (and all the
tests).

2) At the same time, for CMake >= 3.15 it switches handling of CUDA
support from (old) FindCUDA to (new) enable_language, to fix the
problems which the old method has with the new CRT selector for MSVC in
a new CMake.

Added a check for CUDA before enabling it.

Using VERSION_LESS instead of VERSION_GREATER_EQUAL

Since apparently VERSION_GREATER_EQUAL exists only from CMake 3.7, while
Android is using CMake 3.6.

Removed MSVC_RUNTIME_LIBRARY logic from the CMake file.

The static build can be set on the command line with CMake >= 3.15
by defining the policy and the CMAKE_MSVC_RUNTIME_LIBARY this way:

cmake -G <gen> <options>
    -DCMAKE_POLICY_DEFAULT_CMP0091=NEW
    -DMSVC_BUILD_STATIC=ON
    -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>"

When MSVC_BUILD_DEBUG is set the test 'posix-mock-test' is skipped as it
does not build with the static runtime.
2019-09-25 06:46:11 -07:00
ac59d9f3a4 workaround VS2019 Update 3 compiler bug. (#1328) 2019-09-24 11:29:29 -07:00
8f27ce4d8b add test for multiple compilation types 2019-09-24 06:25:21 -07:00
89b0c71fa9 fix name clash in header-only mode 2019-09-24 06:25:21 -07:00
f6a783ad2e fix get 2019-09-24 06:25:21 -07:00
ccc8f5db02 Disable integral operator<< (#1316) 2019-09-23 20:34:08 -07:00
20fdb88a1c Remove redundant and nonportable test (#1313) 2019-09-23 13:36:12 -07:00
f29901097f Don't use const char* overload of operator<< (#1309) 2019-09-23 12:35:08 -07:00
758446c80d Fix a warning (#1319) and simplify code 2019-09-19 16:00:40 -07:00
f7aedc5fc4 Fix shared build on Solaris 2019-09-19 14:12:03 -07:00
840a817ed2 add oss fuzz badge 2019-09-19 08:23:05 -07:00
79c923ba2c fmt.pc.in: Fix for cross compilation
These variables get set to /usr/lib and /usr/include , which is totally wrong in a cross compilation
environment.

Changed to standard pkgconfig values consistent with most other ones.
2019-09-16 17:18:21 -07:00
5dc577c064 Update ChangeLog.rst 2019-09-12 18:20:48 -07:00
c6d1a94a9f Fix fallback_format (#1306) 2019-09-09 17:28:53 -07:00
0656045d02 Fix format overload that takes text_style (#1305) 2019-09-08 18:41:02 -07:00
c85ae23c73 Add max_value 2019-09-08 09:21:30 -07:00
b3bf665764 Implement multiplication and part of assignment from pow of 10 2019-09-08 08:27:00 -07:00
0887887e23 Implement left shift 2019-09-07 18:10:36 -07:00
ac71d853be Refactor normalize and clean up 2019-09-07 17:28:59 -07:00
6649b8e0ca value -> bigit 2019-09-07 14:23:19 -07:00
56b5c192a0 Add a bigint stub and reenable grisu 2019-09-07 13:50:22 -07:00
b2f0b6e44e Tweak comment 2019-09-07 08:43:35 -07:00
3d9f3c163b Integrate new format string compilation 2019-09-07 07:01:51 -07:00
19547d5148 Update index.rst 2019-09-06 13:27:28 -07:00
972ffd3151 Update README.rst 2019-09-06 13:13:30 -07:00
2ed412fa38 Update README.rst 2019-09-06 13:03:14 -07:00
df4dcf2ece Fixed vs 2015 warning about unused variable when grisu is off 2019-09-06 11:29:56 -07:00
f7a4b4ab91 Make numeric alignment optional 2019-09-06 09:43:53 -07:00
611cf0b3c6 Format octal 0 as 0 2019-09-06 07:03:47 -07:00
58a8f2f539 Add ccache to the list of projects 2019-09-06 06:26:09 -07:00
1882b9687b Reduce the numer of ifdefs with an empty (u)int128_t fallback 2019-09-05 18:03:47 -07:00
6de0454b42 Add support for built-in __int128 when available 2019-09-04 07:05:08 -07:00
16e3c48bb0 Move definition of FMT_USE_INT128 to core.h 2019-09-04 07:05:08 -07:00
8ce5f680f2 Rename internal::is_integral and internal::is_arithmetic
To reserve space for the type traits sharing the same name as the ones
from standard library.
2019-09-04 07:05:08 -07:00
2fd8f9ec8a Initial implementation of optimal compile-time formatter generation 2019-09-02 19:50:30 -07:00
fe642d7648 Clarify use of the core API in header-only mode (#1296) 2019-09-02 17:14:30 -07:00
a128b5b2cb Simplify format string compilation 2019-09-02 06:48:19 -07:00
466128de00 Remove unused code and refactor 2019-09-01 13:08:53 -07:00
22e98a5b6a Make compile work with user-defined types 2019-09-01 11:49:27 -07:00
f18a3f36a7 Remove string_view_metadata
string_view_metadata was introduced to make compiled format relocatable.
However, format string compilation is an optimization and therefore
adding overhead and extra complexity for relocation is undesirable.
In most cases the string will be either static or outlive compilation
and formatting and if it doesn't, it's possible to make compiled
representation relocatale by other means.
2019-09-01 11:10:49 -07:00
7cad33563c Refactor format string compilation 2019-09-01 10:28:41 -07:00
e1ab6bc006 Simplify format string compilation 2019-09-01 08:31:32 -07:00
24a88545d9 Add -Werror to tests 2019-08-31 09:26:45 -07:00
422e7b9d70 Fix compile-time checks for user-defined types (#1292) 2019-08-31 08:35:38 -07:00
d1dd9d5327 Document floating-point n specifier (#1291) 2019-08-31 08:16:47 -07:00
9a56a608ee Fix warnings (#1288) 2019-08-31 08:16:47 -07:00
c76957565c FixedEnum -> StrongEnum and make it a regression test 2019-08-31 08:16:47 -07:00
200ee6f108 Fix minor clang-tidy warnings
using instead of typedef.

climits instead of limits.h

Added missing cast to size_t.
2019-08-31 07:02:21 -07:00
bcd9b9331a Map not int enum to correct underlying_type (#1286)
* Map not int enum to correct underlying_type

* Use non-zero constant in TestFixedEnum
2019-08-31 06:25:38 -07:00
345ba07f1d Add a CUDA test
test cuda: import fmt in CUDA source code

Current test is only for Windows(cl.exe).
Need to test more with the other host compilers...

* Activate the test when `find_package(CUDA)` worked
* The test runs with C++14

Detailed comments in 'test/cuda-test'

test cuda: add more comment / macro check

* checks both `__NVCC__` and `__CUDACC__`

More comments for CMake and CUDA source file.

test cuda: <fmt/core.h> checks NVCC and CUDA

The header file checks 2 things.

* __NVCC__: if the compiler is from NVIDIA
* __CUDACC__: if the source code is CUDA(.cu) file

Since we can't sure all users prefer latest, Version for
`find_pacakge(CUDA)` is downgraded to 9.0.
This is the minimum version for C++14 in CUDA
2019-08-30 17:45:50 -07:00
hhb
9e2490be4c Rename precision parameter
To avoid clang warning:

fmtlib/include/fmt/chrono.h:753:32: error: declaration shadows a field of 'formatter<duration<type-parameter-0-0, type-parameter-0-1>, type-parameter-0-2, void>' [-Werror,-Wshadow]
2019-08-28 07:29:04 -07:00
3f75e2b69e Make buffer_range public and update custom formatting docs (#1281) 2019-08-28 06:50:20 -07:00
744302add0 Workaround broken [[deprecated]] in Intel compiler (#1273) 2019-08-28 05:58:09 -07:00
f5556225a4 Eliminate shadow variable warning
gcc-9 gives the following shadow warning:
```
In file included from /Users/libraries/ioss/src/fmt/ostream.h:12,
                 from /Users/libraries/ioss/src/Ioss_DatabaseIO.C:59:
/Users/libraries/ioss/src/fmt/format.h: In function 'void fmt::v6::internal::parse_format_string(fmt::v6::basic_string_view<Char>, Handler&&)':
/Users/libraries/ioss/src/fmt/format.h:2442:10: warning: declaration of 'struct fmt::v6::internal::parse_format_string(fmt::v6::basic_string_view<Char>, Handler&&)::writer' shadows a global declaration [-Wshadow]
 2442 |   struct writer {
      |          ^~~~~~
/Users/libraries/ioss/src/fmt/format.h:1703:7: note: shadowed declaration is here
 1703 | using writer = basic_writer<buffer_range<char>>;
      |       ^~~~~~
```

Since the `writer` struct is only used internally in the `parse_format_string` function, its name can be changed somewhat aribtrarily to avoid conflicts with names in an outer scope.

Note that this warning is also present in the 6.0.0 release.
2019-08-27 14:29:39 -07:00
ad3c7855e2 Fix typos. 2019-08-27 06:26:17 -07:00
7512a55aa3 Update version 2019-08-26 06:23:37 -07:00
9bd2f1f9af Temporarily disable Grisu 2019-08-26 06:11:44 -07:00
b9815cf048 Simplify part_counter 2019-08-25 08:30:59 -07:00
fe00cddde2 Move part counter to the namespace scope
to reduce the number of instantiations
2019-08-25 08:22:43 -07:00
1a7d172dc7 which_value -> kind 2019-08-25 08:08:46 -07:00
006c2546f2 Get rid of basic_prepared_format 2019-08-25 07:57:56 -07:00
4ce006fb6e Simplify format string compilation 2019-08-25 07:48:09 -07:00
e2e557e273 Remove preparator 2019-08-25 06:47:15 -07:00
a5f470eb10 Test and fix compiled format_to_n and formatted_size 2019-08-25 06:38:41 -07:00
4070c1d80b PrepareTest -> CompileTest 2019-08-25 06:22:13 -07:00
f8b59251c4 Remove unused preparator 2019-08-24 12:48:24 -07:00
643aa4c8c4 Simplify format string compilation 2019-08-24 09:39:40 -07:00
ffe29a92f4 Get rid of internal::compile 2019-08-24 09:04:03 -07:00
e94d723667 Fix compiled format string version of format_to_n 2019-08-24 09:00:30 -07:00
a9337395a2 Remove unused variable 2019-08-24 08:46:15 -07:00
562a9f4991 Remove parts_container_concept_check 2019-08-24 08:41:43 -07:00
b257c56e51 Fix size types 2019-08-24 08:36:14 -07:00
1488df3395 Bump version 2019-08-24 07:31:25 -07:00
b918e3ff81 Fix docopt usage 2019-08-24 07:24:42 -07:00
23b04ca6d5 Update usage instructions 2019-08-24 07:16:45 -07:00
5d5918a74d Update usage instructions 2019-08-24 07:04:24 -07:00
413d97b33a Fix formatting in changelog 2019-08-24 06:46:43 -07:00
790fd90f40 Update changelog 2019-08-24 06:34:19 -07:00
c0890be77d Update changelog 2019-08-24 06:32:47 -07:00
5a4b24613b Update the default floating-point format docs (#1270) 2019-08-22 15:21:14 -07:00
45dc3486fe Update license 2019-08-22 08:37:36 -07:00
5a353fa8cf Draft license 2019-08-21 14:31:22 -07:00
c84d227da9 Update changelog 2019-08-21 13:06:21 -07:00
b2d4ca1546 Workaround an issue with std::filesystem::path being an infinitely deep range (#1268) 2019-08-21 11:22:59 -07:00
2aae6b120c Fix doc for importing header only target with CMake 2019-08-14 13:59:15 -07:00
9f09b8eed1 Fix a warning 2019-08-11 11:38:16 -07:00
2bb8120d98 Fix a warning 2019-08-11 09:27:59 -07:00
c1e97392be Fix warnings 2019-08-11 08:44:12 -07:00
4e99e09bb3 Fix warnings 2019-08-10 16:56:57 -07:00
1607a01870 Suppress a warning 2019-08-10 14:15:55 -07:00
e8219952c6 Restrict fmt::compile to literal strings
to make sure we don't break the API too much when making all of this
compile-time only.
2019-08-10 13:18:11 -07:00
544b537334 Update changelog 2019-08-10 10:01:23 -07:00
83c13a1fe3 Update changelog 2019-08-10 09:56:13 -07:00
2546dafece Update changelog 2019-08-10 09:25:16 -07:00
02c04b1736 Update changelog 2019-08-10 07:59:33 -07:00
5360ab0b59 Fix iteration over named arguments (#1168) 2019-08-09 11:53:07 -07:00
b615eca964 Update changelog 2019-08-05 05:37:44 -07:00
22a42c0b01 Cleanup compile implementation 2019-08-04 11:15:43 -07:00
c63624ed45 Update changelog 2019-08-04 10:38:33 -07:00
211d312406 Don't terminate on I/O errors in report_error 2019-08-04 09:38:47 -07:00
ef55e74e08 Update changelog 2019-08-04 09:20:49 -07:00
612669d343 Update changelog 2019-08-04 07:28:48 -07:00
ba63ac8c18 Make format_to a non-member 2019-08-04 06:47:49 -07:00
3fe49163bd Revert "Make format_to a non-member"
This reverts commit a5bd3ddb28.
2019-08-03 16:12:34 -07:00
a5bd3ddb28 Make format_to a non-member 2019-08-03 08:36:53 -07:00
3df0ea34e5 Remove unnecessary overloads 2019-08-03 08:26:51 -07:00
436acf3489 Make formatted_size & format_to_n non-members 2019-08-03 07:54:49 -07:00
823128049b Make format a non-member 2019-08-03 06:31:24 -07:00
1dfa2591b3 Make operator _a constexpr 2019-08-01 16:56:49 -07:00
6f2dd30e38 Simplify udl_formatter return type 2019-08-01 16:56:49 -07:00
431d0f85cf Use basic_string_view in non-template UDL 2019-08-01 16:56:49 -07:00
ad71f5a706 Use forwarding references in UDL template 2019-08-01 16:56:49 -07:00
d0f2f3b816 Update usage.rst 2019-07-27 20:25:40 +03:00
eac2796ce3 Fix locale detection 2019-07-26 12:13:05 +03:00
ee36257469 Internalize format_part 2019-07-26 09:02:45 +03:00
bbf0bada33 Simplify compile 2019-07-26 07:58:19 +03:00
3730b4f039 Cleanup compile implementation 2019-07-25 21:26:22 +03:00
25ff2efc0a Update changelog 2019-07-25 19:59:59 +03:00
9393fe26f6 prepare -> compile 2019-07-25 19:39:41 +03:00
b48ffc14a4 Update changelog 2019-07-25 18:44:40 +03:00
3268531bc9 Workaround a broken C locale on Windows 2019-07-25 12:55:23 +03:00
8bd59ec936 Use fputws for outputting wide strings
Also adds fwide byte/wide orientation checking to verify streams are
able to receive the character type in question.

On Windows, the fwide calls are no-ops that pass through the second
arg and optimize out the if statement entirely.
2019-07-25 10:29:32 +03:00
1235f0a24a Fix typo in usage.rst 2019-07-24 15:54:02 +02:00
4fb73d1145 Update README.rst 2019-07-21 15:28:48 +02:00
f9ceefb0fe Fix a warning and is_negative usage 2019-07-19 14:18:10 +02:00
6bcc3fd216 Fix warnings 2019-07-19 13:27:41 +02:00
6a497e1d06 Fix warnings 2019-07-19 06:18:46 +02:00
e9b9b0aefa clang-format 2019-07-18 06:28:53 +02:00
ec24342b2b Fix more warnings 2019-07-18 06:28:17 +02:00
230b24944c Fix sign conversion warnings 2019-07-17 21:18:55 +02:00
cadd92d69f Fix #1232. 2019-07-17 11:52:10 +02:00
41076d1de3 Use FMT_THROW in fmt/color.h.
This allows fmt to be compiled with `-fno-exceptions`.
2019-07-17 10:15:31 +02:00
d561cb47a7 Opt-in macro to enforce use of compile-time format strings 2019-07-16 07:08:59 +02:00
699fe8e711 Remove const qualification in compile-time checks 2019-07-15 09:20:16 +02:00
da2d33f1f1 Update changelog 2019-07-12 16:21:13 -07:00
af4734fd15 Fix warnings 2019-07-12 16:03:12 -07:00
a3a74672a0 Update signatures 2019-07-09 17:05:34 -07:00
c11e68305f Update signatures 2019-07-09 17:01:13 -07:00
dd8cc8b0ba Disallow passing views as lvalues 2019-07-09 12:18:48 -07:00
f6f0415b83 typedef -> using 2019-07-07 17:14:26 -07:00
c92dc37464 typedef -> using 2019-07-07 15:40:34 -07:00
e3f20d3e13 Remove gcc 4.4 workaround and use proper alias templates (#940) 2019-07-07 14:35:56 -07:00
b438812324 Clean up is_output_iterator 2019-07-07 12:59:55 -07:00
bc15e3700e typedef -> using 2019-07-07 10:44:06 -07:00
cf5ebf2059 Cleanup 2019-07-07 10:09:22 -07:00
9c20e72de3 Cleanup 2019-07-07 07:58:30 -07:00
79209598f5 core_format_specs -> sprintf_specs 2019-07-07 06:54:25 -07:00
5488d0b53a spec -> specs 2019-07-07 06:39:20 -07:00
e4f84ee1c6 Refactor format_specs for #1109 and #940
Refactor `format_specs` and related APIs to support variable-width fill
(#1109), improve naming consistency, remove legacy setters (#940), and
optimize layout.
2019-07-06 20:57:40 -07:00
8e0dcd20b3 Remove old deprecated functions 2019-07-06 07:55:52 -07:00
1d3e3d8c04 Make the 'n' format specifier work with grisu disabled 2019-07-04 15:15:14 -07:00
bc628f8d49 Fix EXPECT_DEBUG_DEATH_IF_SUPPORTED (#1214) 2019-07-04 07:55:36 -07:00
edd13fcc1c Fix small number rounding with fixed precision in grisu 2019-07-04 07:11:40 -07:00
6a031347e5 Remove unnecessary qualification 2019-07-03 21:14:45 -07:00
bc14c6ee20 Use the decimal point from locale 2019-07-03 17:55:00 -07:00
476f25cd81 Remove ancient gcc workaround 2019-07-03 16:37:02 -07:00
c9d5a08ed8 Add the 'n' float format specifier 2019-07-03 16:36:23 -07:00
f487ddbdfa thousands_sep -> add_thousands_sep 2019-07-03 16:18:12 -07:00
d8fd1699b1 Make data names follow naming conventions 2019-07-03 16:14:14 -07:00
c286ffc88d int_traits -> uint32_or_64_t 2019-07-03 16:01:21 -07:00
1289782f06 Get rid of add_thousands_sep 2019-07-03 15:50:05 -07:00
2249f5571e Simplify thousands separator handling and cleanup 2019-07-03 15:30:45 -07:00
e76446958c Cleanup and remove deprecated visit 2019-07-03 14:31:01 -07:00
de37de912b Remove deprecated color API 2019-07-03 14:19:24 -07:00
df1a3a141b Remove null_terminating_iterator 2019-07-03 14:00:55 -07:00
78dec87a46 typedef -> using 2019-07-03 11:05:20 -07:00
ded0a3bb3d Internalize undocumented basic_writer 2019-07-03 10:01:03 -07:00
83174f2a1f Refactor ranges 2019-07-03 07:23:08 -07:00
c2e84ee9cc Fix FormatTest.StrError on Solaris 2019-07-03 06:09:24 -07:00
2711cb1672 Apply clang format and other minor formatting tweaks 2019-06-30 08:52:15 -07:00
ab0ba8a9d0 Don't emit decimal point if there are no trailing digits (#1210) 2019-06-30 08:44:59 -07:00
bd3fd3bfda clang-format 2019-06-30 06:58:49 -07:00
260c115908 Fix formatting of 0.0 with (#1210) 2019-06-30 06:54:41 -07:00
9d97201ede add oss-fuzz support
see https://github.com/google/oss-fuzz/pull/2381

the history of the fuzz branch is long and messy and
is difficult to rebase on top of the current master.

Squashed commit of the following:

commit b9d6db50010e185d0af2590a35472e9334102248
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 29 21:50:34 2019 +0200

    update exception with a more accurate description

commit f3fbaf60cc80c7f57fa95962dc0069b10c3d3e61
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 29 21:34:55 2019 +0200

    fix missing flags in reproduce build

commit 40a17bec7a1ad724203577842a254ca9c42da388
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 29 21:22:48 2019 +0200

    move check for large precision values closer to where needed

commit ef6e23e1f52d639c5aec1a1e713157cec380a8c3
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 28 20:55:34 2019 +0200

    simplify the fuzzer build script

commit eadee6e0557be6df695e80f0f2717046a29846e0
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 28 20:47:54 2019 +0200

    minimize source code pollution

commit 1ece6416438f199c164ee9aa89f42ad1f21a4985
Merge: f404079b 037b84f2
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 28 20:22:52 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	CMakeLists.txt

commit f404079b4e00e51b0d5a4c9218cbe7afb350b777
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 28 20:20:52 2019 +0200

    make named_arg write into a string or a memory_buffer

    this makes the fuzzer consistent with the others.

commit 545dbe136817eef9e734c32991a324874a51bb4a
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu Jun 20 06:34:17 2019 +0200

    tidy up extra newlines, missing std:: etc.

commit 2d816ef2b13fc2a46c0df76a91f7912bd7196087
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:49:08 2019 +0200

    update unit test to handle expected result following review comment

commit a5b9a26808d0165acd2edc4c3baabf9bff40d8bd
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:40:06 2019 +0200

    update build script to reflect changes after review

commit 8411cb78984f76c74bca273c0bb18918e084e711
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:39:39 2019 +0200

    review comment: clarify what the .gitignore is for

commit 18d9e7bb43d98568fe491e076106e4fa29070b33
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:36:56 2019 +0200

    review comment: don't touch root .gitignore

commit 7683d7faa116a6e261da824ec6c1a6a75689841b
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:35:40 2019 +0200

    review comment: condiionally include main.cpp

commit be0bdaeb27b0c1914cc0b0fd85c2b3bcc6fd2245
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:31:28 2019 +0200

    review comment: drop commented out code not working on travis

commit 013429812d7fb745eec146296623ea245c4848b4
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:30:26 2019 +0200

    review comment: renumber case labels

    the old ones were to be able to reuse the corpus, let's drop it

commit f66fe7bead4a71978f21d9e47a8f3f9e4935fccd
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:06:47 2019 +0200

    review comment: libfmt->fmt

commit 4a4ddb654dd5b90646cd7e6ff45318c17b66dc9f
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:05:32 2019 +0200

    reuse fmt_safe_duration_cast

commit 0a1679411a8bd77c2ff34e1cd572307c92e12040
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:02:48 2019 +0200

    review comment: name convention, better name

    C was for "chrono duration"

commit 63084cac00b798c636e0dc13207df46a5c4539f6
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 20:00:50 2019 +0200

    reuse earlier extract fmt_safe_... function

commit b23388d4d7f919163ead9a9e9bdd50d14daf80b7
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:58:55 2019 +0200

    review comment: don't output inf.inf

commit 6f861f1d89d2127bbe2446d176d59a354665cc15
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:57:00 2019 +0200

    review comment: extract function for invoking safe_duration_cast

commit df19bc87ccff77d4bedf54fa3d3992f78ef699bd
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:47:30 2019 +0200

    review comment: leftover garbage

commit 84eea802efb1164c4f2a83b2e480a7c5bdf4e921
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:45:22 2019 +0200

    review comment: turn cmake option into macro for SAFE_DURATION_CAST

    decided to have it on by default

commit c3a159498c2544a52662cd03d23d5a1d00537bba
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:40:14 2019 +0200

    review comment: extra newline

commit aa556875c5161d817c347ff984dad171c7a35df9
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 19:38:49 2019 +0200

    review comment: file name convention

commit 4102d82c455324bda4ccd64072eab86b3f0ecebf
Merge: 28add37d 4912cff6
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 17 16:29:29 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 28add37df3944cbaa00f614e8063210a6d83c17c
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 21:44:06 2019 +0200

    disable check to pass travis

commit 4119378aedfd3e4063058e8f1f03c29d9f44d5e8
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 21:32:39 2019 +0200

    add missing include

commit ba2efb82f20d6ecb5e49a8c6ced96a7febedc175
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 21:04:41 2019 +0200

    try working around build issue on travis

commit 380671a2cb6e52f2b7d5eaad409d491baba5b7e6
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 20:22:41 2019 +0200

    write positive infinity without sign

commit fd72b9adace17e00c46aae24e061bf14c3af6bb1
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 20:20:50 2019 +0200

    remove leftover from merge

commit 1ae3128be2c53914e4c840d12e1b02c59758c378
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 20:14:45 2019 +0200

    format to buffer instead of string

commit 1d83a561244c2fe81231d17e911c6eb24c87cac4
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 19:50:19 2019 +0200

    fix warnings

commit a33b45a7bb5cf70eb3ef1cd95908282621195f1f
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 19:43:46 2019 +0200

    refactor and fix warnings

commit 02afb12dd5b05804a1a8b55e1b9fb7e3de593e84
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 19:17:27 2019 +0200

    use fixed size input

commit 35f84c8cf20efb18a137efecd10dcdc6bcebf7b5
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 19:07:43 2019 +0200

    factor out main into a separate file

commit a23b7a198ba739dd813897901855c98441e6f29b
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 18:56:40 2019 +0200

    refactor

commit 9a3f4cfb3bc32a304a1a49b8ff24fbc2f924266c
Merge: 7842582a 12f46838
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri Jun 14 18:20:03 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	include/fmt/chrono.h

commit 7842582a0089c24a5d44bbb2d156beb732bb7b58
Merge: 90cab5aa cbbee1b3
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu Jun 13 10:41:34 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 90cab5aa023271a3a746cf9c60dd613b4546ca10
Merge: 8feb8a3f e5422db4
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed Jun 12 18:49:08 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 8feb8a3fe20da043a8303e59b1580b4b2862cc57
Merge: e9fabac1 87fbc6f7
Author: Paul Dreik <github@pauldreik.se>
Date:   Tue Jun 11 19:18:35 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit e9fabac1dd6d710fec1b30ca51dc953f57f2f9f5
Merge: eaff9316 e1a67b52
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 10 22:38:36 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit eaff93166402ff9a16a9ab0fab1081104f4f06b8
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 22:29:01 2019 +0200

    drop old crashes

commit 7f861e481abb7367bd187c92fe202e25d36d0dd0
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:47:30 2019 +0200

    build fuzzers as part of the linux clang 6 build

commit 42c339066dce148723f452d4a94487a6ac80637f
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:42:12 2019 +0200

    travis has old libs

commit 9264e3ac82582a941eba3501301dee1468175c08
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:33:26 2019 +0200

    more travis workarounds

commit c6eed3adaf6cf65d440dd58c88a034f61c55114f
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:27:49 2019 +0200

    travis workaround

commit 5e230d6240841dbc67f0c08ace3a1c24defea54f
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:15:36 2019 +0200

    fix constexpr issues

commit cc5fc033479c769a8ac19115aef48020c532c943
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 21:11:13 2019 +0200

    add a fuzzer build

commit 3997375296eca0d0455e0935ef3aed8b010ecf2d
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:53:04 2019 +0200

    fix minor documentation errors

commit 1572411261abd5c0756ff2998ab707f1131d4fdf
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:49:25 2019 +0200

    polish the documentation

commit 9e5274437cfc3e9c82131c14cf7f3a0abdb10025
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:32:45 2019 +0200

    remove unused headers

commit 4b2492a5e037d3153de342ef7f2729b69e8f5dce
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:28:12 2019 +0200

    clang format

commit a0004ebb417bce5a24c15ea65a0f3741e45b8480
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:27:02 2019 +0200

    format also void*

commit 820142ee2076ae17fea25857c41a1ecdca4a8521
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:12:21 2019 +0200

    improve two_args with lessons learnt from the others

commit 7b8fd7f5123fccf78b600c69ca25d025582c095e
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:11:18 2019 +0200

    improve function names

commit 641bf36a7a061abf6a02d5e31f3adeb33b079f43
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:07:29 2019 +0200

    clang format

commit 7975c0c3cbe19a7159336ad8fcb170fa6259b1cb
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 20:06:02 2019 +0200

    apply lessons learned from chrono fuzzer on sprintf

commit 972124c9f921f8ef786f99c294f556bb7dd9b9ee
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:55:49 2019 +0200

    format to buffer instead of string

commit 7b015c692364d1e087a59dfe83dda1b8f8fd2991
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:50:25 2019 +0200

    apply lessons learned from the chrono fuzzer at one_arg

commit daa8ea95dd71704e367b760fa6605f5a7cac6890
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:41:17 2019 +0200

    renumber cases

commit a667365d0e0f3eb0bc6d6f2cfee5e128a6574aee
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:38:06 2019 +0200

    clang format

commit e0e361b8a3594c43e131d661a28381613a186c2b
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:36:35 2019 +0200

    disable fuzzing by default

commit ccb4274ab246ee1fe3becb2b73432179a8a5fe6f
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:36:25 2019 +0200

    refresh named_arg with lessons learnt from the chrono fuzzer

commit 60da706d4ef35c18eb967bf4ba8d395ef05a9c61
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:36:00 2019 +0200

    fix build error

commit e361bfc24246d7c7e91f5e45209eda2f22689d98
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 19:00:11 2019 +0200

    add comment about formatting to string vs. memory buffer

commit 74c0ed062d34eae1786ca699886ad4f3bccc7fd1
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 18:51:23 2019 +0200

    try to use better names

commit 4efea36f77020eecf3c7826f891417f94aedf6f4
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 18:46:07 2019 +0200

    fix clang build error

commit 03cdd2e4631ad302dde3e1048671d3bb08956096
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 18:44:21 2019 +0200

    drop workarounds fixed upstream

commit e936829ebbd97ed2e6f8c5f595b414c0982f2e4d
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 18:41:02 2019 +0200

    move the fuzzers into the test/ subdirectory

commit 2967765698259764c1f06966a7cdefbc5365e5f2
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 18:30:03 2019 +0200

    revert temporary tests handled upstream

commit 749c5027b0eab3d90d8fbfb6e55ee313a7f7dfe4
Merge: dee69088 5d9100fa
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:49:00 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit dee690881bd33bb77bee1d5ffce643e8bef84a33
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:40:37 2019 +0200

    keep documentation comment formatted properly

commit 87d2c99487eef586ce54d432697f384cbe7a50e1
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:36:12 2019 +0200

    switch to fmt constexpr macros

commit c23fa59139c425a3dfa2e5eeaeb3269c251c90d1
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:30:22 2019 +0200

    clang format

commit 9e58207e9b24a8cc90c721277405b409dd61740d
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:27:03 2019 +0200

    get rid of safe_duration_cast submodule

    replaced with an embedded miniature version

commit a4d36eac46e5db45ded96f80f84986f4f76ea0ec
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Jun 9 17:25:00 2019 +0200

    add safe_duration_cast into fmt

commit 7d5b0ecef37722c40952251c88d74a2552221d84
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 8 22:39:33 2019 +0200

    mark #1194 as fixed

commit ee91514ecf7a8788f2081996db85eef50d7cd57b
Merge: 60569117 4faadff0
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 8 22:25:37 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 6056911784bc86e6caf56a61fd64142f113d531e
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed Jun 5 09:58:30 2019 +0200

    format to small size buffer instead of string

commit 9f006097255c239188840b589f6e39cbb4476481
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed Jun 5 09:45:23 2019 +0200

    switch to fmt::string_view and workaround reported bug

commit 387de0d9440852fac974ff165b2555d54e2380da
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed Jun 5 06:26:15 2019 +0200

    ignore build directories

commit 55da271c5bb3c11a239c4e46570b6741803ce329
Merge: 3716491e c264e641
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed Jun 5 06:12:36 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 3716491ec51c34a918834857c67300eea180ba02
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 3 07:03:29 2019 +0200

    fix UB in on_second

commit 2740241b13b7417a4dae655f825ea5a551ffe7ba
Merge: 1c258402 d54e64b3
Author: Paul Dreik <github@pauldreik.se>
Date:   Mon Jun 3 06:37:18 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	include/fmt/chrono.h

commit 1c258402a4bd03f390e0256fa9475cc5187d37f9
Merge: ca9596d1 f57227a1
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Jun 1 08:01:58 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit ca9596d1c91b0315b407ce2c4b3e9e5ba1aeb640
Merge: 1c274cfd d07cc202
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 19:42:33 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 1c274cfd4112138bfc59dd16f58022016128fe85
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 08:12:10 2019 +0200

    make it easier for the chrono fuzzer to explore

    using a fixed size makes the cases cross pollinate
    each other better.

    the execution speed is much higher as well

commit f0d7cccdc70c98576b7129428c416e7c9e68a8aa
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 07:36:21 2019 +0200

    add a build adapted for analysis of fuzzing performance

commit 56f7cf3fa979de415174a10b18221727e3138b7b
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 06:25:10 2019 +0200

    allow negative values again

commit a77a5fc505bbeab1cfa36be16d40f7799689317a
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 05:45:55 2019 +0200

    fix UB on signed int overflow in chrono_formatter constructor

    see https://github.com/fmtlib/fmt/issues/1179

commit b6a592720be520b58ed2f2d8668ffc6c8b71f0f7
Merge: 492a2046 30bce6c1
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 30 05:26:30 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	include/fmt/chrono.h

commit 492a204623c3c4bbf04c9d47d69979d3a484959c
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 21:36:00 2019 +0200

    fix bad assert

commit 0ae68b03fbb0e80e292a01f529d5cd7e76349907
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 21:35:49 2019 +0200

    add unsigned types for chrono fuzzing

commit 2753d7db76645e8847ff2110c5e98f5c8de4a6b9
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 20:25:21 2019 +0200

    use C++17

commit bc12742f098ec8b513985daedc57faa518203eb0
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 19:44:59 2019 +0200

    add symlink for safe_duration_cast

commit 67201d2639b93736768e109d73b3e9ccc9401c48
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 19:40:40 2019 +0200

    turn on safe duration cast for the fuzzer builds

commit 31a70080a63a5213594e4b4e6a33e7e315cf756e
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 19:32:52 2019 +0200

    clang format

commit 981e30c5782d04453ece1b31e887da4f29268370
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 19:30:19 2019 +0200

    reduce maximum allocation size

commit 7ba51da81de7ecbc5498a22dc29de5b0648bcad2
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 19:30:01 2019 +0200

    make nan unit test pass

commit 95b4b9c28a589c30727826dd4e1367bebfad5894
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 18:39:08 2019 +0200

    special case nan and inf

commit 2673c965506e51d150c005340698a6e15d98aaba
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 16:40:11 2019 +0200

    build a fast fuzzer, for making coverage fast

commit db52b62612fd7ea3ceeaee05584fd8cb83e54a35
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 16:39:48 2019 +0200

    add safe duration cast as submodule

commit c8a028faec5d91728472f5de01ea8b1766fb929d
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 16:00:26 2019 +0200

    enable chrono fuzzing for non-negative values

commit de3555cc573e561691858ca16586f8b45a3ae703
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 13:06:35 2019 +0200

    try start using safe duration cast

commit 5c3245118c3debcb3f6f69c04c2c32d48449ee16
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 09:59:34 2019 +0200

    add failing test

commit 3a565d3b091c29210e24042f86869fecafb70914
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 09:59:09 2019 +0200

    fix cmake option type (should be string, not bool)

commit 61c67564207a13992b1c69d95614b2c4aec5df86
Merge: 63e7b9e3 bb254d14
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 29 07:03:42 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 63e7b9e32c714c594d019ef463c9c40a3510a2f2
Merge: 7dd1d80f 5e7bdf1b
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri May 17 19:17:20 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 7dd1d80f3a32465d0fa13ce733bff8686a5b0bad
Merge: 2c9aa5a3 2a9e8b52
Author: Paul Dreik <github@pauldreik.se>
Date:   Tue May 14 19:38:32 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 2c9aa5a31e64af25f8bb4afa8134258822532d3e
Merge: 16a442c8 2c77562b
Author: Paul Dreik <github@pauldreik.se>
Date:   Tue May 14 06:33:16 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 16a442c864dbdce70c22b4a859dba5e3b5edaf35
Merge: b1d70b61 f4dfd6e3
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 12 15:24:31 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	include/fmt/chrono.h

commit b1d70b6144c7a61e580eb44ec7d1bdd2368f5531
Author: Paul Dreik <github@pauldreik.se>
Date:   Fri May 10 08:52:57 2019 +0200

    prevent excessive time (found by oss-fuzz)

    the following triggered this:
    std::string message =
          fmt::format("\377{:.214718908}\377", fmt::arg("/\0", 0.f));

    there are probably more places with calls to fill_n which could be checked

commit 9a91093a6b20fd22afd6739f5dcba3b00f6f8eaf
Merge: 7de0fdec e9bab6d0
Author: Paul Dreik <github@pauldreik.se>
Date:   Thu May 9 06:06:32 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	include/fmt/chrono.h

commit 7de0fdec38270f2d0302413904a5ef1b13d47177
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 20:08:53 2019 +0200

    clang format

commit bb375e1ca10eb3cc2c6684bf698ad4738ab7eb10
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 19:47:10 2019 +0200

    seems to pass the unit test now (except for the nan stuff from victor)

commit 786b4b7351bc8e305ad7e68d11ca6b542f66d456
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 19:25:23 2019 +0200

    add assert triggering data, and unit test

commit 2790e480b81ec83d00315aa69407fe71b8c4c637
Merge: fa859a05 ca978b3d
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 18:42:51 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit fa859a05c2c3abef263166f3a44cdbaa3122d642
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 18:18:54 2019 +0200

    add crash

commit 1f6e341b1c4bc966a44c7a98b63f22bd65958d0b
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 18:18:27 2019 +0200

    assert floating point is finite internally

commit 50877748d08a0f4433af4f1213c5bc9021e76e7a
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 17:32:03 2019 +0200

    invoke undefined behaviour inside chrono

commit bac7ac4149f2d001f7b36236e1710484674d029b
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 17:31:35 2019 +0200

    refactor the fuzzer build script

commit b19c4cd84a0c8b6d4a7beb281ad881156173ce78
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 16:25:11 2019 +0200

    add one more crash

commit 7607592e06ebaa189dc180441fa1863430e0938e
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 16:24:05 2019 +0200

    add crashing input

commit b059a98b27b40cd284e08a54493c25363d743557
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 16:21:25 2019 +0200

    trigger undefined behaviour with NaN durations

commit 7cce33250282b397c00159e6809125f5fc1c0190
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 16:20:51 2019 +0200

    add asan only fuzzer

commit 757319a4e30978d8661b3be8f75937266071b413
Merge: a574b21c c1d430e6
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun May 5 06:34:59 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	test/chrono-test.cc

commit a574b21c840339abef5e4ad33612b6efac6ad54b
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat May 4 12:54:13 2019 +0200

    disable chrono fuzzing for now

    it triggers integer overflow and is not trivial to solve.

commit ff17322bceba53e0c2d9ebcf3756115ad148195e
Merge: d6a59851 29c10fbf
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat May 4 07:29:39 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit d6a598511c7dc0c208c2d688b2943b0d7c092029
Merge: 663b1592 4a4d72f9
Author: Paul Dreik <github@pauldreik.se>
Date:   Wed May 1 20:44:16 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

    # Conflicts:
    #	test/chrono-test.cc

commit 663b159235f8ae5f58fe80bb02d49bfa392056b0
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 22:36:07 2019 +0200

    add crash case (triggers assertion)

commit 082a5cb226142ea30b415d4231cea9425748741a
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 21:44:19 2019 +0200

    add const

commit b8d70919ea6be0d2e4c58ef82887496f55125ba9
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 21:29:43 2019 +0200

    provoke assertion

    fmt/include/fmt/core.h:246:
    typename std::make_unsigned<_Tp>::type fmt::v5::internal::to_unsigned(Int)
    [with Int = long int;
     typename std::make_unsigned<_Tp>::type = long unsigned int]:
    Assertion `(value >= 0) && "negative value"' failed.

commit e1966013af4eb7febf047d4629cc6236a6aae0e3
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 20:46:16 2019 +0200

    add more crashes

commit 1394ae3fe915319ce7dc63d6a9dc820a29c9539e
Merge: 89338cad 4c721e3a
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 17:16:14 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 89338cad4eed9441644ec8c5f1687b511c829ea4
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 09:40:32 2019 +0200

    add notes on how to reproduce crashes

commit 7dc3e4c7223617da274c4cccb9cf5459d0510e0b
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 09:28:20 2019 +0200

    add crashes from chrono duration

commit b62e8bc783134c2d15ebf0372c8a61b41624e6b1
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 09:26:53 2019 +0200

    rename fuzzer

commit 7f4ab2b80d072fe3ad96e37e45f3fa807a85c99f
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 09:15:38 2019 +0200

    clang format

commit a6cc2a35a9799e88b9ed89e578b7aefd9b09ad09
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 09:12:04 2019 +0200

    add chrono duration fuzzer

commit 682713c9a61d52b46e95fdb7d970a8733f77ce88
Merge: 8b934b37 8d8ea21c
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 28 08:07:56 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 8b934b37161d1389de603ced6560982507bb7ae5
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 10:23:44 2019 +0200

    clang format

commit 793d97b9af33269f5628094f547f9771e968e3f2
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 10:23:17 2019 +0200

    tighten memory allocation

commit e2301f2430b15c9817433206597ef82c990f49a0
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 10:19:56 2019 +0200

    clean up and set license (BSD 2-clause simplified, same as fmt)

commit e64c3fb35719afa644dee1f9f17829cace6e17ff
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 10:04:23 2019 +0200

    clean up and add afl

commit ab46241206aaf46759fd3f292ee4a1088b652d15
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 09:54:48 2019 +0200

    drop c++17 requirement

commit 20c01e1acf330c8a28192f55b16efeebddb72ab0
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 09:25:19 2019 +0200

    initial oss-fuzz compatible version

commit 6cbd91a37cf36a1d0e994bb16cf44a12622f7dca
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 08:42:51 2019 +0200

    initial commit of fuzzers from https://github.com/pauldreik/fuzzfmt

commit eaddfb16d86ef1c259b737e2aab40145b0c956a6
Merge: e37d7db3 134904c8
Author: Paul Dreik <github@pauldreik.se>
Date:   Sat Apr 27 08:38:19 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit e37d7db3b938c82f569d71e6bb00bd1bf8394db7
Merge: 99b2e08b bd516e34
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 21 17:28:06 2019 +0200

    Merge remote-tracking branch 'upstream/master' into fuzz

commit 99b2e08b6bef25b793df5ef07621c9c4402587de
Author: Paul Dreik <github@pauldreik.se>
Date:   Sun Apr 21 10:30:56 2019 +0200

    stop high memory use when fuzzing
2019-06-30 06:10:07 -07:00
037b84f214 Fix warnings 2019-06-24 16:46:48 -07:00
e37ee419c6 Export exceptions destructors
Reenabling Compiling and Linking as DLL.
2019-06-24 08:53:35 -07:00
e3488fcae2 Fix Warning
QtCreator (4.9) Clang Code Model (Clang 7) gives the
warning:core.h:404:11: error: an attribute list cannot appear here
core.h:116:24: note: expanded from macro 'FMT_NORETURN'
2019-06-24 08:53:35 -07:00
d5d5865615 Move strtod_l check to CMake since it's very system-specific 2019-06-23 17:10:57 -07:00
29ef7d31e4 Fix a warning 2019-06-23 11:09:15 -07:00
af83192d79 Fix warnings 2019-06-23 08:14:15 -07:00
6952732b6c Remove misplaced checks 2019-06-23 06:33:07 -07:00
b97e5d8c2a Remove deprecated fmt/time.h 2019-06-23 06:13:17 -07:00
572b077dbf Fix warnings 2019-06-22 20:52:33 -07:00
72e519a4bd Add formatter<std::string_view> 2019-06-22 20:26:28 -07:00
635e01fe74 Update <format> to the current wording 2019-06-22 13:44:48 -07:00
0e72c98043 Make undocumented output_range internal 2019-06-19 20:08:11 -07:00
f13906f408 back_insert_range<internal::buffer> -> buffer_range 2019-06-19 14:12:29 -07:00
22ddd4b989 Simplify feature checks 2019-06-19 07:46:09 -07:00
bb827341ed Add FMT_FUNC where necessary 2019-06-18 09:48:23 -07:00
64c54703d4 Cleanup 2019-06-17 11:02:18 -07:00
1c3197b8d8 Fix warnings 2019-06-17 09:21:29 -07:00
fd2292f13a Cleanup checked iterators 2019-06-17 08:30:37 -07:00
4912cff65d Fix handling of mapped types in compile checks (#1200) 2019-06-16 16:06:06 -07:00
4639843839 Cleanup 2019-06-15 09:44:51 -07:00
e29708ee57 uintptr -> fallback_uintptr to avoid confusion with uintptr_t 2019-06-14 18:47:36 -07:00
f03a6c5325 Cleanup 2019-06-14 13:38:44 -07:00
6c3d584e67 Simplify warning suppression 2019-06-14 13:03:34 -07:00
12f4683883 Make iterator_t an alias template 2019-06-13 21:32:58 -07:00
874d6727e4 Remove workarounds for pre-C++11 compilers 2019-06-13 20:56:08 -07:00
a9940192fb Fix warnings 2019-06-13 08:56:35 -07:00
34b5418359 Fix warnings 2019-06-13 07:29:10 -07:00
cbbee1b385 Fix handling of hexfloat 2019-06-12 20:53:01 -07:00
92a44db11c Fix warnings 2019-06-12 19:44:08 -07:00
d05d42751c Remove old msvc workaround from arg_formatter_base and fix warning 2019-06-12 19:27:23 -07:00
d32fe0f3f6 Fix hadling of nullptr 2019-06-12 09:22:36 -07:00
e5422db4b2 Fix handling of uintptr_t 2019-06-12 08:16:41 -07:00
9d7b64a259 More cleanup 2019-06-11 22:11:47 -07:00
5e293bd97a Remove unnecessary qualification 2019-06-11 20:36:39 -07:00
4a502d9802 Add remove_reference_t 2019-06-11 20:28:05 -07:00
d384cdd397 Make is_contiguous_back_insert_iterator internal 2019-06-11 20:16:57 -07:00
32544b6108 More cleanup 2019-06-11 19:22:19 -07:00
39f522a13a get_types -> encode_types 2019-06-11 18:50:14 -07:00
d7d2bebf99 Remove redundant typename 2019-06-11 18:29:47 -07:00
9427f15bef Fixed issue with formatting to an array of chars 2019-06-11 18:09:18 -07:00
87fbc6f756 get_type -> mapped_type_constant 2019-06-11 07:23:39 -07:00
a48daa60e5 Remove remove_volatile 2019-06-10 20:25:04 -07:00
afdbbac75c Cleanup 2019-06-10 18:10:26 -07:00
e33fe14f5b Simplify visit 2019-06-10 08:28:39 -07:00
e895da2ec3 Clean up value 2019-06-10 07:58:00 -07:00
e1a67b5285 Remove TODO 2019-06-10 06:54:09 -07:00
a291f07e1a Clean up argument mapping 2019-06-09 22:27:40 -07:00
5d9100fa2f Move char8_t to fmt/core.h 2019-06-08 09:42:11 -07:00
4faadff0a0 Add preliminary user-defined type support 2019-06-08 09:04:46 -07:00
5d48733596 Clean up value construction 2019-06-07 19:27:20 -07:00
0f0b42861b Cleanup 2019-06-07 17:53:25 -07:00
209db68b28 Get rid of FMT_CONSTEXPR11 2019-06-07 14:00:57 -07:00
cb4c59495e Deprecate convert_to_int 2019-06-07 13:38:08 -07:00
40779749ac is_formattable -> has_formatter 2019-06-07 06:51:21 -07:00
b3cf8613b1 Make formatter specializations override implicit conversions 2019-06-07 06:25:46 -07:00
3fdba04924 Reduce the number of nontrivial formatter instantiations 2019-06-06 22:02:53 -07:00
f5f3ffac59 Merge string make_value overloads 2019-06-06 08:29:16 -07:00
a38b99a188 Fix a regression in named argument handling introduced by prepare 2019-06-05 16:50:04 -07:00
aa31028b2c char_t_impl -> char_t 2019-06-05 10:13:34 -07:00
0787d69747 Simplify SFINAE 2019-06-05 09:02:33 -07:00
bae00aa8d7 Simplify is_string 2019-06-05 08:41:00 -07:00
388bb389e6 integral_constant -> bool_constant 2019-06-05 08:14:47 -07:00
7e39c7e6f4 Put stringy stuff together 2019-06-05 07:43:20 -07:00
3eff8f94d2 Update docs 2019-06-05 06:24:18 -07:00
469a4bbd35 Use enable_if_t 2019-06-04 21:38:18 -07:00
d2ee5f2407 Merge tests 2019-06-04 21:31:23 -07:00
c264e641ea Add conditional_t for pre-C++14 2019-06-04 18:50:30 -07:00
4aa0dc578b Fix docs 2019-06-04 18:02:55 -07:00
064ce6b6c0 Specialize is_char for character types 2019-06-04 17:08:58 -07:00
7893d85394 Clarify why we cannot have nice things 2019-06-04 08:47:25 -07:00
5bafcb437b Add comments about things broken in MSVC 2019-06-03 19:14:16 -07:00
1530242551 Fix signature in the docs 2019-06-03 17:35:15 -07:00
eddb84cfc0 Fix formatting of exotic characters 2019-06-03 17:08:00 -07:00
7e42c65bb6 Document a more useful to_string_view overload 2019-06-03 11:57:33 -07:00
1e6e87cb74 Update docs 2019-06-03 11:35:12 -07:00
0c6a6e0250 Get rid of the FILE* hack and reword apidocs 2019-06-03 10:27:00 -07:00
1653244c69 Fix compilation issue on VS2019 (#1186) (#1191) 2019-06-03 08:34:27 -07:00
d54e64b3c8 Make buffer_context an alias template 2019-06-02 18:28:49 -07:00
ec6651087d Remove old is_constructible workarounds and replace typedefs with using 2019-06-02 16:46:45 -07:00
4d4b8c238d FMT_CHAR -> char_t 2019-06-02 15:03:37 -07:00
56d2b91108 Install git 2019-06-02 13:57:19 -07:00
89d6c959b2 Fix cmake link 2019-06-02 13:24:32 -07:00
76ef39fc50 Update vagrant config 2019-06-02 13:19:33 -07:00
af2c73772c Implement parsing of string_views 2019-06-02 11:11:28 -07:00
9df0e2d1f1 Implement string parsing 2019-06-02 07:39:38 -07:00
5b7bbf8853 Revert "FMT_CHAR -> char_t"
This reverts commit 4c650057a0.
2019-06-01 15:01:04 -07:00
4c650057a0 FMT_CHAR -> char_t 2019-06-01 12:32:24 -07:00
2833c76f22 Move char_t to template param to reduce symbol size 2019-06-01 12:14:27 -07:00
67feef5589 Make enable_if_t more std-like and move to fmt namespace 2019-06-01 10:05:16 -07:00
78daa50ffc Fix handling of chrono durations with minimal signed rep 2019-06-01 09:36:37 -07:00
87e4ea2906 Fix a warning 2019-06-01 08:24:36 -07:00
c56b17029a Add msvc2019 to CI 2019-06-01 07:50:15 -07:00
c929684e33 inlines count_code_points(basic_string_view<char8_t)
count_code_points(basic_string_view<char8_t>) 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.
2019-06-01 07:17:22 -07:00
f57227a148 FMT_ENABLE_IF -> enable_if_t 2019-05-31 20:09:19 -07:00
634f707f2b Simplify char_t and remove msvc2013 from CI 2019-05-31 19:28:37 -07:00
406e632bd1 result_of -> invoke_result_t 2019-05-31 08:54:32 -07:00
49f78a427b Demacrify 2019-05-30 21:30:29 -07:00
637bf3c6d9 Workaround a bug in clang-format 2019-05-30 11:46:31 -07:00
8302c2f33b fmt::internal::declval -> std::declval 2019-05-30 09:46:10 -07:00
d07cc2026b FMT_EXPLICIT -> explicit, FMT_NULL -> nullptr 2019-05-30 07:42:36 -07:00
4a7966c773 Drop gcc 4.4 from CI 2019-05-30 06:51:59 -07:00
9b3c24b99b One weird trick to simplify docs; doxygen hates it 2019-05-29 21:09:43 -07:00
30bce6c14c Fix a few chrono formatting corner cases (#1178) 2019-05-29 18:02:26 -07:00
e5512c5d57 Use static_assert instead of SFINAE in arg(...) 2019-05-29 13:21:24 -07:00
afc571aedc Document join and relax its compiler requirements 2019-05-29 11:21:05 -07:00
ad360a62b0 add gcc 8 c++17 release build 2019-05-29 06:50:43 -07:00
3cf12d7b11 add gcc 8 c++17 build 2019-05-29 06:50:43 -07:00
bb254d146b Disable std-format-test by default 2019-05-27 20:02:08 -07:00
291ba837f2 Remove wrong compile-time checks from printf (#1173) 2019-05-24 07:50:13 -07:00
01c631af95 Implement unsigned and long long parsing 2019-05-19 07:34:54 -07:00
4fcd4a4bd0 Reuse parse_format_string in scan 2019-05-18 14:18:06 -07:00
2346779d6b More documentation fixes 2019-05-18 09:30:36 -07:00
afc1a74a6c Minor documentation fixes 2019-05-18 09:10:17 -07:00
ad0eade471 Remove MSVC nonsense 2019-05-18 09:05:19 -07:00
28c187bcd7 Capitalize titles 2019-05-18 08:56:49 -07:00
91bb3aaf06 fmtlib.net -> fmt.dev 2019-05-17 15:42:00 -07:00
5e7bdf1b97 Clean up vagrant config 2019-05-16 12:22:04 -07:00
570453f271 Add a vagrant config for testing gcc 4.4 2019-05-16 06:26:16 -07:00
ef6282fc45 Fix gcc 4.4 build 2019-05-15 22:37:00 -07:00
e3e470bb69 Remove deprecated format_decimal 2019-05-15 10:34:45 -07:00
67179dbc23 Remove deprecated format_decimal 2019-05-15 10:34:38 -07:00
a5ffa735db Fix gcc 4.4 build 2019-05-15 10:20:51 -07:00
5ee0804631 Experiment with scan API 2019-05-15 10:02:40 -07:00
25b72fc4cd Move <format> to tests not to confuse users 2019-05-15 09:08:42 -07:00
d179ec5f8b Simplify Grisu 2019-05-15 08:40:21 -07:00
2a9e8b52de Fix advance_to() and begin() using iterator (#1159) 2019-05-14 08:41:11 -07:00
2c77562b13 Fix ambiguous formatter specialization in fmt/ranges.h (#1123) 2019-05-12 13:03:20 -07:00
98b3775297 Add support for exotic string_view iterators (#1156) 2019-05-12 11:07:49 -07:00
b488df6cfe Fix Grisu3 stopping conditions 2019-05-12 08:56:50 -07:00
f4dfd6e30f Suppress all clang-target-msvc test warning in CMake and other misc fixes (#1151)
* Fix conditional `char8_t` from `format.h` and fix `-Wunused-result` of [[no_discard]] begin() when in c++17

* Suppress `-Winconsistent-dllimport` when in clang-target-msvc

* Suppress warning _CRT_SECURE_NO_WARNINGS in MSVC and -Wdeprecated-declarations

Suppress warning _CRT_SECURE_NO_WARNINGS in MSVC and -Wdeprecated-declarations of POSIX functions in Clang target MSVC.
Those functions are used by gtest.

* Remove FMT_FUNC, mark FMT_API to export
2019-05-11 11:48:27 -07:00
a6e8ed15c4 Disable UDL templates on GCC 9 by default (#1148) 2019-05-11 08:58:39 -07:00
de5da50910 Fix formatting of extreme durations (#1154) 2019-05-11 08:42:02 -07:00
ea2976e6d5 Move internal::uintptr_t test to format-impl-test (#1152) 2019-05-11 06:58:22 -07:00
77d6036cd5 Fix unexpected trailing decimal point (#1153) 2019-05-11 06:34:47 -07:00
ccc318e807 Update README.rst 2019-05-10 10:04:44 -07:00
4c8efd694c Update README.rst 2019-05-10 09:56:40 -07:00
d22d11b5ff Update README.rst 2019-05-10 09:54:42 -07:00
e9bab6d028 Improve handling of large durations 2019-05-08 12:40:33 -07:00
f52c09f924 Fix format_to_n docs in 5.1.0 2019-05-08 12:40:25 -07:00
118d8bccc2 Fix compilation error under MSVC 19.21 (#1140) 2019-05-08 11:20:55 -07:00
6828d549e8 Add FMT_ENABLE_IF_T
for definitions of functions which declared using FMT_ENABLE_IF
2019-05-08 11:20:55 -07:00
3fd134be03 Move test_count_digits to format-impl-test and disable gtest warnings (#1147)
* This translation unit includes `gtest.h` in which using something like `strncpy`

Suppress MSVC warnings from `gtest.h` included.

Warning sample:
fmt-master\test\gtest\gtest.h(2873,10): warning: 'strncpy' is deprecated: This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. [-Wdeprecated-declarations]

* Moving `test_count_digits` to format-impl-test then count_digits<4>(internal::uintptr_t) shall not be exported

* retaining _CRT_SECURE_NO_WARNINGS always defined should be no harms.
2019-05-07 12:09:11 -07:00
ca7c1f89dc Fixed a compile error under MSVC.
The #warning directive is not supported by MSVC.
To still get a message to the user we use #pragma message() under MSVC now.
2019-05-05 14:04:04 -07:00
ca978b3d21 Fix handling of nan durations 2019-05-05 08:53:23 -07:00
c1d430e61a Improve handling of negative durations 2019-05-04 17:52:20 -07:00
38a85502ed Use the same rep type for seconds to prevent overflow 2019-05-04 09:22:09 -07:00
241414028d Eliminate shadowed variable warnings from gcc-7.2
The gcc-7.2.0 compiler (and others) were giving shadowed variable warnings for this include file.  A simple renaming of a couple local variables eliminates the warnings.
2019-05-04 08:00:31 -07:00
29c10fbf6e Fix DLL visibility of explicit instantiation "declaration" of internal::basic_data<void> in header format.h and the explicit instantiation "definition" in format.cc (#1134)
* Update format.cc

As the explicit instantiation *declaration* of `internal::basic_data<void>` in format.h, this explicit instantiation *definition* should mirror FMT_API also.

* Mirror visibility of explicit instantiation declaration 

explicit instantiation declaration of internal::basic_data<void> should mirror visibility of FMT_API

* Eliminate `__declspec(dllexport)` designation on extern template internal::basic_data<> when `extern` affected during exporting phase.

* Add `FMT_EXTERN_TEMPLATE_API` for designate DLL export `extern template`

When exporting DLL, do not designate `__declspec(dllexport)` any template that has any explicit class template declaration a.k.a. `extern template`. Instead, designate `__declspec(dllexport)` at single point where we have explicit class template definition a.k.a. normal instantiation without `extern`

Note: this is a c++11 feature.

* Delete whole `FMT_USE_EXTERN_TEMPLATES` block and its condition

1. Remove whole `FMT_USE_EXTERN_TEMPLATES` block
(trailing `FMT_UDL_TEMPLATE` block)
````
#ifndef FMT_USE_EXTERN_TEMPLATES
#  ifndef FMT_HEADER_ONLY
#    define FMT_USE_EXTERN_TEMPLATES                           \
      ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \
       (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
#  else
#    define FMT_USE_EXTERN_TEMPLATES 0
#  endif
#endif
````

2. Delete `FMT_USE_EXTERN_TEMPLATES` condition, only condition, that trailing basic_data class template definition.
````
#if FMT_USE_EXTERN_TEMPLATES
extern template struct basic_data<void>;
#endif
````

3. Replace `FMT_API` with new `FMT_EXTERN_TEMPLATE_API` added in `core.h` for sake of extern template of `basic_data<void>`

* Add `#define FMT_EXTERN extern` only when not `FMT_HEADER_ONLY`

* Replace `extern` on basic_data<void> with the `FMT_EXTERN` condition in core.h

* replace misspelled if !define() with ifndef
2019-05-02 07:49:01 -07:00
4a4d72f917 Fix handling of invalid string in chrono formatting 2019-05-01 10:06:42 -07:00
b3cc9c0567 Merge remote-tracking branch 'upstream/master' into invalidcolons
# Conflicts:
#	test/chrono-test.cc
2019-04-28 21:35:21 +02:00
2e3352fd05 provoke assertion
fmt/include/fmt/core.h:246:
typename std::make_unsigned<_Tp>::type fmt::v5::internal::to_unsigned(Int)
[with Int = long int;
 typename std::make_unsigned<_Tp>::type = long unsigned int]:
Assertion `(value >= 0) && "negative value"' failed.
2019-04-28 21:34:09 +02:00
4c721e3a2f Fix chrono formatting with invalid argument id (#1132) 2019-04-28 07:08:41 -07:00
8d8ea21c69 Partially implement Grisu3 2019-04-27 12:17:21 -07:00
40a7975640 Remove trailing zeros 2019-04-27 07:42:27 -07:00
cb46397dfb Fix typo 2019-04-27 07:13:35 -07:00
134904c886 Re-enabled constexpr tests 2019-04-26 17:07:37 -07:00
bd516e3429 Convert negative precision to zero in printf (#1127)
and remove redundant check in grisu2_prettify.
2019-04-21 07:44:04 -07:00
5efb24dd2b Add specialization test 2019-04-19 17:15:46 -07:00
946498cfbc Fix handling of zero precision 2019-04-19 15:10:12 -07:00
6b20863918 fmt::ptr: support unique_ptr and shared_ptr. 2019-04-18 10:12:11 -07:00
d306585a3f Don't inject internal names into std (#1120) 2019-04-17 13:25:31 -07:00
544b927933 Don't detect C compiler 2019-04-17 06:18:53 -07:00
dc94010fa5 Remove char_traits (#1117) 2019-04-16 17:08:24 -07:00
397e8dd9d5 clang-format 2019-04-15 11:39:19 -07:00
2b415b7af7 Restructure printf_arg_formatter to make it customizable 2019-04-15 11:10:31 -07:00
5d755d0a4e Fix handling of volatile char (#1115) 2019-04-14 12:34:56 -07:00
bade46aae5 Optimize grisu using uint128_t 2019-04-13 13:44:41 -07:00
41fbaeb3b1 Add <format> test 2019-04-13 11:37:52 -07:00
8bc0adb9ba Get rid of obsolete cmake stuff 2019-04-13 11:37:52 -07:00
1763d0e7a2 Add MongoDB to "Projects using this library" 2019-04-12 15:52:04 -07:00
f569c1ba28 doc fix: time -> chrono
Change refs to fmt/time.h -> fmt/chrono.h
RST label rename time-api -> chrono-api
2019-04-12 14:51:32 -07:00
ccd70f59ee Workaround bogus unreachable warnings in MSVC 2019-04-11 17:59:35 -07:00
a4969ebe06 Link to fmt(...) docs from index 2019-04-10 19:22:10 -07:00
a6ad29aa34 Update <format> 2019-04-10 09:09:34 -07:00
52eb3fe274 Update <format> 2019-04-10 08:29:07 -07:00
09e2ac5e46 Update <format> 2019-04-10 07:56:50 -07:00
df4ea0c76c Update <format> 2019-04-10 06:25:42 -07:00
718f60accb Fix shadowing warning (#1105) and clang format 2019-04-08 19:14:32 -07:00
aeb5ad3ce1 Enable [[noreturn]] some. 2019-04-08 07:53:59 -07:00
2808395481 basic_buffer -> buffer
This reduces symbol sizes and gets rid of shadowing warnings.
2019-04-07 20:32:28 -07:00
6e37c20030 Use compile features cxx_auto_type cxx_variadic_templates instead of cxx_std_11 2019-04-07 08:47:17 -07:00
3de3d76a36 Add compile features for cmake 3.8+ 2019-04-07 08:47:17 -07:00
07d5a86a7c Fix warnings 2019-04-06 22:10:10 -07:00
ab1474ef66 Workaround segfault in doxygen and apply clang-format 2019-04-06 15:55:14 -07:00
918ab77baa Try fixing doc build 2019-04-06 10:04:56 -07:00
735b1fadc3 Only update key on Linux 2019-04-06 09:49:35 -07:00
3c531b735b Fix expired key error when installing with apt
Error:
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: https://packagecloud.io/github/git-lfs/ubuntu trusty InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6B05F25D762E3157
W: http://ppa.launchpad.net/couchdb/stable/ubuntu/dists/trusty/Release.gpg: Signature by key 15866BAFD9BCC4F3C1E0DFC7D69548E1C17EAB57 uses weak digest algorithm (SHA1)
W: Failed to fetch https://packagecloud.io/github/git-lfs/ubuntu/dists/trusty/InRelease  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 6B05F25D762E3157
W: Some index files failed to download. They have been ignored, or old ones used instead.
2019-04-06 09:32:38 -07:00
f10a7e2e46 Test exotic pointer formatting 2019-04-06 09:04:44 -07:00
bd8177177a Add support for platforms without uintptr_t 2019-04-06 08:11:03 -07:00
0302927f56 Optimize pointer formatting 2019-04-05 20:36:37 -07:00
bb6842ba35 Simplify to_string 2019-04-05 19:15:22 -07:00
b23c8633fa Detect presence of uintptr_t 2019-04-05 07:43:00 -07:00
b588d7f35f Fix a couple of deprecated things. 2019-04-04 16:26:22 -07:00
018d8b57f6 Remove broken snprintf 2019-03-30 20:27:52 -07:00
1987db663b clang-format 2019-03-30 07:48:53 -07:00
a6d1ad741d handle fwrite results #1098 2019-03-30 07:48:53 -07:00
e979c782d3 Extend basic_writer with write() method for doubles with optional format_specs argument 2019-03-25 19:16:41 -07:00
9e1531c1e1 install pkg-config file into libdir
Most pkgconfig files contain a Libs: variable, which is either /usr/lib
or /usr/lib64. If a 32bit and a 64bit variant of fmt libraries is
installed, the last one wins. As a result compiling for the other
bitsize will fail.

Instead of sharedir use libdir as install target.

Fixes commit 9d0c9c4bb1
Fixes commit 287342dab1

Signed-off-by: Olaf Hering <olaf@aepfle.de>
2019-03-25 19:15:35 -07:00
0a66e4cbbb Update README.rst 2019-03-24 11:37:07 -07:00
91acfe6852 Fix UBSAN warning 2019-03-22 07:56:02 -07:00
b7e6bf9671 clang format 2019-03-21 20:51:37 -07:00
da0ea4161a Make compile-time checks work with fallback formatter (#1088) 2019-03-21 19:26:53 -07:00
7ad3015f5b Added missing typename to FMT_STRING. (#1089)
* Added missing typename to FMT_STRING.

This is so that FMT_STRING can be used in a template.
2019-03-20 20:37:00 -07:00
f0b572da05 Update wording test 2019-03-20 06:53:31 -07:00
6d416cf674 Forward declare is_string<FILE*> specializations 2019-03-19 05:20:18 -07:00
b742f622ab Create PR template to help agree to the licensing terms (#1083) 2019-03-18 14:41:17 +01:00
02a6f16b52 Update LICENSE.rst 2019-03-17 18:49:12 -07:00
294fd7df96 Remove isinf workaround 2019-03-17 14:49:19 -07:00
17c6900f83 Update docs 2019-03-17 14:15:48 -07:00
0faa968cc3 Make floating-point formatting locale-independent 2019-03-17 13:26:56 -07:00
bc784d3625 Remove isnan workaround 2019-03-17 12:23:36 -07:00
53379dfd0c Don't set CMAKE_BUILD_TYPE if fmt is a subproject (#1081) 2019-03-17 10:50:40 -07:00
76d326a2a2 Enable grisu for general format 2019-03-17 09:48:50 -07:00
c21c6b8c4b Move enable_if to template params 2019-03-16 15:15:38 -07:00
ec645ca262 Update readme and doxygen config 2019-03-16 10:47:50 -07:00
ae0b0dab9f Remove obsolete TODO 2019-03-16 10:04:16 -07:00
5466a5b41f Document inherited members 2019-03-16 08:22:16 -07:00
9b392a683d Update readme 2019-03-16 07:59:58 -07:00
0fa65cf329 Add example 2019-03-16 07:36:27 -07:00
fdd0149e71 Update readme 2019-03-16 07:27:53 -07:00
e19a95b271 Update readme 2019-03-16 06:51:35 -07:00
ef39274973 Update readme 2019-03-16 06:47:18 -07:00
a7f68dcc01 Update readme 2019-03-16 06:46:19 -07:00
1428b34299 Update readme 2019-03-16 06:30:50 -07:00
97619e27a2 More fixed precision tests 2019-03-15 10:20:20 -07:00
dd6cc0e6ac Merge time-test into chrono-test 2019-03-14 18:10:56 -07:00
a939c75956 Merge fmt/time.h into fmt/chrono.h 2019-03-14 18:07:42 -07:00
17e4b53926 Make chrono formatting work without exceptions (#1062) 2019-03-14 18:01:03 -07:00
a82b3680dc More tests and fixed precision fixes 2019-03-13 19:47:07 -07:00
287342dab1 cmake: default FMT_PKGCONFIG_DIR to a relative path 2019-03-13 11:28:50 -07:00
e28429ee73 Prevent overflow with zero precision 2019-03-13 10:46:25 -07:00
49bbf3c876 Simplify shadowing warning fix 2019-03-13 08:29:37 -07:00
5e5506f833 Update readme 2019-03-12 06:08:18 -07:00
e06523361d Visual Studio 2017: warning C4456: declaration of 'result' hides previous local declaration 2019-03-11 14:15:23 -07:00
ebec00138b Reword licensing part 2019-03-10 17:42:36 -07:00
8daa3c6834 Clarify contribution licensing
This is similar to https://github.com/apple/swift/blob/master/CONTRIBUTING.md
with an explicit clause that allows changing license for #1073.
2019-03-10 17:38:26 -07:00
0d418a8d58 Update and rename CONTRIBUTING.rst to CONTRIBUTING.md 2019-03-10 17:25:06 -07:00
4c66dad8c1 Refactor digit generation 2019-03-10 15:45:06 -07:00
b1f7cca89e stop -> handler and swap args 2019-03-10 14:43:26 -07:00
f90d33ca12 error_ulp -> error 2019-03-10 14:29:28 -07:00
78c755dc48 Update readme 2019-03-10 12:17:35 -07:00
f230170157 Update readme 2019-03-10 12:13:14 -07:00
ced8aa8c9e Update readme 2019-03-10 12:07:57 -07:00
77d54251f0 Update benchmark results 2019-03-10 11:21:24 -07:00
1632f72cbe Test get_round_direction 2019-03-10 11:14:50 -07:00
8129b9bc46 Test that the library can be compiled witout locales 2019-03-10 07:57:29 -07:00
835087dd04 Add color-test 2019-03-10 07:57:29 -07:00
4523053e6f Fix typos. 2019-03-10 07:49:33 -07:00
8407f4cb24 Round close to zero fixed precision 2019-03-09 15:18:34 -08:00
49d244c065 Don't emit more than precision digits (#1072) 2019-03-09 13:53:23 -08:00
3466d9c845 Don't override fixed formatting depending on exponent (#1072) 2019-03-09 13:22:07 -08:00
93d22dec35 Implement rounding up and clean up FP formatting 2019-03-09 10:40:36 -08:00
d560ddac25 Temporarily disable Grisu for fixed formatting 2019-03-08 19:09:05 -08:00
2d981bb133 Add documentation for '%' format type. (#1071) 2019-03-06 11:50:32 -10:00
d8434baa03 Declare the size of RESET_COLOR.
This is so that the format with a text_tyle will compile even if
header-only mode isn't enabled. Addresses #1063.
2019-03-06 09:41:45 -10:00
8f7780a4f6 Correct comment 2019-03-06 09:23:16 -08:00
2e526a664a Fix handling of output iterator in ranges 2019-03-06 08:10:46 -08:00
79b79f329e Add support for '%' type to output floating point values as a
percentage.

This helps with compatibility with Python's format strings.
2019-03-05 17:36:20 -08:00
287eaab3b2 Increment output iterator in basic_writer::write for character types (#1056) 2019-02-26 12:16:34 -10:00
a97757736b Use grisu for fixed precision 2019-02-23 15:50:50 -10:00
327d4b6e9e Fixes for some pedantic warnings (#1054)
* Fix order of initializers

* Remove unused parameter

* Disable warning "-Wswitch-enum"
2019-02-23 09:40:08 -10:00
8af651be39 Implement fixed precision 2019-02-22 10:47:27 -10:00
187bd1b8b2 Clarify lifetimes of named_arg parameters (#1051)
* Clarify usage of fmt::arg

Document that fmt::arg takes a non-owning
reference, even if that reference is to
a temporary. As such, users should make sure
the lifetime of the reference lasts as long
as the named argument.

* Clean up language

Remove mentions of `std::reference_wrapper` and rvalues
in favor of more common terminology like dangling references.
2019-02-22 06:37:19 -10:00
4e5694fd05 Update arg signature 2019-02-21 17:38:30 -10:00
82c24edcf6 Workaround a bogus Qt Creator warning 2019-02-19 06:33:55 -10:00
ed138d794a test: assert-test: fix typo in else-branch of EXPECT_DEBUG_DEATH_IF_SUPPORTED
Patch by Ievgen Liubymkin (jackyf).
2019-02-18 14:02:02 -10:00
0476a51cba Add Sublime syntax (#1037) 2019-02-15 15:08:58 -08:00
c5aad69f2a Restore deprecated begin() 2019-02-15 15:00:02 -08:00
5b0006476a Make stopping condition configurable in grisu 2019-02-14 18:25:13 -08:00
a44238f2ef Improve grisu 2019-02-13 20:03:27 -08:00
83808076e3 Minor cleanup 2019-02-13 19:28:02 -08:00
9660ea1bff Simplify format string checks 2019-02-10 18:00:19 -08:00
4a9d676362 Gradle 4.10 >> Gradle 5.2
TravisCI
- replaced from manual Gradle download to install with 'sdkman'
- changed build name

Gradle
- updated build tool version
2019-02-10 16:15:32 -08:00
f041f128f5 Minor cleanup 2019-02-10 15:20:40 -08:00
e4572e5def Update std implementation 2019-02-10 07:56:33 -08:00
442fa1bd46 Decouple format and parse contexts 2019-02-09 20:39:37 -08:00
744e66bb08 Deprecate format_context::parse_context() 2019-02-09 16:15:20 -08:00
d231d68a8b Fix handling of custom context 2019-02-09 07:36:09 -08:00
01f34d0b0b Fix library deprecation warning
Since C++17, using template specialization 'std::allocator<void>' in any shape or form (even just mentioning it) is deprecated! A simple workaround is replacing 'void' by another (preferably empty) type, e.g. 'fmt::monostate'.

Found by Clang 9 in Visual Studio.
2019-02-07 12:20:46 -08:00
9a0a24f90b Test is_streamable with overloaded comma operators 2019-02-06 15:44:59 -08:00
430e6ac9b6 Protect against overloaded comma operators in decltype 2019-02-06 15:44:59 -08:00
467520e7a4 Remove unused macro 2019-02-06 11:34:59 -08:00
5a314a5288 Eliminate extra copy on floating-point formatting 2019-02-06 10:17:50 -08:00
9989e7f4e3 Update benchmark results 2019-02-04 17:56:33 -08:00
31510cb437 Fix warnings from Visual Studio
Name hiding.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-02-04 11:58:56 -08:00
61c9b563c2 Replace 'std::result_of' by 'std::invoke_result' where possible (#1025)
C++17 deprecated 'std::result_of' in favour of 'std::invoke_result' and will ban it outright in C++20. Therefore
- implement 'internal::result_of' in terms of 'std::invoke_result' when compiling C++17 mode.
- implement 'internal::result_of' in terms of 'std::result_of' when compiling in modes C++11 or C++14.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-02-04 11:25:22 -08:00
864b9a2202 Correct the comment 2019-02-04 08:29:39 -08:00
1538336836 Remove unnecessary checks 2019-02-04 08:25:41 -08:00
22de5a755f Fix warnings from Travis 2019-02-03 15:25:09 -08:00
355eb6d29a Enable grisu for shortest roundtrip (default) formatting 2019-02-03 10:38:28 -08:00
b8d34e0db3 Fix rounding 2019-02-02 09:19:46 -08:00
e61cac687d Minor grisu improvements 2019-02-02 07:41:52 -08:00
7fbbfed8c6 Fix warnings caused by usage of deprecated functionality 2019-02-02 05:48:39 -08:00
c3268f4e50 Remove use cases of deprecated functionality 2019-02-02 05:48:39 -08:00
34951f1999 Replace comments regarding deprecation with attributes 2019-02-02 05:48:39 -08:00
3f52336e6c Simplify formatter selection 2019-01-30 19:39:42 -08:00
7ca8fc3b17 Fix a bogus warning 2019-01-30 07:06:40 -08:00
5289dd600b Test formatting of special numbers 2019-01-30 06:56:46 -08:00
bf6529f2ce Update docs 2019-01-30 06:07:59 -08:00
0700612249 Implement 'chrono' formatting specifiers '%Q' and '%q'
Howard Hinnant's 'date' library recently gained these two new formatting specifiers. This implementation in {fmt} includes support for 'std::chrono::duration' specializations with floating-point representation types and user-definable precision.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-01-27 11:10:08 -08:00
06c005b7b0 Clarify that compile-time checks don't support named arguments 2019-01-27 10:10:13 -08:00
4f6fda558c Add a grisu test stub 2019-01-27 10:10:13 -08:00
9f70b034e1 Implement precision for floating-point durations.
The formatting syntax follows p1361r0, augmented by a precision field as proposed in #1004.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-01-23 07:17:00 -08:00
7cdb1e5e40 Workaround broken is_default_constructible in MSVC 2019-01-21 10:54:49 -08:00
5f1ceebc7f Make formatter<T> override ostream<< for templates (#952) 2019-01-21 09:42:55 -08:00
1b11b000c7 Update readme 2019-01-20 15:33:30 -08:00
83f052930a Add code from p0645 2019-01-20 15:12:01 -08:00
fdd8e333c1 Fix compilation with locales disabled (#1011) 2019-01-19 07:16:05 -08:00
dad1eec842 Workaround unimplemented T... on gcc 4.6.x (#1008) 2019-01-16 11:41:20 -08:00
b0cde860ae Implement 'snprintf(OutputIt it, size_t n, const S &format, const Args & ... args)' (#917)
Mostly equivalent to 'sprintf(const S &format, const Args & ... args)' but generates at most 'n' characters through output iterator 'it'. The output type is the same as with 'format_to_n'.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-01-13 13:08:01 -05:00
e05dfb0887 Fix compile errors due to name-hiding and an unused function argument.
These problems are pointed out by clang-tidy and fail compilation on msvc at /W4 /WX.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-01-13 12:18:05 -05:00
dde095fab8 Revert "Reorder defines"
This reverts commit 4a059914a9.
2019-01-13 08:13:38 -08:00
4a059914a9 Reorder defines 2019-01-13 07:40:37 -08:00
58b6f8db48 Format the code using clang-format 2019-01-13 06:58:20 -08:00
9a777b9e1c Implemented fmt::prepare()
Implementation of fmt::prepare() function and features around it.
2019-01-12 10:53:31 -08:00
da55e96f53 Install ninja to fix android build 2019-01-09 15:55:29 -08:00
dc8f8ce4c0 Fix handling of dynamic width in chrono formatter
Thanks to Howard Hinnant.
2019-01-09 15:23:21 -08:00
f5cc77cea0 Get rid of 'null_terminating_iterator' in printf.h (#980)
The iterator class itself and its helpers 'to_pointer' are removed after reformulating the formatting loop in terms of a 'basic_string_view<Char>::iterator'.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2019-01-04 12:18:14 -05:00
39623a7400 Replaced usage of gtest's internal scoped_ptr with unique_ptr.
scoped_ptr was removed in with gtest google/googletest@e857f9cdd9.
2019-01-02 19:05:51 -05:00
ae1de3a8d3 Add support for using text_style in format and vformat directly (#993)
* Closes #993
2019-01-01 09:26:54 -05:00
1b8a216ddf Improve docs 2018-12-28 15:05:42 -08:00
b3ad759a0a Bump version and correct changelog 2018-12-28 13:09:31 -08:00
9e554999ce Update version 2018-12-28 12:31:41 -08:00
b34d92b051 Bump version 2018-12-28 12:23:29 -08:00
d39ece1870 Make rst2md runnable and update changelog 2018-12-28 12:04:34 -08:00
fe2d715ff1 Update changelog 2018-12-24 11:56:48 -08:00
27b306701f Update changelog 2018-12-24 11:51:20 -08:00
68837079aa Update changelog 2018-12-24 11:48:41 -08:00
c98b202eb4 Update changelog 2018-12-24 11:47:06 -08:00
587a7f6634 Update changelog and docs 2018-12-24 10:56:13 -08:00
84e5170c9c Update changelog and deprecate visit 2018-12-24 10:02:41 -08:00
130e412b64 Update changelog and docs 2018-12-24 09:37:52 -08:00
0bbdca5b8b Fix conversion warnings (#989)
* Fix sign conversion warnings

* Ignore unused local typedefs

* Remove cast reported as useless on GCC

* Remove warning on unused variable

* Enable conversion warning checking for pedantic build

* Fix sign-conversion warnings in headers
2018-12-20 06:24:19 -08:00
77a7244804 Implement fill/align/width for strftime-like formatting 2018-12-19 07:03:02 -08:00
3e01376e08 Implement fill/align/width parsing in chrono formatter 2018-12-16 09:08:11 -08:00
1f92f8a9d8 Remove noexcept 2018-12-15 06:41:32 -08:00
8668639ae2 Get rid of null_terminating_iterator in format 2018-12-15 06:17:25 -08:00
93fd473b8f Add support for builtin terminal colors. (#974) 2018-12-15 06:16:00 -08:00
61ad543c3e Windows .sln filename changed from FORMAT to FMT 2018-12-14 07:50:54 -08:00
7f7504b3f5 Clean up docs 2018-12-12 18:21:13 -08:00
37f599b1a1 Fix docs 2018-12-12 17:50:50 -08:00
8c2e15aed5 Make printf work in search (#164) 2018-12-12 16:07:54 -08:00
de71db6d42 Fix asan error (#977) 2018-12-12 11:29:39 -08:00
b180b39152 Fix default formatting 2018-12-12 06:39:47 -08:00
24594c747e Disable printing the reset escape code when no style modifiers where applied. (#973) 2018-12-09 15:57:20 -08:00
b0f2224719 Implement default chrono formatting 2018-12-09 15:56:15 -08:00
749276072f Add file stream support for stylized text printing. (#967) 2018-12-09 09:28:48 -08:00
f54f3d0fb7 Move chrono-specific code to a separate header 2018-12-09 06:45:20 -08:00
bf1f1c73e3 Fix time test 2018-12-07 08:19:13 -08:00
b6bc6ec246 Add default ctor and fix use of constexpr macros in text_style 2018-12-07 07:22:18 -08:00
acfa95d4a8 Workaround a bug in MSVC's strftime (#965) 2018-12-07 07:07:21 -08:00
628f830583 More chrono formatting 2018-12-07 06:36:08 -08:00
aa3b5aba41 Implement locale-specific minute formatting 2018-12-06 16:12:10 -08:00
639de21757 Workaround more MSVC bugs 2018-12-06 12:16:04 -08:00
3242ddf7b5 Fix warnings 2018-12-06 08:16:12 -08:00
bd1104046b Workaround a bug in MSVC 2018-12-06 08:16:01 -08:00
81b5c4a5fd Add experimental emphasis support (#961) 2018-12-06 07:56:01 -08:00
7c4eb0fbeb Fix warnings in time.h 2018-12-05 14:38:08 -08:00
2d624218bf Fix another warning 2018-12-05 10:19:53 -08:00
b31680990e Fix a warning 2018-12-05 09:49:39 -08:00
b10ccb83e1 Add rpclib to projects 2018-12-05 06:42:33 -08:00
0497875ff3 Stop the orgy of casts 2018-12-05 06:27:31 -08:00
37dc495b9d Simplify MSVC workaround 2018-12-05 06:22:18 -08:00
2ff4996d05 Fix ambiguous complier error C2666 in vs2017.The '+' opeator may cause ambiguity.Avoid implicit conversion. 2018-12-05 05:55:43 -08:00
77656c672c Fix sign-conversion warnings reported by Clang7 2018-12-03 16:22:59 -08:00
ea5e4790bd Fix formatting 2018-12-03 08:58:48 -08:00
86681c4bb0 Update README.rst 2018-12-03 08:04:21 -08:00
e867768ee6 Do not override user provided compile flag 2018-12-03 07:31:19 -08:00
0c7f5c3ca4 Update README.rst 2018-12-02 08:22:51 -08:00
e7e2ab1070 Make return type of basic_format_args::max_size() consistent.
This squashes nasty narrowing conversion warnings.
2018-12-01 17:07:21 -08:00
29352af369 Update README.rst 2018-12-01 08:19:20 -08:00
68214bd904 More time formatting 2018-11-30 20:12:01 -08:00
bcf3fcd673 Clean up bit fiddling for argument packing 2018-11-30 17:04:49 -08:00
9dcf127fa5 Workaround a bogus MSVC warning 2018-11-30 13:47:04 -08:00
b8b06e3e10 Fix conversion warnings in Grisu 2018-11-30 10:37:40 -08:00
322b2594e0 Implement more time specifiers 2018-11-30 09:25:18 -08:00
0835f1ba3b Use full paths for fmt.pc.in 2018-11-30 06:17:33 -08:00
a084495d7e Add Ceph to projects 2018-11-28 17:28:27 -08:00
fa1d4dbcfd Fix warnings 2018-11-28 16:15:15 -08:00
2b2cfdac19 Update docs 2018-11-28 12:53:09 -08:00
99744f8f8f Suppress unfixable warning 2018-11-28 12:52:41 -08:00
f5fe849238 Specialize formatter for chrono durations 2018-11-28 11:39:21 -08:00
a5a9805a91 First stub at the datetime format parser 2018-11-25 17:25:22 -08:00
645c76a9a5 Fix dummy warnings 2018-11-25 15:33:28 -08:00
fecb2d6f0d Eliminate msvc compiler warnings (#931)
The sheer presence of 'std::gmtime' or 'std::localtime' gives rise to C4996 warnings in Microsofts compilers. Alas, the 'fallback(internal::null<>)'functions containing these library calls are never ADL-picked in the respective 'handle(internal::null<>)' selectors. Therefore hiding the fallbacks from msvc is perfectly fine.
2018-11-25 13:48:52 -08:00
64690d3a97 Add context_base::arg() 2018-11-24 10:49:48 -08:00
01640f44cf Fully qualify dummy_int (#941) 2018-11-24 06:22:59 -08:00
e37d6a9840 add make_printf_args and make_wprintf_args functions (#934)
* add make_printf_args and make_wprintf_args to printf.h
add minimal test for make_printf_args and make_wprintf_args to printf-test.cc

renamed the old printf_context template to basic_printf_context_t. the original wish was to rename it basic_printf_context, but that clashed with the name of the inner typedef. this style matches the format_context_t struct.
2018-11-22 13:57:07 -08:00
982ee5c699 parse_context -> format_parse_context 2018-11-21 07:10:22 -08:00
b7b8548559 thousands_sep -> thousands_sep_impl (#939) 2018-11-20 15:43:17 -08:00
00a8cc8325 Fix formatting 2018-11-20 07:43:40 -08:00
33fbb3a7eb Fix remaining linker errors. 2018-11-20 07:01:21 -08:00
bd6121596f Disable fmt-impl-test in windows + shared lib. 2018-11-20 07:01:21 -08:00
702b3d1618 Fix link error in windows with shared library. 2018-11-20 07:01:21 -08:00
9d4ef94350 Install pdb files. 2018-11-20 07:01:21 -08:00
6c95fb3562 Default Context to format_context 2018-11-18 07:19:25 -08:00
16b78ee629 fix incompatibilities with c++2a mode in clang 2018-11-17 08:38:04 -08:00
19e008876b More locale support 2018-11-14 16:25:49 -08:00
f2ee988105 Improve locale support 2018-11-14 12:07:39 -08:00
1385050e26 More formatter tests 2018-11-08 16:26:55 -08:00
03c1b110a5 Fix gcc 4.4 build 2018-11-08 12:41:55 -08:00
cc805c6162 Test enabled formatters 2018-11-08 10:59:10 -08:00
e01579231d Disallow leading zeros in arg-id 2018-11-08 08:48:56 -08:00
34030deca9 Cleanup warning flags 2018-11-06 17:22:30 -08:00
6b26e3f2d7 Manifest & Gradle comment
- #926
- The version of android build results follows latest release(5.2.1)
- Comment for Gradle and its plugin for android
 - `net.fmtlib` package name in the manifest
2018-11-05 17:31:09 -08:00
d286c97753 Update for Gradle build
Recovered Gradle build with latest release (ver. 4.10.2)

TravisCI
- Changed several apt configurations & build steps for Android

AndroidManifest:
- package name: fmt -> org.fmtlib

Gradle:
- Plugin version 3.1.3. Requires Gradle 4.4+
- Removed `x86` (duplicated with `x86_64`)
- `-std=c++17`. Latest NDK(clang7) should support this
- Missing `repositories` configuration

For some reason, the `repositories` config affects to the error:
"Could not find com.android.tools.lint:lint-gradle:26.1.3."
2018-11-05 17:31:09 -08:00
d951f6dfe7 Get latest Gradle (ver. 4.10.2)
Recovery of Gradle build. 1 of N
Modified several apt configurationss and order of the build
2018-11-05 17:31:09 -08:00
a23d592472 Fix check_format_string (#925) 2018-11-03 16:51:15 -07:00
36161284e2 Update docs 2018-10-28 09:28:51 -07:00
38f355d87b Revert "find sphinx-build before calling build.py"
This reverts commit 07200f445a because
the latter doesn't work with virtualenv correctly.
2018-10-28 09:26:21 -07:00
324eac1aa5 Make locales work with any character type 2018-10-28 09:03:27 -07:00
bdda4d6030 Simplify compile-time strings 2018-10-28 09:02:03 -07:00
5ee1a4bc8a check for property 'mutable iterator' and SFINAE on it 2018-10-28 08:57:43 -07:00
2dea780fbd change type naming and fix sfinae bug 2018-10-28 06:00:55 -07:00
b98e8301d5 add non-char support for compile-time format check 2018-10-28 06:00:55 -07:00
ccd3e8bbf3 Make is_constructible public (#918) 2018-10-27 17:10:19 -07:00
4373153800 Update usage.rst 2018-10-27 12:59:51 -07:00
73cfd8f325 Fix colored print 2018-10-25 17:18:46 -07:00
ec384302db additional test for print with background color
checks for clashes with other function overloads in fmt with templated parameters on the first or second position in the parameter list
2018-10-25 16:54:54 -07:00
0a96c032b9 Parameterize v*printf on string type (#920) 2018-10-25 13:52:08 -07:00
61e6d2e38c Fix core version of vformat_to 2018-10-25 06:21:41 -07:00
ea4010d704 Merge has_to_string_view into is_string 2018-10-24 18:16:00 -07:00
486fff597c Add sprintf_format instantiations and remove syntactic noise 2018-10-24 16:46:32 -07:00
1e3dcbba81 fix: 'format_to_n' compiles 'std::back_inserter' arguments
std::back_insert_iterators model the OutputIterator concept but differ considerably in their traits and behavior. In particular the former made compilation to fail when format_to_n is given a back_inserter as first argument. The emulation of an OutputIterator is not perfect due to the behavioural differences of back_insert_iterators (e.g. assignment always implies increment) but good enough to be used within fmt's machinery.
2018-10-24 16:45:18 -07:00
f0328f8e36 Use char_traits::length in string_view ctor (#914) 2018-10-24 15:21:21 -07:00
895fb98456 Disallow gcc 4.4 failures 2018-10-24 10:52:13 -07:00
20c708bf6d Fix build on gcc 4.4 2018-10-24 10:52:02 -07:00
9d0c9c4bb1 cmake: output share/fmt.pc 2018-10-24 07:14:08 -07:00
2d2326a76d Fix compilation with older gcc 2018-10-23 07:31:24 -07:00
1ec0272303 Get rid of FMT_UNION 2018-10-22 20:19:31 -07:00
2c81c851b2 Adapt any string-like type to be used by {fmt} just like the standard string types already supported. The adaption is totally non-intrusive.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-22 18:25:52 -07:00
846c644e84 Workeround broken sprintf in MSVC 2018-10-19 07:30:59 -07:00
13d472bd8c Compute output size for grisu 2018-10-18 17:16:50 -07:00
b71d3fe7ab Remove use_grisu 2018-10-17 17:01:45 -07:00
847abb6f8f Fix test 2018-10-17 11:57:06 -07:00
dda47c9466 Merge min_digits and max_digits 2018-10-17 10:49:30 -07:00
2924622157 Fix naming of basic_format_specs members 2018-10-17 10:13:10 -07:00
bda5f9a556 Replace grisu2_specs with core_format_specs 2018-10-17 08:55:45 -07:00
b1ca608bac Remove unused empty_spec 2018-10-17 08:39:58 -07:00
e8efdef8de Avoid extra copy 2018-10-17 08:19:46 -07:00
98f1c1fe87 Remove unused code 2018-10-14 15:36:45 -07:00
50b18a3c10 Integrate Grisu 2018-10-14 14:33:25 -07:00
699297520a Implement Grisu rounding 2018-10-13 11:18:54 -07:00
4bb76ef0c7 Remove redundant definition of print 2018-10-13 11:15:46 -07:00
ddd7caf38e Fix locale-dependent formatting (#905) 2018-10-13 11:15:41 -07:00
10e03e695b use found python executable for launching sphinx-build
there is chance that the distro install python as python3, in that case
the shebang of
```
```
in build.py won't work.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2018-10-13 09:14:53 -07:00
07200f445a find sphinx-build before calling build.py
this allows us to use sphinx-build-3, as user might already in a python3
world, and distros, like fedora 28, tend to add a "-3" suffix to sphinx-build.

Signed-off-by: Kefu Chai <tchaikov@gmail.com>
2018-10-13 09:14:53 -07:00
08a65c2282 Workaround broken constexpr in MSVC2017 2018-10-11 06:38:25 -07:00
167f8fe325 Fix a typo in api.rst 2018-10-10 10:51:43 -07:00
57983423c3 Remove signbit workaround 2018-10-10 09:41:46 -07:00
7bebb3e128 Clarify overload resolution in docs 2018-10-10 09:41:46 -07:00
939fbe5567 Remove basic_fixed_buffer.
Issue #873 indicates that this class is no longer required,
as it has been superseded by a new API.

Fixes #873
2018-10-09 06:51:01 -07:00
61f81a0719 minor documentation corrections
In the Format API section, it says fmt:print writes to a file, but it
writes to a stream as referenced from fopen(3), "stream open
functions". Also in the Safety section a typo; tim should be time.
2018-10-08 06:27:25 -07:00
f27defc639 Parameterize printf functions on the type of the format string.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-08 06:22:04 -07:00
6a685571df Make 'std::*::basic_string_view' a valid argument type for 'format_str' parameters.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-08 06:12:02 -07:00
87a0408c64 Fix ostream.h build 2018-10-07 12:58:20 -07:00
2b5acad4a9 Remove redundant size argument to write_padded 2018-10-07 12:45:34 -07:00
655ce53383 is_format_string -> is_string 2018-10-07 12:45:22 -07:00
fea712abb1 Parameterize ostream functions on the type of the format string.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-07 09:21:14 -07:00
f16a118e88 Fix non-matching char types.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-07 05:56:21 -07:00
041bf83d9b Improve fmt::format readability 2018-10-05 18:42:02 -07:00
2299032392 Document how to write a formatter for a type hierarchy 2018-10-05 13:21:29 -07:00
f5480635c0 visit -> visit_format_arg 2018-10-05 07:15:41 -07:00
cdf3fa08dc Put related code together in fmt/core.h 2018-10-04 19:44:09 -07:00
38325248e5 Count width in code points (#628) 2018-10-03 20:09:46 -07:00
deb901b9e4 Parameterize core functions on the type of the format string.
Take #2 of n

Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-10-03 14:19:08 -07:00
0f98de3011 Update docs 2018-10-03 12:07:55 -07:00
c797708fcc Workaround strlen being non-constexpr in ARM toolchain 2018-10-03 09:23:49 -07:00
49b4c1e9db Update docs 2018-10-02 06:21:19 -07:00
63a87beba4 Add to_string_view 2018-10-01 18:48:18 -07:00
4e0c314654 checked_format_args -> checked_args 2018-10-01 07:14:59 -07:00
c3538a1eee Simplify variadic functions further 2018-09-30 22:19:32 -07:00
2d7d0835d7 Simplify variadic functions 2018-09-30 21:52:47 -07:00
3f4cfa6c60 Implement UTF-8 string support 2018-09-30 15:45:58 -07:00
f8027414f5 Impelement char8_t support 2018-09-30 12:31:25 -07:00
76a47d41c8 Cleanup the use of FMT_CHAR 2018-09-30 08:45:57 -07:00
267fdc7a1b Parameterize core functions on the type of the format string.
Take #1 of n

Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-09-30 08:40:58 -07:00
5bced12421 Parameterize more functions on string type 2018-09-30 08:02:19 -07:00
674999c527 fix vs2017 warning fmt::v5::localtime 'not all control paths return a value'. 2018-09-30 07:23:35 -07:00
e4fea22d15 Make char8_t a strongly-typed enum 2018-09-30 07:11:37 -07:00
66992e90d2 Clarify that writing to memory_buffer appends (#877) 2018-09-28 06:22:12 -07:00
e864acfdbd Fix compilation with intel compilers (ICC/ICPC) v14.0 2018-09-27 07:11:23 -07:00
4cf21f58b2 constrain templated format_to on proper format string type.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-09-26 21:05:47 -07:00
d7f17613f5 Fix compilation on platforms with exotic double (#878) 2018-09-26 08:45:34 -07:00
e4ca37ccf6 Parameterize format_to on string type (#880) 2018-09-25 07:47:15 -07:00
d66fa2216e Reduce syntactic noise 2018-09-23 14:31:14 -07:00
48e6dcd0f2 Implement workarounds for gcc 4.4 2018-09-23 12:29:48 -07:00
0ea3221d34 Remove is_named_arg and add FMT_CHAR 2018-09-23 09:44:01 -07:00
73c53d7833 Parameterize 'printf(rgb color, ...)' and 'vprint_rgb(rgb color, ...)' on the type of the format string.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-09-23 09:15:27 -07:00
d41be23acd Simplify string_view detection 2018-09-23 07:29:35 -07:00
2def9e4c82 Remove FMT_DTOR_NOEXCEPT 2018-09-22 18:51:32 -07:00
ff6e46ed97 More cleanup 2018-09-22 16:00:34 -07:00
715f2b4c00 Remove require_wchar and internalize no_formatter_error 2018-09-21 18:25:24 -07:00
ec0cdc46f6 Workaround Windows slowness 2018-09-21 17:11:57 -07:00
3e75ad9822 Update version 2018-09-21 10:18:51 -07:00
4f043f8e00 Bump version 2018-09-21 10:07:56 -07:00
cc02cbc455 Fix formatting 2018-09-21 09:48:21 -07:00
73c0238e3b Update changelog 2018-09-21 09:48:21 -07:00
cb122a4d03 Fix format_to formatting to wmemory_buffer 2018-09-21 09:48:21 -07:00
dc69cc45d2 Clean tests 2018-09-21 09:48:21 -07:00
9d8021f0d6 Add checks for NVIDIA's CUDA compiler
- Disable templated user-defined literals when compiled under nvcc

Similarly to Intel's C++ compiler, nvcc fails to compile templated UDLs
as they both share the same parsing engine (EDG C++ Front End).  This
fixes building CUDA programs which make use of fmt.
2018-09-21 06:55:45 -07:00
9d2221b954 Improve error message when formatting unknown types 2018-09-20 07:01:39 -07:00
70a6a4bb01 prevent ""fmt/range.h"" from specializing fmt::basic_string_view (#865) 2018-09-19 20:13:05 -07:00
e4fc856c2f Disable android build due to gradle issues 2018-09-19 19:53:47 -07:00
3f4984fb36 Clean core-test and fix linkage errors on older gcc 2018-09-19 12:24:38 -07:00
d43665056d Workaround visit lookup issues in printf.h on gcc 2018-09-19 09:16:26 -07:00
894b6fac8e Changed to use scoped enum
Changed "reusing existing formatters example" to use scoped enum instead.
2018-09-16 17:28:40 -07:00
59f555ad8f Workaround more visit lookup issues on gcc 2018-09-15 08:46:12 -07:00
a7e356cc80 Update README.rst 2018-09-14 07:52:30 -07:00
e758bfbae1 Merge branch 'release' of github.com:fmtlib/fmt 2018-09-13 07:38:23 -07:00
66381e308d Minor cleanup 2018-09-13 07:37:50 -07:00
295a0d84d9 Update version 2018-09-13 07:28:20 -07:00
1fb1c4c912 Update docs 2018-09-13 07:20:43 -07:00
465a593536 Add table support to rst2md 2018-09-13 07:15:18 -07:00
d62f4c3bc1 Formatting 2018-09-12 19:00:26 -07:00
a243490ad7 Add more methods to benchmark results 2018-09-12 18:28:26 -07:00
9e12ca6069 Update changelog 2018-09-12 18:07:29 -07:00
fbca830dd1 Update changelog, readme and improve compat 2018-09-12 12:44:04 -07:00
6146248cf4 Update changelog 2018-09-12 10:42:50 -07:00
bc26fbf1b0 Move experimental color API to fmt/color.h 2018-09-12 09:04:26 -07:00
97cc889374 Workaround a visit lookup issue in gcc 8 (#851) 2018-09-12 08:45:14 -07:00
7110b46076 Optimize default formatting 2018-09-12 08:45:14 -07:00
c8a8464f7d Optimize buffer construction 2018-09-12 08:45:14 -07:00
8cbfb6e727 Get rid of conversion warning in gcc-4.8 (#854)
Get rid of conversion warning in gcc-4.8 

Get rid of the following warning:
conversion to ‘int’ from ‘long unsigned int’ may alter its value [-Werror=conversion]
2018-09-11 06:14:39 -07:00
6ffc828a79 Phasing out null_terminating_iterator 2018-09-10 06:51:38 -07:00
aeb6add336 Skip strchr for the common case 2018-09-09 09:08:41 -07:00
5614289dd8 Optimize and simplify format string parsing 2018-09-09 08:41:27 -07:00
10c7f89351 Optimize format string processing on dumb compilers 2018-09-09 08:13:06 -07:00
59c268a5f8 Use strlen when possible since it's constexpr on gcc 2018-09-08 16:17:22 -07:00
918bb1ce8f Optimize argument capture 2018-09-08 15:29:32 -07:00
a3ba6b4f62 Disable the fmt(...) macro by default (#853) 2018-09-08 09:55:41 -07:00
8671689449 Update docs and formatting 2018-09-08 09:06:54 -07:00
cc10b4607f Make format_to faster on older gcc 2018-09-08 07:22:29 -07:00
981797f059 Get rid of implicit-fallthrough warn. in GCC 7 and 8
This change enables FMT_FALLLTHROUGH also for GCC-Compilers in the versions 7 and 8.
2018-09-07 12:43:32 -07:00
2117775747 Micro-optimize parsing 2018-09-05 07:10:50 -07:00
be0e268468 Optimize processing of trailing '}' 2018-08-31 15:34:31 -07:00
fbc38b9083 Pass heavy arguments by ref 2018-08-31 15:17:18 -07:00
8dc69b9da9 Workaround a bug in Intellisense 2018-08-29 20:40:54 -07:00
1489d3b7fa Implement exponential notation 2018-08-29 18:55:57 -07:00
dd8c5ce442 Implement more FP formatting options 2018-08-29 09:34:57 -07:00
46484da711 Fix a warning 2018-08-29 07:00:24 -07:00
802ff8866e Fix compilation of time.h when localtime_t is a macro (#843) 2018-08-29 06:40:54 -07:00
95a718992c Remove conversion compiler warnings (#844)
* Remove conversion compiler warning

When compiling with g++8, I get the following two errors:
include/fmt/format-inl.h:400:29: error: conversion from ‘int’ to ‘char’ may change value [-Werror=conversion]
       buffer[size++] = zero + static_cast<char>(digit);
                        ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
include/fmt/format-inl.h:416:28: error: conversion from ‘int’ to ‘char’ may change value [-Werror=conversion]
       buffer[size++] = '0' + digit;
                        ~~~~^~~~~~~

With this change, the errors are gone.
2018-08-29 06:38:56 -07:00
e483a01a0f Implement some formatting options in Grisu 2018-08-27 17:51:49 -07:00
f51080916e Revert "Implement some formatting options in Grisu"
This reverts commit 2a952dd0b2.
2018-08-27 17:51:27 -07:00
2a952dd0b2 Implement some formatting options in Grisu 2018-08-26 09:51:49 -07:00
0de44a469a Implement exponent formatting 2018-08-26 08:12:35 -07:00
f0d0a1ebd7 Implement Grisu2 digit generation 2018-08-25 20:45:50 -07:00
569ac91e0b Implement Grisu boundary computation 2018-08-25 11:39:38 -07:00
a11eb3a090 Workaround various icc bugs (#822) 2018-08-22 09:07:17 -07:00
62010520ed Disable gnu-string-literal-operator-template warning 2018-08-22 08:12:59 -07:00
987514761e Make convert_to_int public (#818) 2018-08-22 07:40:06 -07:00
ba95e36a58 Clarify that '\0' cannot be used as fill (#832) 2018-08-19 08:37:40 -07:00
abde38b4fb Add compilation support with Newlib nano for embedded targets
Remove the dependency on std::locale to reduce executable sizes

For embedded target the usage of locale bring a huge amount of code to the executable, just to get hold of the thousands separator. Using a static defined thousands separator makes libfmt embedded target friendly.
2018-08-19 07:40:34 -07:00
18400503da Fix C4127 warning in basic_writer<Range>::write_double 2018-08-17 07:36:38 -07:00
9de312112a Reformat and add a comment 2018-08-15 06:54:43 -07:00
8bbb0b48b4 Update README.rst 2018-08-15 06:34:34 -07:00
5c0101ab2d Use the correct function signature in the docs 2018-08-12 11:34:48 -07:00
fbe6410e53 Fix docs 2018-08-12 08:52:47 -07:00
8b9fb9fb7e Fix ambiguous instantiation with formatter in fmt/ostream.h (#830) 2018-08-11 09:13:54 -07:00
0f04ec68a9 Fix package upload (#828) 2018-08-11 07:57:45 -07:00
809073851f Update changelog 2018-08-11 07:22:41 -07:00
5d02041c59 Update changelog 2018-08-11 07:12:52 -07:00
4b868b8922 Re-enable compile-time format-string checking
Since the commit 691a7a9 compile-time string checking was accidently not possible anymore.
With this change, it should be possible again.
2018-08-07 07:43:47 -07:00
4061a0d35d Parameterize vformat to support custom char types 2018-08-05 10:44:59 -07:00
c68bab7014 Remove broken fmt::internal::format_enum (#818) 2018-08-01 07:11:53 -07:00
0c63d15ee9 Improve wording 2018-07-27 07:37:45 -07:00
ce19309d09 Workaround a bug in icc 15 2018-07-26 07:59:41 -07:00
c684349195 Move contiguous version of format_to to fmt/core.h 2018-07-22 18:09:22 -07:00
8db14efa84 util-test -> core-test and minor cleanup 2018-07-22 17:05:23 -07:00
ffe414cad1 Add compile-time format string checks to format_to (#783) 2018-07-22 15:30:51 -07:00
c178ab440f Remove FMT_USE_RVALUE_REFERENCES 2018-07-22 15:07:53 -07:00
5befe6584d Remove fmt/folly.h and clean up core API 2018-07-22 14:42:25 -07:00
35538ca66c Merge more format overloads 2018-07-22 12:24:47 -07:00
4f16409730 Merge format overloads using SFINAE 2018-07-22 08:06:42 -07:00
2a4e948864 Add UTF-8 types 2018-07-22 06:36:21 -07:00
d778bded95 Make line in tests fit within 80chars 2018-07-20 17:07:23 -07:00
7b4f170c94 Fix warning about using old-style cast 2018-07-20 17:07:23 -07:00
b1d10a2884 Add support for dynamic arg sets
This allows construction of basic_format_args from a dynamic set of arguments. The syntax is a little clunky and could probably be improved but this at least enables the functionality.
2018-07-20 17:07:23 -07:00
cf2719bd12 Add support for types explicitly convertible to wstring_view 2018-07-18 19:12:10 -07:00
50584f42b4 Test formatting of an object with templated conversion to string-like 2018-07-18 16:24:46 -07:00
73bed45b7a Add support for types explicitly convertible to fmt::string_view 2018-07-18 14:42:26 -07:00
6eaa507473 Fix global initialization issue (#807) 2018-07-18 09:49:21 -07:00
48dff9f3c5 Update docs 2018-07-18 06:44:46 -07:00
a9e261599b Minor cleanup 2018-07-17 08:54:22 -07:00
efd8ee8a7f Reduce warnings, support #809 2018-07-16 12:37:54 +02:00
8615ff2acc Micro-optimize argument retrieval 2018-07-15 07:28:31 -07:00
916ed99dab Micro-optimize argument retrieval 2018-07-14 15:28:55 -07:00
e7e9578ed4 Optimize format string parsing 2018-07-14 14:27:56 -07:00
c99a259739 Mark new functions with FMT_API (#808) 2018-07-14 07:43:16 -07:00
e0f6a2f8be Add a formatter for folly::StringPiece 2018-07-14 07:31:47 -07:00
ae4a3945f5 Revert "Better support for newer CMake's"
This reverts commit 0eb01b832c.
2018-07-14 06:34:20 -07:00
a317448bd4 Keep noexcept specifier when exceptions are disabled. 2018-07-13 12:46:15 -07:00
0eb01b832c Better support for newer CMake's 2018-07-11 07:08:17 -07:00
2a4cd6d05e Fix the returned value of format_to_n with user-defined types having operator<<. 2018-07-10 14:01:12 -07:00
9c32e73abf Fixing return unreachable warning on NVCC 2018-07-09 21:33:10 -07:00
e5c93108e6 Added clear() to basic_buffer 2018-07-09 20:25:49 -07:00
60c662b3a7 Add an example of reusing formatters 2018-07-08 15:00:44 -07:00
f66ba6508a Optimize format string parsing 2018-07-08 10:15:24 -07:00
f21268aa72 Revert "Optimize format string parsing" because of a bug in MSVC
https://godbolt.org/g/rpiDgh

This reverts commit f9e9bf0231.
2018-07-08 08:08:50 -07:00
07b690a679 Update README.rst 2018-07-07 18:18:56 -07:00
f9e9bf0231 Optimize format string parsing 2018-07-07 16:50:22 -07:00
c2ce7e4f07 Update version 2018-07-05 06:22:54 -07:00
434eb9167e Update README.rst 2018-07-04 18:07:17 -07:00
09d94162f9 Update changelog 2018-07-04 17:47:46 -07:00
e6362642cf Fix pedantic conversion warning 2018-07-04 17:45:28 -07:00
f0110e8125 Update changelog and CI 2018-07-04 17:43:07 -07:00
479ee2a8c6 Fix MSVC build, take 2 2018-07-04 14:24:07 -07:00
e928b6724c Fix MSVC 2013 build 2018-07-04 12:33:15 -07:00
ec218a3ad1 Fix redefinition warning for RESET_COLOR 2018-07-04 07:52:19 -07:00
c04fb91b03 Fix handling of user-defined types in format_to (#793) 2018-07-04 07:40:56 -07:00
323b92bffe Force linking of inline functions into the library (#795) 2018-07-03 19:10:23 -07:00
c6d9730ddb Fix sign conversion warnings (#790) 2018-06-27 14:31:20 +02:00
2e95823ef7 Move new color support to format.h and mark old as deprecated 2018-06-24 06:39:22 -07:00
ab2d88ca8e Make format_to work with basic_memory_buffer (#776) 2018-06-23 08:29:26 -07:00
3abd036c47 Fix compilation on gcc 4 2018-06-23 07:18:59 -07:00
c2f3805488 Add vformat_to_n (#769) 2018-06-23 07:03:00 -07:00
ce500635c7 Renamed enum color to colors.
Added enum colors conversion to rgb struct.
Added colors_test.cpp.

Removed print_colored.
Renamed enum colors back to color.

Removed unnecessary inline keyword.
Removed print_rgb.
2018-06-23 06:14:44 -07:00
0508bbc7ae Add wchar_t overload of format_to_n (#764) 2018-06-13 08:24:32 +02:00
c2fbadb9cf Fixed issue #779 2018-06-12 07:39:44 +02:00
47268ecd80 Fixed GCC version test 2018-06-10 20:35:38 +02:00
9ff3b6af2e Fix handling of compile-time strings when including ostream.h (#768) 2018-06-10 19:05:27 +02:00
e3707ef14b Document that file should be in wide-oriented mode for wide print 2018-06-09 09:12:49 +02:00
45fa4ee949 Merge branch 'master' of github.com:fmtlib/fmt 2018-06-08 21:43:56 +02:00
9c07b37fff Using enum class now.
Renamed from hex to color.
Changed colr names to snake case.
2018-06-08 21:40:35 +02:00
5b5886a993 Fixed line length. 2018-06-08 19:48:41 +02:00
d2bfee13e2 Added quotes for strings in ranges and tuple likes. 2018-06-08 19:48:41 +02:00
aff6e45e14 Added support for rgb color output. 2018-06-07 22:49:16 +02:00
1b8a7f8fa0 Fix postincrement in truncating and counting iterators 2018-06-07 20:20:36 +02:00
4bc26f0a7b Merge branch 'master' of github.com:fmtlib/fmt 2018-06-07 18:42:30 +02:00
fc6e0fe992 Fix FP formatting to a non-back_insert_iterator with sign & numeric alignment (#756) 2018-06-07 18:41:40 +02:00
cd5b5670ba Make is_range and is_tuple_like public API, fix #751 2018-06-06 21:49:14 +02:00
6322b47e60 Minor cleanup 2018-06-06 16:51:35 +02:00
691a7a91a1 Add more compilers to CI and increase FMT_PEDANTIC warning levels (#736)
* Add a _lot_ more warnings to FMT_PEDANTIC
Fix these warnings

* Add more compilers to CI
Fix (some) of the compiler errors with them

* Enable -Werror on CI
Increase warning level on MSVC when compiling with FMT_PEDANTIC

* Add VS 2013 and 2015 to Appveyor

* Fix Appveyor tests
Formatting

* Implement requested changes
Fix some of the MSVC warnings
Implement C++11 integer_sequence

* Reintroduce appveyor-build.py

* Remove ranges-test from tests

* Remove (some) explicit warning suppressions
Fix C++ standard setting in CI

* Remove (some) explicit warning suppressions
Fix C++ standard setting in CI

* Fix test builds with C++11

* Enable pedantic warnings on tests

* Fix warnings from edits to master

* Cleanups

* Add C++11 support to ranges.h
Re-enable ranges-test
Fix a Visual Studio error about function not returning a value in printf.h
Fix a bug in .travis.yml
2018-06-06 15:57:59 +02:00
dd1a5ef7f9 Let requests close the file 2018-06-05 16:58:02 +02:00
d5c462596b Fix formatting of more than 15 named arguments (#754) 2018-06-05 08:32:28 +02:00
47d147b65d Simplify the nvcc warning fix 2018-06-04 21:27:20 +02:00
911a75114b Fix nvcc warnings (#752) 2018-06-04 21:00:28 +02:00
94b476283c Fix docs 2018-06-04 19:56:22 +02:00
252f11f85d Fix a bogus MSVC warning about unreachable code, take 2 2018-06-04 18:17:55 +02:00
81d5663825 Fix more bogus MSVC warnings about unreachable code (#748) 2018-06-04 06:10:52 +02:00
68f0ac8271 Fix a bogus MSVC warning about unreachable code 2018-06-03 08:03:56 +02:00
b60a5c5d49 Improve floating-point formatting 2018-05-28 20:16:30 -07:00
8dc2360b11 Fix a comment 2018-05-28 17:21:39 -07:00
4e4b8570e5 Implement simple version of Grisu 2018-05-28 11:25:07 -07:00
4027557958 Fix tests on 64-bit MSVC 2018-05-27 11:38:53 -07:00
5c32aa411c Workaround a bug in MSVC 2018-05-27 11:18:27 -07:00
468c243ca8 Add a function to get cached power of 10 2018-05-27 10:57:26 -07:00
2f257b7291 Implement normalization and simplify power table 2018-05-27 08:04:30 -07:00
6a5bb6e268 Move Android.mk to support and update 2018-05-27 06:20:54 -07:00
e282d963fe Bump version 2018-05-26 09:46:59 -07:00
e2cd521b8f Fix incorrect call to on_align in '{:}=' (#750) 2018-05-26 09:23:09 -07:00
fba352a92a Don't use UDL templates on Intel C++ compiler (#742) 2018-05-26 08:07:45 -07:00
6dcc526d5b Update release script 2018-05-26 07:02:49 -07:00
5386f1df20 Update version 2018-05-21 21:00:04 -07:00
ba6640b257 Fix formatting 2018-05-21 20:50:23 -07:00
507a50c3ad Fix changelog 2018-05-21 20:38:07 -07:00
147807c911 Detect integer_sequence support on MSVC 2018-05-21 20:30:58 -07:00
8b246531e6 Update changelog 2018-05-21 20:27:58 -07:00
5ad54256c5 Fix a conflict between fmt::join and fmt/ostream.h (#744) 2018-05-21 20:21:06 -07:00
6ebc1a967d Merge locale.h into format-inl.h 2018-05-20 17:16:34 -07:00
6966db1dab Update docs 2018-05-20 17:10:34 -07:00
2196025dd1 Fix a warning 2018-05-20 17:09:12 -07:00
589f5f37b6 Update changelog 2018-05-20 16:00:39 -07:00
edd5f1445d Fix compilation errors on gcc 4.4 2018-05-20 09:09:03 -07:00
936aba5f90 Fix compilation errors on gcc 4.4 2018-05-20 07:42:09 -07:00
3e3a27740e Update changelog 2018-05-19 11:46:55 -07:00
b76bb79613 Improve naming consistency 2018-05-19 10:32:53 -07:00
fbd5153487 Update changelog 2018-05-19 10:31:49 -07:00
69823bf852 Improve naming consistency 2018-05-19 08:59:37 -07:00
d940fa679c Disable unsafe implicit conversion to std::string (#729) 2018-05-19 07:14:27 -07:00
d2bf93fe22 Update changelog 2018-05-19 07:13:06 -07:00
550ef1d29d MSVC improvements and data truncation cleanup.
MSVC is timid about evaluating constexpr functions unless it has to, so the "TYPES" variables end up in read-write memory even though the optimizer removes the initializer. Making TYPES constexpr causes MSVC to try harder to initialize these variables at compile time, which also ends up completely removing the (named) variable from the final compiled binary.
Fixed a data truncation warning being reported in ostream-test.
2018-05-17 18:46:31 -07:00
728e4f5a8d Fix docs 2018-05-16 08:26:55 -07:00
8c2557710d Update docs and changelog 2018-05-16 07:58:53 -07:00
a68fd44ecc Add ranges.h to FMT_HEADERS in CMakeLists.txt (#738) 2018-05-14 06:16:30 -06:00
e3f7f3a2e9 Add support for ranges, containers and tuple-like types in fmt/ranges.h 2018-05-13 13:28:11 -07:00
984232db15 Remove duplicate ChangeLog entries 2018-05-13 13:14:28 -07:00
78677e3fcf Update ChangeLog and docs 2018-05-13 12:42:55 -07:00
ad23270ec7 Document to_wstring 2018-05-13 09:11:29 -07:00
3c0f8c2601 Update ChangeLog 2018-05-13 08:53:16 -07:00
989378930a Detect inline namespaces on gcc 2018-05-13 08:53:04 -07:00
dfb6546932 Fix docs 2018-05-13 08:04:39 -07:00
3aa2911579 Update ChangeLog.rst 2018-05-13 08:02:06 -07:00
d3f6c841c1 Update ChangeLog.rst 2018-05-13 07:22:41 -07:00
c1441ae4c4 Update ChangeLog.rst 2018-05-12 16:02:20 -07:00
dece85b31f Fix docs, take 2 2018-05-12 13:57:56 -07:00
6a1df3bd05 Fix docs 2018-05-12 12:57:16 -07:00
838400d29b Add inline namespace fmt::v5 2018-05-12 11:02:15 -07:00
b64b24ebc5 Update ChangeLog.rst 2018-05-12 09:42:59 -07:00
fc9087114f Update ChangeLog.rst 2018-05-12 09:10:11 -07:00
46c374a8a9 Fix compilation with new gcc and -std=c++11 (#734) 2018-05-09 20:58:05 -07:00
f0ae725721 Clarify the use of allocators 2018-05-09 06:43:54 -07:00
d72d046254 Update paths in fmt.pro 2018-05-09 06:21:00 -07:00
edbbf7ce6c Fix FreeBSD 12
FreeBSD 12 changed the type of freelocale to the type defined by
POSIX. Check the FreeBSD version when building for FreeBSD.
2018-05-09 06:10:37 -07:00
a4e4f74530 Fix a -Wundef when FMT_GCC_VERSION < 600 2018-05-09 06:09:25 -07:00
7d3de49715 Implement double to fp conversion 2018-05-06 13:37:49 -07:00
a4c7d99f70 Add bit_cast 2018-05-06 11:52:51 -07:00
0adccaefb6 Fix a -Wundef of _LIBCPP_VERSION 2018-05-05 07:43:22 -07:00
2570f1afdc Provide more overloads for the wide string flavour
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-05-05 07:31:44 -07:00
ca31ca13f1 Fixed arg_formatter_base::write_pointer to not mutate the format specs.
This fixes cases where arg_formatters are reused, like with arg_join.
2018-05-01 07:12:27 -07:00
6cd666100f remove trailing spaces.
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-05-01 07:10:05 -07:00
fe19c266ce Move format_string to fmt namespace for ADL 2018-04-29 08:35:20 -07:00
2768af2388 Add cached powers of 10 2018-04-29 06:33:05 -07:00
dd296e1de0 Add a script to compute powers of 10 2018-04-28 14:32:05 -07:00
0efc8a1808 Fix compiler warning about narrowing
Signed-off-by: Daniela Engert <dani@ngrt.de>
2018-04-27 06:41:43 -07:00
df1ba52b64 Update example 2018-04-22 17:04:28 -07:00
221b08fd8f Merge branch 'master' of github.com:fmtlib/fmt 2018-04-22 09:16:34 -07:00
fa9066fe3e context_base::begin -> out 2018-04-22 09:16:32 -07:00
90ff31b38e Fix a -Wundef warning on clang
Resolves #715
2018-04-22 09:13:55 -07:00
b1f68c43b5 Merge branch 'master' of github.com:fmtlib/fmt 2018-04-21 19:21:41 -07:00
cd90097ca4 Implement handmade FP 2018-04-21 17:26:24 -07:00
822eccc3b8 Sync API with standards proposal 2018-04-21 14:29:24 -07:00
2ae41242a5 allow time formatting with wchar_t contexts
change total specialization of 'struct formatter<std::tm>' into partial specialization 'template <typename Char> struct formatter<std::tm, Char>', backed by matching 'strftime'-like overloads
2018-04-18 18:55:49 -07:00
a1579b0ff8 Update key 2018-04-16 18:22:03 -07:00
ded921f0a2 Fix documentation build, take 2 2018-04-15 10:34:04 -07:00
3284751f43 Fix documentation build 2018-04-15 09:49:37 -07:00
bb738c4c26 Remove section on Write API since it's being superceeded by compile-time Format API 2018-04-15 09:13:44 -07:00
d180c25c8f Update godbolt link 2018-04-15 06:19:38 -07:00
1ed842a3b4 Update godbolt link 2018-04-14 12:41:08 -07:00
e80aba1c2b Remove format_float stub 2018-04-14 12:40:53 -07:00
7b8cb3135a Make context_base::args() public 2018-04-14 12:40:26 -07:00
48ae0506de fixes MSVC compiler warning bloat (Visual Studio 2017, latest updates) 2018-04-11 06:53:27 -07:00
096c4051b2 Simplify char_traits 2018-04-08 13:38:12 -07:00
7610c5362a Remove unused macro 2018-04-08 11:54:22 -07:00
111fa5814b Update README.rst 2018-04-08 09:03:37 -07:00
52fcef1e57 Update docs 2018-04-08 07:33:07 -07:00
7d28674d3a make_args -> make_format_args 2018-04-08 07:21:26 -07:00
9382b76f2a context_t -> format_context_t 2018-04-08 07:09:34 -07:00
fd0b07a75a (w)context -> (w)format_context 2018-04-08 07:03:44 -07:00
26aa34f319 basic_context -> basic_format_context 2018-04-08 06:45:21 -07:00
44cc034651 Relax string_view requirements 2018-04-07 16:18:01 -07:00
0829cab8f2 Remove from_checked 2018-04-07 15:21:48 -07:00
cb7bbc6224 Improve checked iterator support 2018-04-07 15:11:34 -07:00
5079f924d6 Fix a narrowing warning 2018-04-07 14:42:09 -07:00
5859e58ba1 Fix msvc warnings 2018-04-04 21:11:31 -07:00
1e747f603f Fix msvc warnings 2018-04-04 20:57:02 -07:00
9d4efd7aa2 Iterator Wars VI: Return of the checked iterator 2018-04-04 20:15:02 -07:00
9764f55891 Update docs 2018-04-04 07:53:19 -07:00
4ef97b9bb2 Add a missing comma 2018-04-04 07:43:51 -07:00
23759b2688 basic_arg -> basic_format_arg, arg_store -> format_arg_store 2018-04-04 07:38:21 -07:00
4975297eb0 Simplify counting iterators 2018-03-31 07:47:30 -10:00
e8e006f4e7 Fix compile checks for mixing narrow and wide strings (#690) 2018-03-30 09:29:47 -10:00
c5ebecf7c6 Document format_to_n 2018-03-30 08:31:41 -10:00
3cf0526316 Return output iterator to the end from format_to_n 2018-03-30 08:20:12 -10:00
174087bfdb Implement format_to_n 2018-03-29 15:13:10 -10:00
050f3f1f0e Remove parts of obsolete write API 2018-03-29 07:36:37 -10:00
e90b1da367 Fix linker errors using fmt as shared library in MSVC 2018-03-28 07:14:56 -10:00
8e10d404db Fix compile tests 2018-03-27 07:39:03 -10:00
7a41d61d79 Add make_printf_args
Fixes #687
2018-03-27 07:15:51 -10:00
4fea018b2d Fix string_view detection 2018-03-26 07:00:41 -10:00
6957d28cfb Detect string_view on libc++ (#686) 2018-03-26 06:50:22 -10:00
0ea70defbe Update readme 2018-03-21 09:25:28 -07:00
9ce5e30c06 Update readme 2018-03-21 09:15:28 -07:00
8c29459eda Fix handling of empty string_view (#689) 2018-03-21 09:01:51 -07:00
a24005d5fd Fix a narrowing warning 2018-03-21 08:29:06 -07:00
3651b7fca6 Fix a narrowing warning 2018-03-21 07:59:42 -07:00
b64486dae9 Add format.cc 2018-03-21 07:51:56 -07:00
3da71d51e0 Move source files to the src directory 2018-03-21 07:50:59 -07:00
7971ed3db3 Update readme 2018-03-21 06:48:36 -07:00
f61ca2ec4f Update readme 2018-03-21 06:46:41 -07:00
84e520b79c Update readme 2018-03-21 06:16:13 -07:00
e8aa0f3315 Update docs 2018-03-21 06:12:10 -07:00
17258e9c63 Update docs 2018-03-19 19:47:14 -07:00
6d339e32a0 Improve comment 2018-03-16 16:26:31 -04:00
c3d05245fe Fix a shadowing warning 2018-03-16 16:26:11 -04:00
b58c8ddeb4 Update docs 2018-03-16 16:04:12 -04:00
505b3ae66f Workaround GCC bug 67371 (#682) 2018-03-16 12:02:19 -04:00
70dffc639a Remove unnecessary check 2018-03-15 09:58:26 -04:00
df828f88da Don't define FMT_GCC_VERSION on clang 2018-03-15 09:55:31 -04:00
42f70c8b4f Avoid narrowing casts 2018-03-15 09:45:31 -04:00
10b939b096 Remove unneeded usage of anonymous struct on clang 2018-03-15 09:28:50 -04:00
3adfaae20c Remove extra semicolon in format_args constructor 2018-03-15 09:28:50 -04:00
4006678577 Fix warnings under MSVC (#679)
Closes #678.
2018-03-14 20:17:15 +01:00
9c5f54a723 Add format example for padded hex byte
Fixes #2
2018-03-13 23:05:48 -04:00
7bab90e52d Remove extra comma 2018-03-13 22:45:14 -04:00
2e21e7d1f1 Fix util-test 2018-03-13 22:20:06 -04:00
acb469ae2e Fixed UTF8/16 converters to support empty string input
Previously an exception was thrown since Win32 WideCharToMultiByte API
returns error on zero-length input.
2018-03-13 21:33:21 -04:00
c37c4c437e Fix find-package-test 2018-03-13 14:13:39 -04:00
6d21fc43b9 add alias targets with fmt namespace
For the consumer it should not matter if fmt has been added to the
project as subdirectory or via find_package. With the alias targets
the library can be always imported via fmt::fmt.
2018-03-13 13:51:48 -04:00
e02aacc634 Add CMake namespace (#511) 2018-03-13 13:03:18 -04:00
aee4512cc5 Gradle (#649)
* Gradle

Gradle support to make ease of import in Android Java projects.

* Gradle

Gradle support for Android projects.
For command line build, `gradle assembe` will trigger build phase

 - Config for Android .so file generation
 - Commented build.gradle
 - Automatic file copy after build
 - Dummy AndroidManifest file

* Build with Gradle

 - Build job for Travis CI
 - Moved gradle file to support/

* Gradle Path

 - Absolute path for Gradle binary

* File check after Gradle build

 - Additional script for build success
 - Check the Gradle's `assemble.doLast` task
2018-03-12 15:40:25 -04:00
7db0e94b9e Fix handling of numeric alignment with no width (#675) 2018-03-11 21:04:42 -04:00
9facc119a6 Update docs 2018-03-10 09:44:37 -08:00
a1d187113b Merge branch 'master' of github.com:fmtlib/fmt 2018-03-10 06:46:51 -08:00
daf650c49a Disallow formatting of multibyte strings into a wide buffer (#606) 2018-03-10 06:46:41 -08:00
8fd7e30f37 Update README.rst 2018-03-09 15:44:46 -08:00
ca93be130a Use fmt(s) as an alias for FMT_STRING(s) 2018-03-09 15:40:40 -08:00
80e57c7a3d Update to new naming conventions 2018-03-07 07:36:13 -08:00
ae3cc844e7 Check format string at compile time in print 2018-03-07 05:41:45 -08:00
585512fc7c Remove unnecessary instantiations 2018-03-04 15:14:02 -08:00
7755cdc199 Make symbols readable 2018-03-04 15:00:22 -08:00
f867d08239 Update docs 2018-03-04 12:09:34 -08:00
a103b9bc46 Workaround missed optimization in gcc (#668) 2018-03-04 11:45:20 -08:00
bb47109a78 Cleanup 2018-03-04 11:25:40 -08:00
f1ede6380b Make inline_buffer_size public and update docs 2018-03-04 10:33:42 -08:00
995b63adfe Update copyright 2018-03-04 10:11:44 -08:00
4023291759 Update docs 2018-03-04 09:55:17 -08:00
86a9bc8291 Cleanup 2018-03-04 09:16:51 -08:00
b7632e9641 Make format_to return iterator and update docs 2018-03-04 08:13:08 -08:00
5281ea6ad2 do_vformat_to -> vformat_to and update docs 2018-03-04 06:40:43 -08:00
d07ba49821 Fix docs 2018-03-03 22:12:23 -08:00
418659adbe Fix compilation errors on gcc 4.4 2018-03-03 14:04:59 -08:00
1d2adef28d Fix compilation errors on gcc 4.4 2018-03-01 03:45:25 -08:00
45518c3fe1 Fix compilation errors on gcc 4.4 2018-02-28 07:47:24 -08:00
698d909706 Workaround a bug in gcc 5.1 2018-02-28 06:14:56 -08:00
81074c7048 Fix more compilation errors on gcc 4.6 2018-02-28 05:23:25 -08:00
1b4525384b Fix more compilation errors on gcc 4.6 2018-02-28 05:09:24 -08:00
6090e51b65 Fix compilation errors on gcc 4.6 2018-02-28 04:49:20 -08:00
0827ec5aa9 Fix compilation errors on gcc 4.6 2018-02-28 04:33:43 -08:00
4d35f94133 Always use fallback string_view to pass format string (#664) 2018-02-24 18:19:30 +00:00
34cf54c2fc Update README.rst 2018-02-24 09:37:17 +00:00
0565d65461 Fix gcc 7.2 issue 2018-02-24 09:29:15 +00:00
f5dc0ed342 Break long lines 2018-02-24 08:39:17 +00:00
ea06f021f8 test: comment out one FormatStringErrors constexpr test
GCC 7.3 complains that this is not a compile time constant.

test/format-test.cc: In member function ‘virtual void FormatTest_FormatStringErrors_Test::TestBody()’:
test/format-test.cc:1919:3: error: non-constant condition for static assertion
   static_assert(test_error<__VA_ARGS__>(fmt, error), "")
   ^
test/format-test.cc:1924:3: note: in expansion of macro ‘EXPECT_ERROR’
   EXPECT_ERROR("{0:s", "unknown format specifier", Date);
   ^~~~~~~~~~~~
2018-02-24 08:20:20 +00:00
5b49177352 test: Initialize some local variables
GCC 7.3 complains about uninitialized varaibles in constexpr context.
2018-02-24 08:20:20 +00:00
f45f70af09 Use trailing return type instead of deduction
C++11 does not support deduction of return type.
2018-02-24 08:20:20 +00:00
db86e8d5d3 Remove a couple of unused argument names 2018-02-24 08:20:20 +00:00
55f5c9f21b Use FMT_NULL instead of 0 is a few more places.
Found with GCC and -Wzero-as-null-pointer-constant
2018-02-24 08:20:20 +00:00
e92ba1071d Fix Python str.format link to point to Python 3 docs 2018-02-20 17:40:49 +00:00
a7ae5666a0 Enable join on msvc 2018-02-19 21:03:51 +00:00
24d249b0b4 Fix formatting of objects convertible to string_view 2018-02-19 20:25:56 +00:00
e508e30800 Don't define FMT_LOCALE on OpenBSD
OpenBSD doesn't have strtod_l() (at least under the default
headers), so the class Locale that the macro gates won't compile.
2018-02-19 19:24:33 +00:00
0ee4273b04 Put is_enum check first not to instantiate convert_to_int unnecessarily 2018-02-18 05:47:29 +00:00
8ca3ab2c4c Revert problematic pragma 2018-02-18 05:38:32 +00:00
18ac98700e Fix formatting of objects convertible to std::string 2018-02-17 12:57:18 +00:00
ce4a65ffea Add pointer support to basic_writer 2018-02-17 09:38:46 +00:00
91721caa42 Add detection of wostream operator<< (#650) 2018-02-17 09:03:43 +00:00
1efc15c177 Fix MSVC build 2018-02-16 18:13:54 +00:00
8ed264fcd4 Rename type enum constants to prevent collision with poorly written C libs (#644) 2018-02-16 17:20:33 +00:00
4ba3f7db82 Update docs 2018-02-15 18:52:44 -08:00
7d2723d57c posix.cc: Fix compilation with -fno-exceptions
Signed-off-by: Andrew Gunnerson <andrewgunnerson@gmail.com>
2018-02-15 18:39:36 -08:00
24d66c5d65 compilation fix & warnings 2018-02-15 18:37:45 -08:00
229887bd40 Make constexpr remove_prefix gcc version check tighter (#648) 2018-02-14 05:46:41 -08:00
f3f19e762f Update docs 2018-02-11 13:43:16 -08:00
e9fa42acb8 Fix docs and build issues on gcc-4.6 2018-02-11 09:43:54 -08:00
affb35cfb9 Replace using with typedef for compatibility with gcc-4.6 2018-02-11 09:23:47 -08:00
9710c058aa Update documentation building script 2018-02-11 09:23:17 -08:00
1a4e892765 Move output_range to format.h 2018-02-11 08:36:44 -08:00
522de7b55d Replace using with typedef for compatibility with gcc-4.6 2018-02-11 08:32:02 -08:00
0b508fd29d Fix c++0x detection 2018-02-11 07:32:22 -08:00
1849735f12 Fallback to c++11 if c++14 not available 2018-02-11 07:25:53 -08:00
3239c51814 Get rid of generic lambdas 2018-02-11 07:05:14 -08:00
78166ccd36 Get rid of generic lambdas 2018-02-11 06:50:56 -08:00
d8ef8a9e9b Cleanup 2018-02-11 06:24:22 -08:00
822222181b Update README.rst 2018-02-10 07:45:32 -08:00
b00053247c Merge the std branch 2018-02-10 07:38:27 -08:00
a502decddb Added a fmt.pro to support build using qmake (#641) 2018-02-10 07:22:02 -08:00
61065e1a5c Fix unreachable code warning when signbit returns bool 2018-02-10 07:21:17 -08:00
403ae0a23b Add debug postfix for libfmt (#636) 2018-02-10 07:17:40 -08:00
5096c0fe97 Fix string_view detection 2018-02-10 07:17:29 -08:00
5b3f9eab94 Update syntax.rst 2018-02-10 07:03:44 -08:00
e802cf14e3 Add note about errno to the documentation 2018-02-10 07:01:59 -08:00
c96d64652b CMakeLists: Use GNUInstallDirs to set install location 2018-02-10 07:00:14 -08:00
dbd84697ff Update usage.rst 2018-02-10 06:54:26 -08:00
5013c15737 Silence MSVC 2017 constant if expression warning 2018-02-10 06:52:46 -08:00
cdfcee27fb Use allocator_traits if available 2018-02-10 06:51:13 -08:00
66b25ef0d0 Add examples 2018-02-10 06:33:03 -08:00
6cb68f9496 Fix warnings 2018-02-10 06:28:43 -08:00
0b635c9dc5 Fix handling of fixed enums in clang (#580) 2018-02-10 06:17:42 -08:00
66afd9b33a Fix compilation on gcc 6 2018-02-10 05:16:16 -08:00
67e070fe5a Make format work with C++17 std::string_view (#571) 2018-02-07 08:14:54 -08:00
64599973e9 Enable stream exceptions (#581) 2018-02-07 07:36:15 -08:00
35f8f03670 Use less version 2.6.1 and sudo to fix npm install issues on travis 2018-02-07 07:17:34 -08:00
92a250fdb6 Suppress Clang's warning on zero as a null pointer 2018-02-07 07:16:00 -08:00
2f13d41e30 Add to_wstring 2018-02-07 07:08:14 -08:00
1e19ae8348 Workaround a bug in MSVC 2018-02-07 06:31:42 -08:00
3810d7e4d4 Workaround a bug in MSVC 2018-02-04 09:29:50 -08:00
5c7474e1fb Relax constexpr requirements 2018-02-04 08:58:21 -08:00
1f57243b49 Relax constexpr requirements 2018-02-04 08:52:43 -08:00
dc5403612e Conditionally compile constexpr 2018-02-04 08:21:31 -08:00
5d8ba816de Fix a segfault in test on glibc 2.26 #551 2018-02-02 19:34:08 -08:00
a9f810c188 Update README.rst 2018-02-02 19:17:19 -08:00
2582f41e12 Fix ifdefs 2018-02-02 19:16:13 -08:00
1a7d0ba2d0 Adding OpenSpace to the list of projects 2018-02-02 19:10:25 -08:00
8921f613de Update build script 2018-02-02 18:46:39 -08:00
f62e225e82 Automatically update version in release script (#431) 2018-02-02 18:45:05 -08:00
94806747df remove 'FMT_CPPFORMAT' CMake option 2018-02-02 18:42:22 -08:00
bfce29ffef Improve conversion 2018-02-02 18:40:36 -08:00
f164e4c72f Remove old bcc-related comments 2018-02-01 16:49:47 -08:00
c57029c1f0 Add Drake & Lyft Envoy to the list of projects 2018-02-01 16:46:41 -08:00
8fa9acb8e5 Workaround broken __builtin_clz in clang with MS codegen (#519) 2018-02-01 16:43:16 -08:00
3dae25828f Describe cmake use of header-only target 2018-02-01 16:42:53 -08:00
1c7b751d70 Fix handling of implicit conversion to integral types larger than int 2018-02-01 16:42:15 -08:00
08dff3774c Allow compiling and using as DLL in windows #502 2018-01-28 20:50:43 -08:00
c753a2af39 Don't include the world with WIN32_LEAN_AND_MEAN (#503) 2018-01-28 20:26:25 -08:00
a5185ec8d4 add SOURCELINK_SUFFIX for compatibility with Sphinx 1.5 2018-01-28 20:20:39 -08:00
768061c85e Fix FormatBuf implementation (#491) 2018-01-28 20:08:51 -08:00
0c136381e3 Move back_insert_range to format.h 2018-01-27 18:56:50 -08:00
5060568f72 %.f should have zero precision, not default precision 2018-01-27 17:56:19 -08:00
a09f748894 Add Kodi (xbmc) to the list of projects using fmt 2018-01-27 17:47:41 -08:00
f9fa7c405f Add FMT_API and FMT_OVERRIDE where needed 2018-01-27 17:15:14 -08:00
a980d3b46b Add fmt::join to format ranges (#466) 2018-01-27 16:04:45 -08:00
87eab90ea8 Fix missing intrinsic when included from C++/CLI (#457) 2018-01-27 09:25:15 -08:00
75005bbcd5 Don't export the -std=c++11 flag from the fmt target 2018-01-27 09:18:20 -08:00
19f990a9c0 Use https to fetch dependencies from github 2018-01-27 09:15:28 -08:00
bca9de9e68 Return iterator from format_to 2018-01-27 07:03:26 -08:00
a93270fd60 Replace a bunch of craft with type_traits, take 2 2018-01-22 18:56:53 -08:00
21429c8646 Revert "Replace a bunch of craft with type_traits"
This reverts commit e79588d6c1.
2018-01-21 18:53:38 -08:00
0473c48f88 Add std::basic_string allocator support (#441) 2018-01-21 18:21:16 -08:00
72d9fffd78 Fix test compilation for FreeBSD (#433) 2018-01-21 18:18:05 -08:00
e79588d6c1 Replace a bunch of craft with type_traits 2018-01-21 18:11:57 -08:00
3a6c7d0cbd Fix signbit detection (#423) 2018-01-21 16:41:55 -08:00
5e4c34b25a Add version macro FMT_VERSION (#411) 2018-01-21 16:36:22 -08:00
bd8a7e7ea1 More iteratification 2018-01-21 14:30:38 -08:00
0a402056bc Add CONTRIBUTING.rst 2018-01-20 19:52:19 -08:00
e35d41fff5 Add extern templates for format_float (#413) 2018-01-20 19:17:59 -08:00
d8c25a175a Use nullptr if available 2018-01-20 19:11:19 -08:00
e95e4659d9 Add syntax.rst to build 2018-01-20 17:55:43 -08:00
e51119508c argument index -> argument id 2018-01-20 17:55:28 -08:00
229ee34eea Fix compiler warnings 2018-01-20 17:54:06 -08:00
7fe0f3dabc Update ChangeLog 2018-01-20 17:39:15 -08:00
38b603a42f Update README.rst 2018-01-20 17:12:43 -08:00
a1e7e4a768 Fix compilation with -fno-exceptions (#402, #405) 2018-01-20 17:10:14 -08:00
3f24a38840 Thread-safe time formatting (#396) 2018-01-20 11:35:23 -08:00
f853d94a15 Remove unnecessary fmt/ prefix (#397) 2018-01-20 10:28:10 -08:00
9649919d01 Document use of format_arg for user-defined type #393 2018-01-20 10:07:29 -08:00
c8efe145b4 Add api.rst to build 2018-01-20 09:52:29 -08:00
da80005f11 Fix compilation on Cygwin (#388) 2018-01-20 09:52:03 -08:00
8ed163533c Fix a typo 2018-01-20 09:43:56 -08:00
72606f2391 Add missing types to counting_iterator 2018-01-20 08:20:18 -08:00
64b349aee2 More iterator support & fmt::count 2018-01-17 22:04:24 -08:00
e3b69efbe1 Suppress msvc warnings in gmock 2018-01-17 05:46:14 -08:00
322736d3bb Add support for arbitrary output iterators 2018-01-15 12:46:44 -08:00
1029119497 Cleanup 2018-01-15 11:37:39 -08:00
c1d137ed5f Add support for nonconiguous iterators 2018-01-15 11:30:53 -08:00
f6fd38bb3a More iterator support 2018-01-15 08:48:37 -08:00
c2fecb9b2a Clean API 2018-01-14 14:15:59 -08:00
9a53a706fc Add support for back_insert_iterator 2018-01-14 13:12:26 -08:00
91ee9c9acd Return iterator from the format method 2018-01-14 11:00:27 -08:00
67928eae28 Don't inherit context from parse_context 2018-01-14 09:27:40 -08:00
217e7c76f1 Pass ranges by value 2018-01-14 08:13:48 -08:00
22994c62f7 Decouple arg_formatter_base from buffer 2018-01-13 15:34:48 -08:00
00f1450d9a Update tesmplate parameter names 2018-01-13 14:57:43 -08:00
3a2e89e134 Reduce dependency on buffer 2018-01-13 12:57:27 -08:00
cea3c20747 Give a better error message for function pointers (#633) 2018-01-13 07:02:45 -08:00
232ceabbc3 Workaround an internal compiler error in MSVC 2018-01-13 06:43:03 -08:00
c095445394 Replace buffer with range 2018-01-10 22:41:23 -08:00
c3d6c5fc4c Replace buffer with range 2017-12-30 07:42:56 -08:00
d165d9c483 Decouple locale and buffer 2017-12-26 17:22:07 -08:00
3663414053 Parameterize basic_writer on buffer type 2017-12-26 09:00:22 -08:00
6f2769d0b4 Revert "Added support for format string containing '\0' in _format udl (#619) (#620)"
This reverts commit 3aaa25fa70 for
reasons discussed in #622.
2017-12-23 08:00:51 -08:00
5f1c73db7d Shorten a comment in locale.h 2017-12-23 08:00:38 -08:00
941663d038 Merge ostream.cc into ostream.h 2017-12-17 09:33:56 -08:00
955062da2e Merge printf.cc into printf.h 2017-12-17 08:36:19 -08:00
ccaae0c019 Refer to jeaiii project 2017-12-10 16:09:35 -08:00
e37151021e Add a integer formatter based on jeaiii 2017-12-10 16:05:51 -08:00
b3495f2e4b Update README.rst 2017-12-10 06:54:51 -08:00
61f296e30c Move FMT_HAS_BUILTIN to format.h 2017-12-09 08:56:44 -08:00
ce801c9095 Remove dependency on <vector> and <array> 2017-12-09 08:48:30 -08:00
41fc29907a Merge branch 'std' of github.com:fmtlib/fmt into std 2017-12-09 08:16:34 -08:00
971fb584c3 Allow mixing named and automatic arguments 2017-12-09 08:15:13 -08:00
af0f21da0f add missing inline in header-only mode (#626) 2017-12-09 07:50:53 -08:00
7cea163809 numeric -> arithmetic 2017-12-09 06:19:15 -08:00
5328907f7f Get rid of <limits> dependency 2017-12-06 09:18:17 -08:00
faaafc7e12 Remove <utility> dependency and replace typedefs with using 2017-12-06 09:13:23 -08:00
94edb1a71c Add a lightweight header for the core API 2017-12-06 07:42:42 -08:00
3aaa25fa70 Added support for format string containing '\0' in _format udl (#619) (#620)
Added support for strings containing '\0' in udl (#619)
2017-12-06 06:21:34 -08:00
84bd2f1962 Merge include/fmt/CMakeLists.txt into the main CMake file 2017-12-03 09:59:55 -08:00
7f351dec27 Decouple <locale> for better compile times 2017-12-03 09:51:59 -08:00
81bd9e8ea3 args -> format_args 2017-12-03 08:00:22 -08:00
10e70a06c9 Improve handling of custom arguments 2017-12-02 09:44:48 -08:00
e0243000de arg_index -> arg_id 2017-11-26 10:05:49 -08:00
ac5f95208c Automatically add package to release 2017-11-25 08:23:13 -08:00
0e914372fb Avoid conflict with the macro CHAR_WIDTH
It looks like CHAR_WIDTH is a macro in glibc. See
https://sourceware.org/ml/libc-alpha/2016-09/msg00225.html
2017-11-25 07:25:06 -08:00
f03a35a679 Check string specs at compile time 2017-11-24 09:54:28 -08:00
e9da574147 Check char specs at compile time 2017-11-24 07:54:22 -08:00
b25a029284 Check pointer type specs are compile time 2017-11-23 10:12:23 -08:00
c8a9d902dd Check floating-point type specifiers 2017-11-23 09:14:37 -08:00
6570dc3122 Disallow formatting of multibyte strings into a wide buffer (#606) 2017-11-23 07:23:07 -08:00
3851994ab0 Fix yet another internal compiler error in MSVC 2017-11-19 09:06:49 -08:00
44e186512b Refactor parse context and fix warnings 2017-11-19 08:49:58 -08:00
e7e270f511 Test error on invalid type spec and remove unused alias 2017-11-19 08:25:34 -08:00
692b82d32c UdlArg -> udl_arg 2017-11-19 08:02:07 -08:00
c523dd584f Use error handler to report errors 2017-11-19 07:36:01 -08:00
5a32e64b05 More tests 2017-11-19 07:03:12 -08:00
093e2a4780 Improve error handling 2017-11-18 09:16:35 -08:00
dc104cbaaa Workaround internal compiler errors in MSVC 2017-11-18 09:05:05 -08:00
39411504a5 More tests 2017-11-18 08:16:59 -08:00
e3eb5ea074 Add parse_context::error_handler() 2017-11-18 06:58:14 -08:00
734e722da4 Fix warnings 2017-11-18 06:56:29 -08:00
62af25dca8 Workaround yet another MSVC internal error 2017-11-18 06:31:47 -08:00
594bd8feba More tests 2017-11-16 06:55:49 -08:00
f2b52bba05 More tests 2017-11-15 07:06:03 -08:00
dfdb1adea5 More tests 2017-11-12 10:03:39 -08:00
7967c2f874 Disable test that triggers an MSVC bug 2017-11-12 09:47:15 -08:00
18a0b94b0e Fix overflow check 2017-11-12 09:25:28 -08:00
686ff942af Fix compile-time parsing and add more tests 2017-11-11 11:40:56 -08:00
5b95b5d77c Test compile-time errors 2017-11-11 10:28:05 -08:00
246bdafc74 Add FMT_STRING macro for compile-time strings 2017-11-11 07:39:12 -08:00
e805543341 Remove FMT_USE_VARIADIC_TEMPLATES 2017-11-11 07:02:58 -08:00
dba1ccc4d7 Update readme 2017-11-10 07:38:51 -08:00
e613b3c7b1 Update readme 2017-11-10 07:24:16 -08:00
9fda7a36fd Check integral type specs at compile time 2017-11-08 07:58:09 -08:00
92847a0d11 Add integral type handler 2017-11-08 05:56:52 -08:00
a03842b0d5 More compile-time checks 2017-11-05 13:26:19 -08:00
1c855a4762 Integrate constexpr format specs parsing 2017-11-05 09:28:50 -08:00
780b44bf82 Add compile-time format string check 2017-11-04 09:02:47 -07:00
8ca6e76dbc Detect user-defined literal templates 2017-11-04 08:23:24 -07:00
a7e986166a Workaround another MSVC madness 2017-10-29 08:19:55 -07:00
db9ffa1405 Make parse_format_string constexpr 2017-10-29 07:32:14 -07:00
e926ae78ac Add parse_format_string 2017-10-29 07:00:47 -07:00
57e266ab1d Rename handlers 2017-10-27 06:44:00 -07:00
d29c7c3aca Workaround a bug in MSVC 2017-10-25 07:37:50 -07:00
aadb38a5e6 Make specs_checker constexpr 2017-10-24 07:46:30 -07:00
dd0b72e1ee Remove refactoring artefacts 2017-10-22 14:44:52 -07:00
e52b10e33f Merge branch 'vitaut-patch-1' of github.com:fmtlib/fmt into std 2017-10-22 10:35:37 -07:00
529d88ce95 Make dynamic_format_specs construction constexpr 2017-10-22 10:19:09 -07:00
d2f2a8b0ca constexpr support of dynamic width and precision 2017-10-22 09:32:46 -07:00
6b3840b73c Make format_specs construction constexpr 2017-10-22 08:18:26 -07:00
a38bd9ca24 Fix formatting and naming 2017-10-22 07:19:45 -07:00
91014f0171 Naming conventions 2017-10-22 06:43:41 -07:00
932ab2bfca Report error from parse_nonnegative_int via handler 2017-10-21 08:37:52 -07:00
0ebdf41efa Fix compile-test 2017-10-21 08:17:00 -07:00
170f5c671f Move headers to include/fmt 2017-10-21 07:38:49 -07:00
3d11eac784 Workaround another MSVC constexpr bug 2017-10-21 07:13:20 -07:00
c69e308690 Update README.rst 2017-10-20 18:00:31 -07:00
25aac0bee5 Fix travis build on macOS 2017-10-20 06:47:17 -07:00
b83241ff4d Make format spec parsing constexpr 2017-10-19 07:36:46 -07:00
bd5188c811 Remove MinGW because it's not on appveyor image 2017-10-19 06:46:25 -07:00
62616b88a6 Workaround a bug in MSVC's constexpr handling 2017-10-19 06:06:13 -07:00
b8f85f671f Use Visual Studio 2017 image on appveyor 2017-10-18 08:38:16 -07:00
7174de0d79 Fix contexpr-ness of pointer_from 2017-10-18 06:36:08 -07:00
3785afc5a3 Pass errors to handler instead of throwing (#566) 2017-10-18 06:28:18 -07:00
1b5ccf6c13 Make parse_arg_id constexpr 2017-10-15 16:54:47 -07:00
17f93fe084 Make basic_string_view ctors constexpr 2017-09-29 12:26:57 -07:00
d5e918b61f Detect C++14 compiler support 2017-09-28 08:57:54 -07:00
be5b4552d9 Make null_terminating_iterator more iteratory 2017-09-27 22:40:58 -07:00
643fb0662e Check for argument indexing switch 2017-09-27 21:18:37 -07:00
d45544d14e Fix width handling in dynamic formatting 2017-09-27 19:04:15 -07:00
8cbf544733 Add parse context 2017-09-17 09:05:01 -07:00
ec4f5175f1 Replace Range with ParseContext in parse() 2017-09-16 17:07:03 -07:00
83dd2ab919 Simplify dynamic_specs_handler 2017-09-16 15:30:13 -07:00
5a8ae0bb05 Fix a warning 2017-09-13 08:36:06 -07:00
39bc319b35 Update test results 2017-09-10 07:35:32 -07:00
534bff7d31 Fix handling of max packed arguments 2017-09-09 07:38:52 -07:00
0cda806dcc Fix compile tests 2017-09-08 11:25:49 -07:00
a3191a9903 Get rid of FMT_MAKE_WSTR_VALUE macro 2017-09-08 08:42:01 -07:00
fced79b0ee Get rid of old compat macros 2017-09-08 08:26:05 -07:00
be887d9269 Replace internal::get with std::declval 2017-09-08 08:09:28 -07:00
53cf073561 Get rid of FMT_MAKE_VALUE macro 2017-09-08 07:43:04 -07:00
2972de4ba3 Char -> char_type 2017-09-06 07:29:48 -07:00
9ee7c2163c Type -> type 2017-09-06 07:12:07 -07:00
1a09194ae6 Cleanup type handling 2017-09-06 07:00:21 -07:00
c18a4041f9 Remove conditional and to_iterator 2017-09-04 13:56:14 -07:00
1cade7ef4d Remove FMT_USE_RVALUE_REFERENCES 2017-09-04 13:52:29 -07:00
7413239f49 Remove unnecessary qualification 2017-09-04 13:12:52 -07:00
af00e4f9c9 Remove printf_arg_formatter from format.h and cleanup 2017-09-04 12:28:53 -07:00
44a26e5e21 CharPtr -> pointer_type and move to writer 2017-09-04 11:58:14 -07:00
0fbd846561 Replace fmt::internal::make_unsigned with std::make_unsigned 2017-09-04 11:41:15 -07:00
8a2bc0ab1b Add nullptr support 2017-09-04 11:10:08 -07:00
80505995d0 Allow delayed type checking 2017-09-04 09:33:22 -07:00
b0867f3fa0 AlignSpec -> align_spec and fix a warning 2017-08-27 09:56:45 -07:00
f194a418f9 Replace fmt::is_same with std::is_same 2017-08-27 09:16:50 -07:00
47c84d7974 Move part of write API (spec factories) to a separate header 2017-08-27 09:08:44 -07:00
20168147dd Add ptr, a helper function for pointer formatting 2017-08-27 08:41:28 -07:00
77c892c88e Fix more warnings 2017-08-27 08:16:46 -07:00
be7d72ba0d Fix expansion-to-defined warning 2017-08-27 08:00:15 -07:00
d4c504ae1c Fix a warning 2017-08-27 06:38:23 -07:00
27ad6cee82 Use standard enable_if 2017-08-26 10:41:58 -07:00
64681739fd Fix a warning 2017-08-26 09:32:37 -07:00
388061674a Remove FMT_HAS_GXX_CXX11 2017-08-26 09:23:00 -07:00
a7320bdce9 Fix a warning 2017-08-26 09:19:03 -07:00
016acebb56 Remove legacy code 2017-08-26 09:09:43 -07:00
07f8ffc44f Suppress shadowing warnings 2017-08-26 08:50:09 -07:00
466386d5cd Suppress a warning in gmock 2017-08-26 08:50:09 -07:00
70ef82a8e3 Workaround a bug in MSVC 2017-08-20 09:47:21 -07:00
5e0562ab51 Separate parsing and formatting 2017-08-13 13:09:02 -07:00
1102d46508 Make format spec parsing context-independent 2017-07-30 08:58:24 -07:00
45911770c5 Separate parsing and formatting in extension API 2017-07-29 07:50:16 -07:00
7bd776e7db Explain why null_terminating_iterator is used 2017-07-26 08:48:59 -07:00
873c8451ed Remove system_header pragma 2017-07-26 08:42:57 -07:00
9f7957c073 Separate argument parsing and formatting 2017-07-26 08:37:46 -07:00
da439f2838 Suppress warning about missing noreturn attribute (#549)
Suppress warning about missing noreturn attribute

Adding `[[noreturn]]` to `report_unknown_type` suppresses the Clang/GCC `-Wmissing-noreturn` warning:

Clang outputs:

    .../fmt/fmt/format.cc:294:74: warning:
          function 'report_unknown_type' could be declared with
          attribute 'noreturn' [-Wmissing-noreturn]
      ...code, const char *type) {
                                 ^

GCC outputs:

    .../fmt/fmt/format.cc:294:74: warning: function might be candidate for
        attribute 'noreturn' [-Wsuggest-attribute=noreturn]
      ...code, const char *type) {
                                 ^

Cherry-picked d16c4d.
2017-07-23 20:21:11 -07:00
eefdb379f9 Fix an unused argument warning 2017-07-23 20:15:52 -07:00
2f4f49fd60 Switch from cstring_view to string_view 2017-07-22 08:24:37 -07:00
a8d6f309c8 Minor optimizations 2017-07-17 06:52:56 -07:00
d16582a038 Move printf-related code to printf.cc 2017-07-15 09:46:18 -04:00
361911dd18 Use preinstalled version of cmake on travis 2017-07-13 19:06:20 -04:00
9ea183aaba Fix MSVC build 2017-07-13 19:00:21 -04:00
8f4b918c5b Check argument index 2017-07-12 13:24:51 -04:00
4193485b43 Remove test files 2017-07-12 13:15:06 -04:00
07123e8ff3 Use Ubuntu Trusty on Travis for a new CMake 2017-07-12 13:13:36 -04:00
586d63636a Implement more efficient handling of large number of format arguments 2017-07-12 00:26:54 -04:00
12252152ac CStringRef -> cstring_view 2017-03-26 15:13:10 -07:00
5aa8d6ea21 Return locale by value 2017-03-25 08:57:23 -07:00
32ec13f149 Switch to C++ locale 2017-03-25 08:20:06 -07:00
b4f4b7e21a Clean the buffer API (#477) 2017-03-12 09:48:21 -07:00
f423e46835 Replace clear() with resize(0) and data_ -> store_ 2017-03-11 08:30:15 -08:00
23b8c24da4 Add noexcept 2017-03-11 07:38:16 -08:00
7175bd8ae6 Fix error on MinGW 2017-03-09 06:09:43 -08:00
7258d1b8f3 Fix tests 2017-03-08 08:08:08 -08:00
3610f34c70 Fix windows build 2017-03-04 07:10:54 -08:00
572491ad1f Document which header defines formatting functions 2017-02-24 07:04:44 -08:00
c333dca065 Follow standard naming conventions 2017-02-21 06:56:26 -08:00
6a2ff287b2 Follow standard naming conventions 2017-02-19 08:05:41 -08:00
eedfd07f8b internal::MemoryBuffer -> basic_memory_buffer 2017-02-18 09:13:12 -08:00
4ec8860783 ArgFormatter -> arg_formatter 2017-02-18 07:46:32 -08:00
50e716737d StringRef -> string_view, LongLong -> long_long 2017-02-18 07:34:52 -08:00
e022c21ddc Fix windows build 2017-02-18 06:29:33 -08:00
87b691d80c Merge StringWriter into StringBuffer 2017-02-17 06:23:16 -08:00
c2f021692f Merge ArrayWriter into FixedBuffer 2017-02-17 06:09:26 -08:00
fefaf07b6f Pass buffer instead of writer to format_value 2017-02-14 19:39:34 -05:00
6e568f3a08 buffer -> basic_buffer 2017-02-14 12:08:37 -05:00
bb1c82ef7d Fix build 2017-02-05 08:04:13 -08:00
a13b96ed88 Simplify API 2017-02-05 06:54:03 -08:00
624c58682d Simplify API 2017-02-05 06:41:39 -08:00
7ae8bd7073 basic_format_arg -> basic_arg, Buffer -> buffer 2017-02-05 06:09:06 -08:00
bf0f107564 Parameterize format_specs on character type 2017-01-28 13:17:47 +00:00
296e9cada2 FrmatSpec -> format_spec 2017-01-28 12:51:35 +00:00
b5fb8dd18b stream -> buffer 2017-01-28 12:44:36 +00:00
984a102921 Remove IntFormatSpec and StrFormatSpec 2017-01-28 04:26:48 -08:00
4863730eca Remove pad 2017-01-22 19:11:47 -08:00
aaa0fc396b Improve compatibility with old compilers and fix test 2017-01-22 12:16:16 -08:00
aea5d3ab00 Improve compatibility with older gcc and update tests 2017-01-22 11:50:52 -08:00
8485027710 Use named argument emulation instead of nested functions 2017-01-22 11:28:55 -08:00
ec15ef7b7b Replace operator<< with write function 2017-01-22 10:00:34 -08:00
b77c8190ca FPUtil -> fputil 2016-12-30 13:12:27 -08:00
8428621ddc BasicWriter -> basic_writer 2016-12-30 12:26:12 -08:00
939aff2936 Remove unnecessary template arg from basic_format_args 2016-12-30 10:19:38 -08:00
f69786a715 Remove Not 2016-12-30 09:29:41 -08:00
b2a0d8914a Merge value and MakeValue 2016-12-30 09:25:01 -08:00
acd1811c50 Value -> value 2016-12-30 08:05:26 -08:00
42a319074c Parameterize Value on context 2016-12-29 18:07:05 -08:00
a4d6cb32d1 Clean up basic_format_arg 2016-12-29 17:17:18 -08:00
d705d51671 Parameterize basic_format_arg on context (#442) 2016-12-29 15:25:22 -08:00
422236af7c Don't erase writer type 2016-12-28 07:55:33 -08:00
abb6996f36 MakeArg -> make_arg 2016-12-27 07:55:44 -08:00
ee1651ce07 Handle empty format_arg state 2016-12-27 07:43:25 -08:00
3bbc5799b6 Fix MinGW build 2016-12-26 12:20:49 -08:00
63fcfc5798 Fix build on older gcc 2016-12-26 10:55:30 -08:00
d86e51e9c1 Don't inherit basic_format_arg from internal::Value 2016-12-24 07:46:50 -08:00
f05888692c Fix handling of unpacked args (#437) 2016-12-23 08:24:48 -08:00
1183621867 Add support for exotic character types 2016-12-15 08:36:18 -08:00
763ca9780f Parameterize Value on character type 2016-12-15 08:26:10 -08:00
6cba8fe9ba Move stuff out of internal::Value 2016-12-15 07:51:40 -08:00
e1ee5bf0ba Replace StringValue with StringRef 2016-12-11 21:13:54 -08:00
0854f8c3bf Parameterize formatting argument on char type. 2016-12-11 15:43:11 -08:00
9cf6c8fdc6 Get rid of fmt::internal::Arg 2016-11-26 10:21:31 -08:00
5f022ae081 Remove FMT_DISPATCH 2016-11-20 10:14:23 -08:00
41d4bcf0cc Ingore Xcode files 2016-11-20 10:13:16 -08:00
284297019f Merge BasicArgFormatter and ArgFormatter 2016-11-20 09:36:27 -08:00
d4084ac5b1 Get rid of ArgVisitor 2016-11-20 09:11:13 -08:00
d58cc8a4a8 Merge BasicPrintfArgFormatter and PrintfArgFormatter 2016-11-20 07:42:38 -08:00
e2dfd39c75 Update arg visitors 2016-11-19 09:29:09 -08:00
751ff64bdb Update ArgConverter to the new visitor API 2016-11-19 08:40:24 -08:00
c9dc41ab3f Replace ArgVisitor::visit with a free visit function 2016-11-19 07:59:54 -08:00
caa60b9c99 Update comment 2016-11-19 07:41:28 -08:00
95a53e1f62 Refactor argument visitor API (#422) 2016-11-19 07:39:07 -08:00
6d24116763 Improve visitor API 2016-11-13 09:42:17 -08:00
a1dd524b6f format_arg -> do_format_arg 2016-11-07 18:22:21 -08:00
55a1ac5035 Fix test 2016-11-07 08:55:40 -08:00
85793a18cd Simplify API 2016-11-06 19:27:14 -08:00
9998f66f8c Replace formatter with context 2016-11-06 18:59:17 -08:00
2bba420337 Pass writer directly to format_value (#400) 2016-10-26 17:54:11 -07:00
b656a1c133 Make value the second argument to format_value 2016-10-25 06:19:19 -07:00
edf98792a5 Pass writer to format_value 2016-10-25 05:55:40 -07:00
64ca334a2d CharType -> Char 2016-10-22 09:15:28 -07:00
be613204ab Char -> char_type 2016-10-22 08:19:19 -07:00
f85d5f4dac BasicFormatter -> basic_formatter 2016-10-22 08:04:20 -07:00
18dfa257d0 Pass correct formatters to make_format_args 2016-10-21 06:46:21 -07:00
dafbec7553 Fix type safety when using custom formatters (#394) 2016-10-07 08:37:06 -07:00
506435bf71 Fix formatting 2016-10-07 03:41:23 -07:00
f287994084 Fix formatting 2016-10-07 03:22:14 -07:00
48fe97835b Add format_arg::operator bool 2016-10-02 09:36:40 -07:00
119a63ab72 internal::Arg -> format_arg 2016-10-02 09:29:11 -07:00
65a8c2c343 format_arg -> format_value 2016-10-02 08:49:10 -07:00
13b04044e5 Add format_args::size_type 2016-10-02 08:26:32 -07:00
8a77e7927e Enable C++11 in tests. 2016-10-01 07:18:55 -07:00
1e8553d679 Enable C++11 in tests. 2016-10-01 07:02:58 -07:00
06bab3edb0 Workaround mingw bug https://sourceforge.net/p/mingw/bugs/1531/ 2016-09-30 07:20:57 -07:00
6fd6ecc10d Enable C++11 for no-windows-h-test 2016-09-28 07:45:28 -07:00
c4212f9ec2 format -> vformat 2016-09-28 07:09:26 -07:00
21c6700b83 Don't build std branch with -std=c++0=98 2016-09-26 07:35:27 -07:00
209a1d58bf Get rid of macros 2016-08-27 09:06:21 -07:00
9a07973261 Test types 2016-08-27 08:55:01 -07:00
ea28a63706 Get rid of FMT_VARIADIC_CTOR 2016-08-27 08:23:44 -07:00
0d8aca8de3 Get rid of FMT_VARIADIC_VOID 2016-08-27 08:16:49 -07:00
4ece95a754 Make make_format_args public 2016-08-27 07:57:48 -07:00
0028ce57b6 Get rid of FMT_VARIADIC 2016-08-26 17:23:13 -07:00
ece7ae5f49 Make format_arg_store convertible to format_args 2016-08-26 15:09:40 -07:00
621447fece Make initialization C++11-compatible 2016-08-26 14:41:18 -07:00
a0190e4bbd Add a missing include 2016-08-26 10:26:33 -07:00
b903f5c123 format -> vformat 2016-08-26 09:10:23 -07:00
43c0095aa3 Refactor type mapping 2016-08-26 08:50:09 -07:00
4873685c7e ArgArray -> format_arg_store 2016-08-26 06:44:41 -07:00
fc73e10620 ArgList -> format_args 2016-08-25 08:50:07 -07:00
92605eb4f7 Remove FMT_USE_VARIADIC_TEMPLATES 2016-08-25 08:44:53 -07:00
9bb213e920 FormatError -> format_error 2016-08-25 08:38:07 -07:00
161 changed files with 66250 additions and 49550 deletions

8
.clang-format Normal file
View File

@ -0,0 +1,8 @@
# Run manually to reformat a file:
# clang-format -i --style=file <file>
Language: Cpp
BasedOnStyle: Google
IndentPPDirectives: AfterHash
IndentCaseLabels: false
AlwaysBreakTemplateDeclarations: false
DerivePointerAlignment: false

8
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions" # Necessary to update action hashs
directory: "/"
schedule:
interval: "weekly"
# Allow up to 3 opened pull requests for github-actions versions
open-pull-requests-limit: 3

6
.github/issue_template.md vendored Normal file
View File

@ -0,0 +1,6 @@
<!--
Please make sure that the problem reproduces on the current master before
submitting an issue.
If possible please provide a repro on Compiler Explorer:
https://godbolt.org/z/fxccbh53W.
-->

View File

@ -1,3 +0,0 @@
<!---
Please make sure you've followed the guidelines outlined in the CONTRIBUTING.rst file.
--->

7
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,7 @@
<!--
Please read the contribution guidelines before submitting a pull request:
https://github.com/fmtlib/fmt/blob/master/CONTRIBUTING.md.
By submitting this pull request, you agree to license your contribution(s)
under the terms outlined in LICENSE.rst and represent that you have the right
to do so.
-->

30
.github/workflows/cifuzz.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: CIFuzz
on: [pull_request]
permissions:
contents: read
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'fmt'
dry-run: false
language: c++
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'fmt'
fuzz-seconds: 300
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts

35
.github/workflows/doc.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: doc
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
# Use Ubuntu 20.04 because doxygen 1.8.13 from Ubuntu 18.04 is broken.
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Add ubuntu mirrors
run: |
# Github Actions caching proxy is at times unreliable
# see https://github.com/actions/runner-images/issues/7048
printf 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt
curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt
sudo sed -i 's~http://azure.archive.ubuntu.com/ubuntu/~mirror+file:/etc/apt/mirrors.txt~' /etc/apt/sources.list
- name: Create Build Environment
run: |
sudo apt update
sudo apt install doxygen python3-virtualenv
sudo npm install -g less clean-css
cmake -E make_directory ${{runner.workspace}}/build
- name: Build
working-directory: ${{runner.workspace}}/build
env:
KEY: ${{secrets.KEY}}
run: $GITHUB_WORKSPACE/support/build-docs.py

111
.github/workflows/linux.yml vendored Normal file
View File

@ -0,0 +1,111 @@
name: linux
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
cxx: [g++-4.8, g++-10, clang++-9]
build_type: [Debug, Release]
std: [11]
include:
- cxx: g++-4.8
install: sudo apt install g++-4.8
- cxx: g++-8
build_type: Debug
std: 14
install: sudo apt install g++-8
- cxx: g++-8
build_type: Debug
std: 17
install: sudo apt install g++-8
- cxx: g++-9
build_type: Debug
std: 17
- cxx: g++-10
build_type: Debug
std: 17
- cxx: g++-11
build_type: Debug
std: 20
install: sudo apt install g++-11
- cxx: clang++-8
build_type: Debug
std: 17
cxxflags: -stdlib=libc++
install: sudo apt install clang-8 libc++-8-dev libc++abi-8-dev
- cxx: clang++-9
install: sudo apt install clang-9
- cxx: clang++-9
build_type: Debug
fuzz: -DFMT_FUZZ=ON -DFMT_FUZZ_LINKMAIN=ON
std: 17
install: sudo apt install clang-9
- cxx: clang++-11
build_type: Debug
std: 20
- cxx: clang++-11
build_type: Debug
std: 20
cxxflags: -stdlib=libc++
install: sudo apt install libc++-11-dev libc++abi-11-dev
- shared: -DBUILD_SHARED_LIBS=ON
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set timezone
run: sudo timedatectl set-timezone 'Asia/Yekaterinburg'
- name: Add repositories for older GCC
run: |
# Below two repos provide GCC 4.8, 5.5 and 6.4
sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic main'
sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic universe'
# Below two repos additionally update GCC 6 to 6.5
# sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic-updates main'
# sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic-updates universe'
if: ${{ matrix.cxx == 'g++-4.8' }}
- name: Add ubuntu mirrors
run: |
# Github Actions caching proxy is at times unreliable
# see https://github.com/actions/runner-images/issues/7048
printf 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt
curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt
sudo sed -i 's~http://azure.archive.ubuntu.com/ubuntu/~mirror+file:/etc/apt/mirrors.txt~' /etc/apt/sources.list
- name: Create Build Environment
run: |
sudo apt update
${{matrix.install}}
sudo apt install locales-all
cmake -E make_directory ${{runner.workspace}}/build
- name: Configure
working-directory: ${{runner.workspace}}/build
env:
CXX: ${{matrix.cxx}}
CXXFLAGS: ${{matrix.cxxflags}}
run: |
cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ${{matrix.fuzz}} ${{matrix.shared}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} -DFMT_DOC=OFF \
-DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON \
-DFMT_PEDANTIC=ON -DFMT_WERROR=ON $GITHUB_WORKSPACE
- name: Build
working-directory: ${{runner.workspace}}/build
run: |
threads=`nproc`
cmake --build . --config ${{matrix.build_type}} --parallel $threads
- name: Test
working-directory: ${{runner.workspace}}/build
run: ctest -C ${{matrix.build_type}}
env:
CTEST_OUTPUT_ON_FAILURE: True

55
.github/workflows/macos.yml vendored Normal file
View File

@ -0,0 +1,55 @@
name: macos
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
strategy:
matrix:
os: [macos-11, macos-13]
build_type: [Debug, Release]
std: [11, 17, 20]
exclude:
- { os: macos-11, std: 20 }
- { os: macos-13, std: 11 }
- { os: macos-13, std: 17 }
include:
- shared: -DBUILD_SHARED_LIBS=ON
runs-on: '${{ matrix.os }}'
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set timezone
run: sudo systemsetup -settimezone 'Asia/Yekaterinburg'
- name: Select Xcode 14.3 (macOS 13)
run: sudo xcode-select -s "/Applications/Xcode_14.3.app"
if: ${{ matrix.os == 'macos-13' }}
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure
working-directory: ${{runner.workspace}}/build
run: |
cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ${{matrix.shared}} \
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
-DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON \
-DFMT_DOC=OFF -DFMT_PEDANTIC=ON -DFMT_WERROR=ON $GITHUB_WORKSPACE
- name: Build
working-directory: ${{runner.workspace}}/build
run: |
threads=`sysctl -n hw.logicalcpu`
cmake --build . --config ${{matrix.build_type}} --parallel $threads
- name: Test
working-directory: ${{runner.workspace}}/build
run: ctest -C ${{matrix.build_type}}
env:
CTEST_OUTPUT_ON_FAILURE: True

65
.github/workflows/scorecard.yml vendored Normal file
View File

@ -0,0 +1,65 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '26 14 * * 5'
push:
branches: [ "master" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@a09933a12a80f87b87005513f0abb1494c27a716 # v2.21.4
with:
sarif_file: results.sarif

100
.github/workflows/windows.yml vendored Normal file
View File

@ -0,0 +1,100 @@
name: windows
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
runs-on: ${{matrix.os}}
strategy:
matrix:
# windows-2019 has MSVC 2019 installed;
# windows-2022 has MSVC 2022 installed:
# https://github.com/actions/virtual-environments.
os: [windows-2019]
platform: [Win32, x64]
toolset: [v140, v141, v142]
standard: [14, 17, 20]
shared: ["", -DBUILD_SHARED_LIBS=ON]
build_type: [Debug, Release]
exclude:
- { toolset: v140, standard: 17 }
- { toolset: v140, standard: 20 }
- { toolset: v141, standard: 14 }
- { toolset: v141, standard: 20 }
- { toolset: v142, standard: 14 }
- { platform: Win32, toolset: v140 }
- { platform: Win32, toolset: v141 }
- { platform: Win32, standard: 14 }
- { platform: Win32, standard: 20 }
- { platform: x64, toolset: v140, shared: -DBUILD_SHARED_LIBS=ON }
- { platform: x64, toolset: v141, shared: -DBUILD_SHARED_LIBS=ON }
- { platform: x64, standard: 14, shared: -DBUILD_SHARED_LIBS=ON }
- { platform: x64, standard: 20, shared: -DBUILD_SHARED_LIBS=ON }
include:
- os: windows-2022
platform: x64
toolset: v143
build_type: Debug
standard: 20
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set timezone
run: tzutil /s "Ekaterinburg Standard Time"
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure
# Use a bash shell for $GITHUB_WORKSPACE.
shell: bash
working-directory: ${{runner.workspace}}/build
run: |
cmake -A ${{matrix.platform}} -T ${{matrix.toolset}} \
-DCMAKE_CXX_STANDARD=${{matrix.standard}} \
${{matrix.shared}} -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
$GITHUB_WORKSPACE
- name: Build
working-directory: ${{runner.workspace}}/build
run: |
$threads = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
cmake --build . --config ${{matrix.build_type}} --parallel $threads
- name: Test
working-directory: ${{runner.workspace}}/build
run: ctest -C ${{matrix.build_type}} -V
env:
CTEST_OUTPUT_ON_FAILURE: True
mingw:
runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
strategy:
matrix:
sys: [ mingw64, ucrt64 ]
steps:
- name: Set timezone
run: tzutil /s "Ekaterinburg Standard Time"
shell: cmd
- uses: msys2/setup-msys2@7efe20baefed56359985e327d329042cde2434ff # v2
with:
release: false
msystem: ${{matrix.sys}}
pacboy: cc:p cmake:p ninja:p lld:p
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Configure
run: cmake -B ../build -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug
env: { LDFLAGS: -fuse-ld=lld }
- name: Build
run: cmake --build ../build
- name: Test
run: ctest -j `nproc` --test-dir ../build
env:
CTEST_OUTPUT_ON_FAILURE: True

18
.gitignore vendored
View File

@ -1,13 +1,29 @@
.vscode/
.vs/
*.iml
.idea/
.externalNativeBuild/
.gradle/
gradle/
gradlew*
local.properties
build/
support/.cxx
bin/
/_CPack_Packages
/CMakeScripts
/doc/doxyxml
/doc/html
/doc/node_modules
virtualenv
/Testing
/install_manifest.txt
*~
*.a
*.so*
*.xcodeproj
*.zip
cmake_install.cmake
CPack*.cmake
@ -15,5 +31,7 @@ fmt-*.cmake
CTestTestfile.cmake
CMakeCache.txt
CMakeFiles
FMT.build
Makefile
run-msbuild.bat
fmt.pc

View File

@ -1,27 +0,0 @@
language: cpp
dist: trusty
sudo: required # the doc target uses sudo to install dependencies
os:
- linux
- osx
env:
global:
- secure: |-
Gsnp9ERFnXt+diCfc7Vb72g+7HDn1MCHvw4zfUDdoBh9bxxFlLQRlzZZfwWhzni57lflrt
0QHXafu+oBVOJuNv6WauV3+ZyuWIQRmNGjZFNLvZsXHK/dyad2vGQBPvEkb+8l/aCyTpbr
6pxmyzLHSn1ZR7OX5rfPvwM3tOyZ3H0=
matrix:
- BUILD=Doc
- BUILD=Debug STANDARD=0x
- BUILD=Release STANDARD=98
- BUILD=Release STANDARD=0x
matrix:
exclude:
- os: osx
env: BUILD=Doc
script:
- support/travis-build.py

View File

@ -1,54 +1,177 @@
message(STATUS "CMake version: ${CMAKE_VERSION}")
if(NOT DEFINED IDF_TARGET)
cmake_minimum_required(VERSION 3.8...3.26)
cmake_minimum_required(VERSION 2.8.12)
if (POLICY CMP0048) # Version variables
cmake_policy(SET CMP0048 OLD)
endif ()
if (POLICY CMP0063) # Visibility
cmake_policy(SET CMP0063 OLD)
endif (POLICY CMP0063)
# Fallback for using newer policies on CMake <3.12.
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
# Determine if fmt is built as a subproject (using add_subdirectory)
# or if it is the master project.
set(MASTER_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(MASTER_PROJECT ON)
if (NOT DEFINED FMT_MASTER_PROJECT)
set(FMT_MASTER_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(FMT_MASTER_PROJECT ON)
message(STATUS "CMake version: ${CMAKE_VERSION}")
endif ()
endif ()
# Joins arguments and places the results in ${result_var}.
function(join result_var)
set(result )
set(result "")
foreach (arg ${ARGN})
set(result "${result}${arg}")
endforeach ()
set(${result_var} "${result}" PARENT_SCOPE)
endfunction()
# DEPRECATED! Should be merged into add_module_library.
function(enable_module target)
if (MSVC)
set(BMI ${CMAKE_CURRENT_BINARY_DIR}/${target}.ifc)
target_compile_options(${target}
PRIVATE /interface /ifcOutput ${BMI}
INTERFACE /reference fmt=${BMI})
set_target_properties(${target} PROPERTIES ADDITIONAL_CLEAN_FILES ${BMI})
set_source_files_properties(${BMI} PROPERTIES GENERATED ON)
endif ()
endfunction()
# Adds a library compiled with C++20 module support.
# `enabled` is a CMake variables that specifies if modules are enabled.
# If modules are disabled `add_module_library` falls back to creating a
# non-modular library.
#
# Usage:
# add_module_library(<name> [sources...] FALLBACK [sources...] [IF enabled])
function(add_module_library name)
cmake_parse_arguments(AML "" "IF" "FALLBACK" ${ARGN})
set(sources ${AML_UNPARSED_ARGUMENTS})
add_library(${name})
set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX)
if (NOT ${${AML_IF}})
# Create a non-modular library.
target_sources(${name} PRIVATE ${AML_FALLBACK})
return()
endif ()
# Modules require C++20.
target_compile_features(${name} PUBLIC cxx_std_20)
if (CMAKE_COMPILER_IS_GNUCXX)
target_compile_options(${name} PUBLIC -fmodules-ts)
endif ()
# `std` is affected by CMake options and may be higher than C++20.
get_target_property(std ${name} CXX_STANDARD)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(pcms)
foreach (src ${sources})
get_filename_component(pcm ${src} NAME_WE)
set(pcm ${pcm}.pcm)
# Propagate -fmodule-file=*.pcm to targets that link with this library.
target_compile_options(
${name} PUBLIC -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm})
# Use an absolute path to prevent target_link_libraries prepending -l
# to it.
set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm})
add_custom_command(
OUTPUT ${pcm}
COMMAND ${CMAKE_CXX_COMPILER}
-std=c++${std} -x c++-module --precompile -c
-o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src}
"-I$<JOIN:$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>,;-I>"
# Required by the -I generator expression above.
COMMAND_EXPAND_LISTS
DEPENDS ${src})
endforeach ()
# Add .pcm files as sources to make sure they are built before the library.
set(sources)
foreach (pcm ${pcms})
get_filename_component(pcm_we ${pcm} NAME_WE)
set(obj ${pcm_we}.o)
# Use an absolute path to prevent target_link_libraries prepending -l.
set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj})
add_custom_command(
OUTPUT ${obj}
COMMAND ${CMAKE_CXX_COMPILER} $<TARGET_PROPERTY:${name},COMPILE_OPTIONS>
-c -o ${obj} ${pcm}
DEPENDS ${pcm})
endforeach ()
endif ()
target_sources(${name} PRIVATE ${sources})
endfunction()
include(CMakeParseArguments)
# Sets a cache variable with a docstring joined from multiple arguments:
# set(<variable> <value>... CACHE <type> <docstring>...)
# This allows splitting a long docstring for readability.
function(set_verbose)
# cmake_parse_arguments is broken in CMake 3.4 (cannot parse CACHE) so use
# list instead.
list(GET ARGN 0 var)
list(REMOVE_AT ARGN 0)
list(GET ARGN 0 val)
list(REMOVE_AT ARGN 0)
list(REMOVE_AT ARGN 0)
list(GET ARGN 0 type)
list(REMOVE_AT ARGN 0)
join(doc ${ARGN})
set(${var} ${val} CACHE ${type} ${doc})
endfunction()
# Set the default CMAKE_BUILD_TYPE to Release.
# This should be done before the project command since the latter can set
# CMAKE_BUILD_TYPE itself (it does so for nmake).
if (NOT CMAKE_BUILD_TYPE)
join(doc "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or "
"CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
set(CMAKE_BUILD_TYPE Release CACHE STRING ${doc})
if (FMT_MASTER_PROJECT AND NOT CMAKE_BUILD_TYPE)
set_verbose(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None(CMAKE_CXX_FLAGS or "
"CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
endif ()
project(FMT CXX)
include(GNUInstallDirs)
set_verbose(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING
"Installation directory for include files, a relative path that "
"will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute path.")
option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF)
option(FMT_WERROR "Halt the compilation with an error on compiler warnings."
OFF)
# Options that control generation of various targets.
option(FMT_DOC "Generate the doc target." ${MASTER_PROJECT})
option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT})
option(FMT_TEST "Generate the test target." ${MASTER_PROJECT})
option(FMT_USE_CPP11 "Enable the addition of C++11 compiler flags." ON)
option(FMT_DOC "Generate the doc target." ${FMT_MASTER_PROJECT})
option(FMT_INSTALL "Generate the install target." ON)
option(FMT_TEST "Generate the test target." ${FMT_MASTER_PROJECT})
option(FMT_FUZZ "Generate the fuzz target." OFF)
option(FMT_CUDA_TEST "Generate the cuda-test target." OFF)
option(FMT_OS "Include core requiring OS (Windows/Posix) " ON)
option(FMT_MODULE "Build a module instead of a traditional library." OFF)
option(FMT_SYSTEM_HEADERS "Expose headers with marking them as system." OFF)
project(FMT)
if (FMT_TEST AND FMT_MODULE)
# The tests require {fmt} to be compiled as traditional library
message(STATUS "Testing is incompatible with build mode 'module'.")
endif ()
set(FMT_SYSTEM_HEADERS_ATTRIBUTE "")
if (FMT_SYSTEM_HEADERS)
set(FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
endif ()
if(CMAKE_SYSTEM_NAME STREQUAL "MSDOS")
set(FMT_TEST OFF)
message(STATUS "MSDOS is incompatible with gtest")
endif()
# Starting with cmake 3.0 VERSION is part of the project command.
file(READ fmt/format.h format_h)
if (NOT format_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])")
message(FATAL_ERROR "Cannot get FMT_VERSION from format.h.")
# Get version from core.h
file(READ include/fmt/core.h core_h)
if (NOT core_h MATCHES "FMT_VERSION ([0-9]+)([0-9][0-9])([0-9][0-9])")
message(FATAL_ERROR "Cannot get FMT_VERSION from core.h.")
endif ()
# Use math to skip leading zeros if any.
math(EXPR CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
@ -60,18 +183,72 @@ message(STATUS "Version: ${FMT_VERSION}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
endif ()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/support/cmake")
include(cxx11)
include(CheckCXXCompilerFlag)
include(JoinPaths)
if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wshadow -pedantic)
if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
set_verbose(CMAKE_CXX_VISIBILITY_PRESET hidden CACHE STRING
"Preset for the export of private symbols")
set_property(CACHE CMAKE_CXX_VISIBILITY_PRESET PROPERTY STRINGS
hidden default)
endif ()
if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
if (FMT_MASTER_PROJECT AND NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN)
set_verbose(CMAKE_VISIBILITY_INLINES_HIDDEN ON CACHE BOOL
"Whether to add a compile flag to hide symbols of inline functions")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic
-Wold-style-cast -Wundef
-Wredundant-decls -Wwrite-strings -Wpointer-arith
-Wcast-qual -Wformat=2 -Wmissing-include-dirs
-Wcast-align
-Wctor-dtor-privacy -Wdisabled-optimization
-Winvalid-pch -Woverloaded-virtual
-Wconversion -Wundef
-Wno-ctor-dtor-privacy -Wno-format-nonliteral)
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS}
-Wno-dangling-else -Wno-unused-local-typedefs)
endif ()
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wdouble-promotion
-Wtrampolines -Wzero-as-null-pointer-constant -Wuseless-cast
-Wvector-operation-performance -Wsized-deallocation -Wshadow)
endif ()
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wshift-overflow=2
-Wnull-dereference -Wduplicated-cond)
endif ()
set(WERROR_FLAG -Werror)
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion -Wundef
-Wdeprecated -Wweak-vtables -Wshadow
-Wno-gnu-zero-variadic-macro-arguments)
check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING)
if (HAS_NULLPTR_WARNING)
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS}
-Wzero-as-null-pointer-constant)
endif ()
set(WERROR_FLAG -Werror)
endif ()
if (MSVC)
set(PEDANTIC_COMPILE_FLAGS /W3)
set(WERROR_FLAG /WX)
endif ()
if (FMT_MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
# If Microsoft SDK is installed create script run-msbuild.bat that
# calls SetEnv.cmd to set up build environment and runs msbuild.
# It is useful when building Visual Studio projects with the SDK
@ -81,20 +258,149 @@ if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
set(MSBUILD_SETUP "call \"${WINSDK_SETENV}\"")
endif ()
# Set FrameworkPathOverride to get rid of MSB3644 warnings.
set(netfxpath "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0")
join(netfxpath
"C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\"
".NETFramework\\v4.0")
file(WRITE run-msbuild.bat "
${MSBUILD_SETUP}
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()
include(CheckSymbolExists)
if (WIN32)
check_symbol_exists(open io.h HAVE_OPEN)
else ()
check_symbol_exists(open fcntl.h HAVE_OPEN)
function(add_headers VAR)
set(headers ${${VAR}})
foreach (header ${ARGN})
set(headers ${headers} include/fmt/${header})
endforeach()
set(${VAR} ${headers} PARENT_SCOPE)
endfunction()
# Define the fmt library, its includes and the needed defines.
add_headers(FMT_HEADERS args.h chrono.h color.h compile.h core.h format.h
format-inl.h os.h ostream.h printf.h ranges.h std.h
xchar.h)
set(FMT_SOURCES src/format.cc)
if (FMT_OS)
set(FMT_SOURCES ${FMT_SOURCES} src/os.cc)
endif ()
add_subdirectory(fmt)
add_module_library(fmt src/fmt.cc FALLBACK
${FMT_SOURCES} ${FMT_HEADERS} README.rst ChangeLog.rst
IF FMT_MODULE)
add_library(fmt::fmt ALIAS fmt)
if (FMT_MODULE)
enable_module(fmt)
endif ()
if (FMT_WERROR)
target_compile_options(fmt PRIVATE ${WERROR_FLAG})
endif ()
if (FMT_PEDANTIC)
target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
if (cxx_std_11 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
target_compile_features(fmt PUBLIC cxx_std_11)
else ()
message(WARNING "Feature cxx_std_11 is unknown for the CXX compiler")
endif ()
target_include_directories(fmt ${FMT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.")
set_target_properties(fmt PROPERTIES
VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}
PUBLIC_HEADER "${FMT_HEADERS}"
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}")
# Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target
# property because it's not set by default.
set(FMT_LIB_NAME fmt)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(FMT_LIB_NAME ${FMT_LIB_NAME}${FMT_DEBUG_POSTFIX})
endif ()
if (BUILD_SHARED_LIBS)
target_compile_definitions(fmt PRIVATE FMT_LIB_EXPORT INTERFACE FMT_SHARED)
endif ()
if (FMT_SAFE_DURATION_CAST)
target_compile_definitions(fmt PUBLIC FMT_SAFE_DURATION_CAST)
endif()
add_library(fmt-header-only INTERFACE)
add_library(fmt::fmt-header-only ALIAS fmt-header-only)
target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
target_compile_features(fmt-header-only INTERFACE cxx_std_11)
target_include_directories(fmt-header-only ${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)
# Install targets.
if (FMT_INSTALL)
include(CMakePackageConfigHelpers)
set_verbose(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING
"Installation directory for cmake files, a relative path that "
"will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute "
"path.")
set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake)
set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake)
set(pkgconfig ${PROJECT_BINARY_DIR}/fmt.pc)
set(targets_export_name fmt-targets)
set_verbose(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
"Installation directory for libraries, a relative path that "
"will be joined to ${CMAKE_INSTALL_PREFIX} or an absolute path.")
set_verbose(FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE STRING
"Installation directory for pkgconfig (.pc) files, a relative "
"path that will be joined with ${CMAKE_INSTALL_PREFIX} or an "
"absolute path.")
# Generate the version, config and target files into the build directory.
write_basic_package_version_file(
${version_config}
VERSION ${FMT_VERSION}
COMPATIBILITY AnyNewerVersion)
join_paths(libdir_for_pc_file "\${exec_prefix}" "${FMT_LIB_DIR}")
join_paths(includedir_for_pc_file "\${prefix}" "${FMT_INC_DIR}")
configure_file(
"${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in"
"${pkgconfig}"
@ONLY)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in
${project_config}
INSTALL_DESTINATION ${FMT_CMAKE_DIR})
set(INSTALL_TARGETS fmt fmt-header-only)
# Install the library and headers.
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
LIBRARY DESTINATION ${FMT_LIB_DIR}
ARCHIVE DESTINATION ${FMT_LIB_DIR}
PUBLIC_HEADER DESTINATION "${FMT_INC_DIR}/fmt"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
# Use a namespace because CMake provides better diagnostics for namespaced
# imported targets.
export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt::
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
# Install version, config and target files.
install(
FILES ${project_config} ${version_config}
DESTINATION ${FMT_CMAKE_DIR})
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
NAMESPACE fmt::)
install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}")
endif ()
if (FMT_DOC)
add_subdirectory(doc)
@ -105,11 +411,23 @@ if (FMT_TEST)
add_subdirectory(test)
endif ()
# Control fuzzing independent of the unit tests.
if (FMT_FUZZ)
add_subdirectory(test/fuzzing)
# The FMT_FUZZ macro is used to prevent resource exhaustion in fuzzing
# mode and make fuzzing practically possible. It is similar to
# FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION but uses a different name to
# avoid interfering with fuzzing of projects that use {fmt}.
# See also https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode.
target_compile_definitions(fmt PUBLIC FMT_FUZZ)
endif ()
set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore)
if (MASTER_PROJECT AND EXISTS ${gitignore})
if (FMT_MASTER_PROJECT AND EXISTS ${gitignore})
# Get the list of ignored files from .gitignore.
file (STRINGS ${gitignore} lines)
LIST(REMOVE_ITEM lines /doc/html)
list(REMOVE_ITEM lines /doc/html)
foreach (line ${lines})
string(REPLACE "." "[.]" line "${line}")
string(REPLACE "*" ".*" line "${line}")
@ -125,3 +443,12 @@ if (MASTER_PROJECT AND EXISTS ${gitignore})
set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst)
include(CPack)
endif ()
else()
idf_component_register(
SRCS
src/format.cc
INCLUDE_DIRS
include
)
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 23)
endif()

20
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,20 @@
Contributing to {fmt}
=====================
By submitting a pull request or a patch, you represent that you have the right
to license your contribution to the {fmt} project owners and the community,
agree that your contributions are licensed under the {fmt} license, and agree
to future changes to the licensing.
All C++ code must adhere to [Google C++ Style Guide](
https://google.github.io/styleguide/cppguide.html) with the following
exceptions:
* Exceptions are permitted
* snake_case should be used instead of UpperCamelCase for function and type
names
All documentation must adhere to the [Google Developer Documentation Style
Guide](https://developers.google.com/style).
Thanks for contributing!

View File

@ -1,11 +0,0 @@
Contributing to fmt
===================
All C++ code must adhere to `Google C++ Style Guide
<https://google.github.io/styleguide/cppguide.html>`_ with the following
exceptions:
* Exceptions are permitted
* snake_case should be used instead of UpperCamelCase for function names
Thanks for contributing!

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,27 @@
Copyright (c) 2012 - 2016, Victor Zverovich
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

View File

@ -1,295 +1,191 @@
{fmt}
=====
.. image:: https://user-images.githubusercontent.com/
576385/156254208-f5b743a9-88cf-439d-b0c0-923d53e8d551.png
:width: 25%
:alt: {fmt}
.. image:: https://travis-ci.org/fmtlib/fmt.png?branch=master
:target: https://travis-ci.org/fmtlib/fmt
.. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux
.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v
:target: https://ci.appveyor.com/project/vitaut/fmt
.. image:: https://badges.gitter.im/Join%20Chat.svg
:alt: Join the chat at https://gitter.im/fmtlib/fmt
:target: https://gitter.im/fmtlib/fmt
.. image:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos
**fmt** is an open-source formatting library for C++.
It can be used as a safe alternative to printf or as a fast
alternative to IOStreams.
.. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg
:target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows
`Documentation <http://fmtlib.net/latest/>`_
.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg
:alt: fmt is continuously fuzzed at oss-fuzz
:target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\
Summary&q=proj%3Dfmt&can=1
.. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg
:alt: Ask questions at StackOverflow with the tag fmt
:target: https://stackoverflow.com/questions/tagged/fmt
.. image:: https://api.securityscorecards.dev/projects/github.com/fmtlib/fmt/badge
:target: https://securityscorecards.dev/viewer/?uri=github.com/fmtlib/fmt
**{fmt}** is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.
If you like this project, please consider donating to one of the funds that
help victims of the war in Ukraine: https://www.stopputin.net/.
`Documentation <https://fmt.dev>`__
`Cheat Sheets <https://hackingcpp.com/cpp/libs/fmt.html>`__
Q&A: ask questions on `StackOverflow with the tag fmt
<https://stackoverflow.com/questions/tagged/fmt>`_.
Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
Features
--------
* Two APIs: faster concatenation-based `write API
<http://fmtlib.net/latest/api.html#write-api>`_ and slower,
but still very fast, replacement-based `format API
<http://fmtlib.net/latest/api.html#format-api>`_ with positional arguments
for localization.
* Write API similar to the one used by IOStreams but stateless allowing
faster implementation.
* Format API with `format string syntax
<http://fmtlib.net/latest/syntax.html>`_
similar to the one used by `str.format
<https://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
* Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments
for localization
* Implementation of `C++20 std::format
<https://en.cppreference.com/w/cpp/utility/format>`__
* `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's
`format <https://docs.python.org/3/library/stdtypes.html#str.format>`_
* Fast IEEE 754 floating-point formatter with correct rounding, shortness and
round-trip guarantees using the `Dragonbox <https://github.com/jk-jeon/dragonbox>`_
algorithm
* Portable Unicode support
* Safe `printf implementation
<http://fmtlib.net/latest/api.html#printf-formatting-functions>`_
including the POSIX extension for positional arguments.
* Support for user-defined types.
* High speed: performance of the format API is close to that of
glibc's `printf <http://en.cppreference.com/w/cpp/io/c/fprintf>`_
and better than the performance of IOStreams. See `Speed tests`_ and
`Fast integer to string conversion in C++
<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
* Small code size both in terms of source code (the core library consists of a single
header file and a single source file) and compiled code.
See `Compile time and code bloat`_.
* Reliability: the library has an extensive set of `unit tests
<https://github.com/fmtlib/fmt/tree/master/test>`_.
* Safety: the library is fully type safe, errors in format strings are
reported using exceptions, automatic memory management prevents buffer
overflow errors.
<https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
extension for positional arguments
* Extensibility: `support for user-defined types
<https://fmt.dev/latest/api.html#formatting-user-defined-types>`_
* High performance: faster than common standard library implementations of
``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_
and `Converting a hundred million integers to strings per second
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
* Small code size both in terms of source code with the minimum configuration
consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``,
and compiled code; see `Compile time and code bloat`_
* Reliability: the library has an extensive set of `tests
<https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed
<https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20
Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>`_
* Safety: the library is fully type-safe, errors in format strings can be
reported at compile time, automatic memory management prevents buffer overflow
errors
* Ease of use: small self-contained code base, no external dependencies,
permissive BSD `license
permissive MIT `license
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
* `Portability <http://fmtlib.net/latest/index.html#portability>`_ with consistent output
across platforms and support for older compilers.
* Clean warning-free codebase even on high warning levels
(-Wall -Wextra -pedantic).
* Support for wide strings.
* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro.
* `Portability <https://fmt.dev/latest/index.html#portability>`_ with
consistent output across platforms and support for older compilers
* Clean warning-free codebase even on high warning levels such as
``-Wall -Wextra -pedantic``
* Locale independence by default
* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro
See the `documentation <http://fmtlib.net/latest/>`_ for more details.
See the `documentation <https://fmt.dev>`_ for more details.
Examples
--------
This prints ``Hello, world!`` to stdout:
**Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_)
.. code:: c++
fmt::print("Hello, {}!", "world"); // uses Python-like format string syntax
fmt::printf("Hello, %s!", "world"); // uses printf format string syntax
Arguments can be accessed by position and arguments' indices can be repeated:
.. code:: c++
std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
// s == "abracadabra"
fmt can be used as a safe portable replacement for ``itoa``:
.. code:: c++
fmt::MemoryWriter w;
w << 42; // replaces itoa(42, buffer, 10)
w << fmt::hex(42); // replaces itoa(42, buffer, 16)
// access the string using w.str() or w.c_str()
An object of any user-defined type for which there is an overloaded
:code:`std::ostream` insertion operator (``operator<<``) can be formatted:
.. code:: c++
#include "fmt/ostream.h"
class Date {
int year_, month_, day_;
public:
Date(int year, int month, int day) : year_(year), month_(month), day_(day) {}
friend std::ostream &operator<<(std::ostream &os, const Date &d) {
return os << d.year_ << '-' << d.month_ << '-' << d.day_;
}
};
std::string s = fmt::format("The date is {}", Date(2012, 12, 9));
// s == "The date is 2012-12-9"
You can use the `FMT_VARIADIC
<http://fmtlib.net/latest/api.html#utilities>`_
macro to create your own functions similar to `format
<http://fmtlib.net/latest/api.html#format>`_ and
`print <http://fmtlib.net/latest/api.html#print>`_
which take arbitrary arguments:
.. code:: c++
// Prints formatted error message.
void report_error(const char *format, fmt::ArgList args) {
fmt::print("Error: ");
fmt::print(format, args);
#include <fmt/core.h>
int main() {
fmt::print("Hello, world!\n");
}
FMT_VARIADIC(void, report_error, const char *)
report_error("file not found: {}", path);
Note that you only need to define one function that takes ``fmt::ArgList``
argument. ``FMT_VARIADIC`` automatically defines necessary wrappers that
accept variable number of arguments.
Projects using this library
---------------------------
* `0 A.D. <http://play0ad.com/>`_: A free, open-source, cross-platform real-time strategy game
* `AMPL/MP <https://github.com/ampl/mp>`_:
An open-source library for mathematical programming
* `CUAUV <http://cuauv.org/>`_: Cornell University's autonomous underwater vehicle
* `Drake <http://drake.mit.edu/>`_: A planning, control, and analysis toolbox for nonlinear dynamical systems (MIT)
* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus (Lyft)
* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
* `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
* `Keypirinha <http://keypirinha.com/>`_: A semantic launcher for Windows
* `Kodi <https://kodi.tv/>`_ (formerly xbmc): Home theater software
* `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: A small tool to generate randomized datasets
* `OpenSpace <http://openspaceproject.com/>`_: An open-source astrovisualization framework
* `PenUltima Online (POL) <http://www.polserver.com/>`_:
An MMO server, compatible with most Ultima Online clients
* `quasardb <https://www.quasardb.net/>`_: A distributed, high-performance, associative database
* `readpe <https://bitbucket.org/sys_dev/readpe>`_: Read Portable Executable
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
* `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
Small crossplatform 2D graphic engine
* `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
Business intelligence software
* `Scylla <http://www.scylladb.com/>`_: A Cassandra-compatible NoSQL data store that can handle
1 million transactions per second on a single server
* `Seastar <http://www.seastar-project.org/>`_: An advanced, open-source C++ framework for
high-performance server applications on modern hardware
* `spdlog <https://github.com/gabime/spdlog>`_: Super fast C++ logging library
* `Stellar <https://www.stellar.org/>`_: Financial platform
* `Touch Surgery <https://www.touchsurgery.com/>`_: Surgery simulator
* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: Open-source MMORPG framework
`More... <https://github.com/search?q=cppformat&type=Code>`_
If you are aware of other projects using this library, please let me know
by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
`issue <https://github.com/fmtlib/fmt/issues>`_.
Motivation
----------
So why yet another formatting library?
There are plenty of methods for doing this task, from standard ones like
the printf family of function and IOStreams to Boost Format library and
FastFormat. The reason for creating a new library is that every existing
solution that I found either had serious issues or didn't provide
all the features I needed.
Printf
~~~~~~
The good thing about printf is that it is pretty fast and readily available
being a part of the C standard library. The main drawback is that it
doesn't support user-defined types. Printf also has safety issues although
they are mostly solved with `__attribute__ ((format (printf, ...))
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to printf but it is not a part of C99 and may not be available on some
platforms.
IOStreams
~~~~~~~~~
The main issue with IOStreams is best illustrated with an example:
**Format a string** (`run <https://godbolt.org/z/oK8h33>`_)
.. code:: c++
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
std::string s = fmt::format("The answer is {}.", 42);
// s == "The answer is 42."
which is a lot of typing compared to printf:
**Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_)
.. code:: c++
printf("%.2f\n", 1.23456);
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
// s == "I'd rather be happy than right."
Matthew Wilson, the author of FastFormat, referred to this situation with
IOStreams as "chevron hell". IOStreams doesn't support positional arguments
by design.
**Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_)
The good part is that IOStreams supports user-defined types and is safe
although error reporting is awkward.
.. code:: c++
Boost Format library
~~~~~~~~~~~~~~~~~~~~
#include <fmt/chrono.h>
This is a very powerful library which supports both printf-like format
strings and positional arguments. The main its drawback is performance.
According to various benchmarks it is much slower than other methods
considered here. Boost Format also has excessive build times and severe
code bloat issues (see `Benchmarks`_).
int main() {
using namespace std::literals::chrono_literals;
fmt::print("Default format: {} {}\n", 42s, 100ms);
fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
}
FastFormat
~~~~~~~~~~
Output::
This is an interesting library which is fast, safe and has positional
arguments. However it has significant limitations, citing its author:
Default format: 42s 100ms
strftime-like format: 03:15:30
Three features that have no hope of being accommodated within the
current design are:
**Print a container** (`run <https://godbolt.org/z/MxM1YqjE7>`_)
* Leading zeros (or any other non-space padding)
* Octal/hexadecimal encoding
* Runtime width/alignment specification
.. code:: c++
It is also quite big and has a heavy dependency, STLSoft, which might be
too restrictive for using it in some projects.
#include <vector>
#include <fmt/ranges.h>
Loki SafeFormat
~~~~~~~~~~~~~~~
int main() {
std::vector<int> v = {1, 2, 3};
fmt::print("{}\n", v);
}
SafeFormat is a formatting library which uses printf-like format strings
and is type safe. It doesn't support user-defined types or positional
arguments. It makes unconventional use of ``operator()`` for passing
format arguments.
Output::
Tinyformat
~~~~~~~~~~
[1, 2, 3]
This library supports printf-like format strings and is very small and
fast. Unfortunately it doesn't support positional arguments and wrapping
it in C++98 is somewhat difficult. Also its performance and code compactness
are limited by IOStreams.
**Check a format string at compile time**
Boost Spirit.Karma
~~~~~~~~~~~~~~~~~~
.. code:: c++
This is not really a formatting library but I decided to include it here
for completeness. As IOStreams it suffers from the problem of mixing
verbatim text with arguments. The library is pretty fast, but slower
on integer formatting than ``fmt::Writer`` on Karma's own benchmark,
see `Fast integer to string conversion in C++
<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
std::string s = fmt::format("{:d}", "I am not a number");
This gives a compile-time error in C++20 because ``d`` is an invalid format
specifier for a string.
**Write a file from a single thread**
.. code:: c++
#include <fmt/os.h>
int main() {
auto out = fmt::output_file("guide.txt");
out.print("Don't {}", "Panic");
}
This can be `5 to 9 times faster than fprintf
<http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_.
**Print with colors and text styles**
.. code:: c++
#include <fmt/color.h>
int main() {
fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
"Hello, {}!\n", "world");
fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
fmt::emphasis::underline, "Hello, {}!\n", "мир");
fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
"Hello, {}!\n", "世界");
}
Output on a modern terminal:
.. image:: https://user-images.githubusercontent.com/
576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
Benchmarks
----------
@ -297,31 +193,33 @@ Benchmarks
Speed tests
~~~~~~~~~~~
The following speed tests results were generated by building
``tinyformat_test.cpp`` on Ubuntu GNU/Linux 14.04.1 with
``g++-4.8.2 -O3 -DSPEED_TEST -DHAVE_FORMAT``, and taking the best of three
runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"`` or
equivalent is filled 2000000 times with output sent to ``/dev/null``; for
further details see the `source
<https://github.com/fmtlib/format-benchmark/blob/master/tinyformat_test.cpp>`_.
================= ============= ===========
Library Method Run Time, s
================= ============= ===========
EGLIBC 2.19 printf 1.30
libstdc++ 4.8.2 std::ostream 1.85
fmt 1.0 fmt::print 1.42
tinyformat 2.0.1 tfm::printf 2.25
Boost Format 1.54 boost::format 9.94
libc printf 0.91
libc++ std::ostream 2.49
{fmt} 9.1 fmt::print 0.74
Boost Format 1.80 boost::format 6.26
Folly Format folly::format 1.87
================= ============= ===========
As you can see ``boost::format`` is much slower than the alternative methods; this
is confirmed by `other tests <http://accu.org/index.php/journals/1539>`_.
Tinyformat is quite good coming close to IOStreams. Unfortunately tinyformat
cannot be faster than the IOStreams because it uses them internally.
Performance of fmt is close to that of printf, being `faster than printf on integer
formatting <http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_,
but slower on floating-point formatting which dominates this benchmark.
{fmt} is the fastest of the benchmarked methods, ~20% faster than ``printf``.
The above results were generated by building ``tinyformat_test.cpp`` on macOS
12.6.1 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
further details refer to the `source
<https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_.
{fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on
IEEE754 ``float`` and ``double`` formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
and faster than `double-conversion <https://github.com/google/double-conversion>`_ and
`ryu <https://github.com/ulfjack/ryu>`_:
.. image:: https://user-images.githubusercontent.com/576385/
95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png
:target: https://fmt.dev/unknown_mac64_clang12.0.html
Compile time and code bloat
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -331,50 +229,54 @@ The script `bloat-test.py
from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
tests compile time and code bloat for nontrivial projects.
It generates 100 translation units and uses ``printf()`` or its alternative
five times in each to simulate a medium sized project. The resulting
executable size and compile time (g++-4.8.1, Ubuntu GNU/Linux 13.10,
best of three) is shown in the following tables.
five times in each to simulate a medium-sized project. The resulting
executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
macOS Sierra, best of three) is shown in the following tables.
**Optimized build (-O3)**
============ =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============ =============== ==================== ==================
printf 2.6 41 30
IOStreams 19.4 92 70
fmt 46.8 46 34
tinyformat 64.6 418 386
Boost Format 222.8 990 923
============ =============== ==================== ==================
============= =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============= =============== ==================== ==================
printf 2.6 29 26
printf+string 16.4 29 26
iostreams 31.1 59 55
{fmt} 19.0 37 34
Boost Format 91.9 226 203
Folly Format 115.7 101 88
============= =============== ==================== ==================
As you can see, fmt has two times less overhead in terms of resulting
code size compared to IOStreams and comes pretty close to ``printf``.
Boost Format has by far the largest overheads.
As you can see, {fmt} has 60% less overhead in terms of resulting binary code
size compared to iostreams and comes pretty close to ``printf``. Boost Format
and Folly Format have the largest overheads.
``printf+string`` is the same as ``printf`` but with an extra ``<string>``
include to measure the overhead of the latter.
**Non-optimized build**
============ =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============ =============== ==================== ==================
printf 2.1 41 30
IOStreams 19.7 86 62
fmt 47.9 108 86
tinyformat 27.7 234 190
Boost Format 122.6 884 763
============ =============== ==================== ==================
============= =============== ==================== ==================
Method Compile Time, s Executable size, KiB Stripped size, KiB
============= =============== ==================== ==================
printf 2.2 33 30
printf+string 16.0 33 30
iostreams 28.3 56 52
{fmt} 18.2 59 50
Boost Format 54.1 365 303
Folly Format 79.9 445 430
============= =============== ==================== ==================
``libc``, ``libstdc++`` and ``libfmt`` are all linked as shared
libraries to compare formatting function overhead only. Boost Format
and tinyformat are header-only libraries so they don't provide any
linkage options.
``libc``, ``lib(std)c++``, and ``libfmt`` are all linked as shared libraries to
compare formatting function overhead only. Boost Format is a
header-only library so it doesn't provide any linkage options.
Running the tests
~~~~~~~~~~~~~~~~~
Please refer to `Building the library`__ for the instructions on how to build
Please refer to `Building the library`__ for instructions on how to build
the library and run the unit tests.
__ http://fmtlib.net/latest/usage.html#building-the-library
__ https://fmt.dev/latest/usage.html#building-the-library
Benchmarks reside in a separate repository,
`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
@ -392,47 +294,252 @@ Then you can run the speed test::
or the bloat test::
$ make bloat-test
Migrating code
--------------
`clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`_ v17 (not yet
released) provides the `modernize-use-std-print
<https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-print.html>`_
check that is capable of converting occurrences of ``printf`` and
``fprintf`` to ``fmt::print`` if configured to do so. (By default it
converts to ``std::print``.)
Projects using this library
---------------------------
* `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform
real-time strategy game
* `AMPL/MP <https://github.com/ampl/mp>`_:
an open-source library for mathematical programming
* `Aseprite <https://github.com/aseprite/aseprite>`_:
animated sprite editor & pixel art tool
* `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft
operations suite
* `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform
* `Celestia <https://celestia.space/>`_: real-time 3D visualization of space
* `Ceph <https://ceph.com/>`_: a scalable distributed storage system
* `ccache <https://ccache.dev/>`_: a compiler cache
* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: an analytical database
management system
* `Contour <https://github.com/contour-terminal/contour/>`_: a modern terminal emulator
* `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater
vehicle
* `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox
for nonlinear dynamical systems (MIT)
* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
(Lyft)
* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
* `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style
logging library with latency in nanoseconds
* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
* `GemRB <https://gemrb.org/>`_: a portable open-source implementation of
Biowares Infinity Engine
* `Grand Mountain Adventure
<https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
a beautiful open-world ski & snowboarding game
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
* `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server
engine
* `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows
* `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software
* `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node
* `libunicode <https://github.com/contour-terminal/libunicode/>`_: a modern C++17 Unicode library
* `MariaDB <https://mariadb.org/>`_: relational database management system
* `Microsoft Verona <https://github.com/microsoft/verona>`_:
research programming language for concurrent ownership
* `MongoDB <https://mongodb.com/>`_: distributed document database
* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to
generate randomized datasets
* `OpenSpace <https://openspaceproject.com/>`_: an open-source
astrovisualization framework
* `PenUltima Online (POL) <https://www.polserver.com/>`_:
an MMO server, compatible with most Ultima Online clients
* `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine
learning library
* `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance,
associative database
* `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library
* `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify
navigation, and executing complex multi-line terminal command sequences
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster
proxy
* `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement
for mission-critical systems written in C++
* `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client
library
* `Salesforce Analytics Cloud
<https://www.salesforce.com/analytics-cloud/overview/>`_:
business intelligence software
* `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store
that can handle 1 million transactions per second on a single server
* `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++
framework for high-performance server applications on modern hardware
* `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library
* `Stellar <https://www.stellar.org/>`_: financial platform
* `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator
* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source
MMORPG framework
* `🐙 userver framework <https://userver.tech/>`_: open-source asynchronous
framework with a rich set of abstractions and database drivers
* `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows
terminal
`More... <https://github.com/search?q=fmtlib&type=Code>`_
If you are aware of other projects using this library, please let me know
by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
`issue <https://github.com/fmtlib/fmt/issues>`_.
Motivation
----------
So why yet another formatting library?
There are plenty of methods for doing this task, from standard ones like
the printf family of function and iostreams to Boost Format and FastFormat
libraries. The reason for creating a new library is that every existing
solution that I found either had serious issues or didn't provide
all the features I needed.
printf
~~~~~~
The good thing about ``printf`` is that it is pretty fast and readily available
being a part of the C standard library. The main drawback is that it
doesn't support user-defined types. ``printf`` also has safety issues although
they are somewhat mitigated with `__attribute__ ((format (printf, ...))
<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to ``printf`` but it is not a part of C99 and may not be available on some
platforms.
iostreams
~~~~~~~~~
The main issue with iostreams is best illustrated with an example:
.. code:: c++
std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
which is a lot of typing compared to printf:
.. code:: c++
printf("%.2f\n", 1.23456);
Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
don't support positional arguments by design.
The good part is that iostreams support user-defined types and are safe although
error handling is awkward.
Boost Format
~~~~~~~~~~~~
This is a very powerful library that supports both ``printf``-like format
strings and positional arguments. Its main drawback is performance. According to
various benchmarks, it is much slower than other methods considered here. Boost
Format also has excessive build times and severe code bloat issues (see
`Benchmarks`_).
FastFormat
~~~~~~~~~~
This is an interesting library that is fast, safe, and has positional arguments.
However, it has significant limitations, citing its author:
Three features that have no hope of being accommodated within the
current design are:
* Leading zeros (or any other non-space padding)
* Octal/hexadecimal encoding
* Runtime width/alignment specification
It is also quite big and has a heavy dependency, STLSoft, which might be too
restrictive for using it in some projects.
Boost Spirit.Karma
~~~~~~~~~~~~~~~~~~
This is not a formatting library but I decided to include it here for
completeness. As iostreams, it suffers from the problem of mixing verbatim text
with arguments. The library is pretty fast, but slower on integer formatting
than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
see `Converting a hundred million integers to strings per second
<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
License
-------
fmt is distributed under the BSD `license
{fmt} is distributed under the MIT `license
<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
The `Format String Syntax
<http://fmtlib.net/latest/syntax.html>`_
Documentation License
---------------------
The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
section in the documentation is based on the one from Python `string module
documentation <https://docs.python.org/3/library/string.html#module-string>`_
adapted for the current library. For this reason the documentation is
distributed under the Python Software Foundation license available in
`doc/python-license.txt
documentation <https://docs.python.org/3/library/string.html#module-string>`_.
For this reason, the documentation is distributed under the Python Software
Foundation license available in `doc/python-license.txt
<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
It only applies if you distribute the documentation of fmt.
It only applies if you distribute the documentation of {fmt}.
Acknowledgments
---------------
Maintainers
-----------
The fmt library is maintained by Victor Zverovich (`vitaut <https://github.com/vitaut>`_)
and Jonathan Müller (`foonathan <https://github.com/foonathan>`_) with contributions from many
other people. See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and `Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names. Let us know if your contribution
is not listed or mentioned incorrectly and we'll make it right.
The benchmark section of this readme file and the performance tests are taken
from the excellent `tinyformat <https://github.com/c42f/tinyformat>`_ library
written by Chris Foster. Boost Format library is acknowledged transitively
since it had some influence on tinyformat.
Some ideas used in the implementation are borrowed from `Loki
<http://loki-lib.sourceforge.net/>`_ SafeFormat and `Diagnostic API
<http://clang.llvm.org/doxygen/classclang_1_1Diagnostic.html>`_ in
`Clang <http://clang.llvm.org/>`_.
Format string syntax and the documentation are based on Python's `str.format
<http://docs.python.org/2/library/stdtypes.html#str.format>`_.
Thanks `Doug Turnbull <https://github.com/softwaredoug>`_ for his valuable
comments and contribution to the design of the type-safe API and
`Gregory Czajkowski <https://github.com/gcflymoto>`_ for implementing binary
formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensive
`comparison of integer formatting algorithms <https://github.com/ruslo/int-dec-format-tests>`_
and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
`C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
improvements to the code.
The {fmt} library is maintained by Victor Zverovich (`vitaut
<https://github.com/vitaut>`_) with contributions from many other people.
See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
Let us know if your contribution is not listed or mentioned incorrectly and
we'll make it right.

View File

@ -1,12 +1,26 @@
find_program(DOXYGEN doxygen)
find_program(DOXYGEN doxygen
PATHS "$ENV{ProgramFiles}/doxygen/bin"
"$ENV{ProgramFiles\(x86\)}/doxygen/bin")
if (NOT DOXYGEN)
message(STATUS "Target 'doc' disabled (requires doxygen)")
return ()
endif ()
add_custom_target(doc
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build.py ${FMT_VERSION}
SOURCES build.py conf.py _templates/layout.html)
# Find the Python interpreter and set the PYTHON_EXECUTABLE variable.
if (CMAKE_VERSION VERSION_LESS 3.12)
# This logic is deprecated in CMake after 3.12.
find_package(PythonInterp QUIET REQUIRED)
else ()
find_package(Python QUIET REQUIRED)
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
endif ()
add_custom_target(doc
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/build.py
${FMT_VERSION}
SOURCES api.rst syntax.rst usage.rst build.py conf.py _templates/layout.html)
include(GNUInstallDirs)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
DESTINATION share/doc/fmt OPTIONAL)
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/fmt OPTIONAL
PATTERN ".doctrees" EXCLUDE)

View File

@ -6,14 +6,13 @@
<meta name="author" content="Victor Zverovich">
<link rel="stylesheet" href="_static/fmt.css">
{# Google Analytics #}
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-20116650-4"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();
a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;
a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-20116650-4', 'fmtlib.net');
ga('send', 'pageview');
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-20116650-4');
</script>
{% endblock %}
@ -58,7 +57,7 @@
<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
{% for v in versions.split(',') %}
<li><a href="http://fmtlib.net/{{v}}">{{v}}</a></li>
<li><a href="https://fmt.dev/{{v}}">{{v}}</a></li>
{% endfor %}
</ul>
</li>
@ -84,7 +83,7 @@
<div class="jumbotron">
<div class="tb-container">
<h1>{fmt}</h1>
<p class="lead">Small, safe and fast formatting library</p>
<p class="lead">A modern formatting library</p>
<div class="btn-group" role="group">
{% set name = 'fmt' if version.split('.')[0]|int >= 3 else 'cppformat' %}
<a class="btn btn-success"

View File

@ -4,308 +4,668 @@
API Reference
*************
All functions and classes provided by the fmt library reside
in namespace ``fmt`` and macros have prefix ``FMT_``. For brevity the
namespace is usually omitted in examples.
The {fmt} library API consists of the following parts:
* :ref:`fmt/core.h <core-api>`: the core API providing main formatting functions
for ``char``/UTF-8 with C++20 compile-time checks and minimal dependencies
* :ref:`fmt/format.h <format-api>`: the full format API providing additional
formatting functions and locale support
* :ref:`fmt/ranges.h <ranges-api>`: formatting of ranges and tuples
* :ref:`fmt/chrono.h <chrono-api>`: date and time formatting
* :ref:`fmt/std.h <std-api>`: formatters for standard library types
* :ref:`fmt/compile.h <compile-api>`: format string compilation
* :ref:`fmt/color.h <color-api>`: terminal color and text style
* :ref:`fmt/os.h <os-api>`: system APIs
* :ref:`fmt/ostream.h <ostream-api>`: ``std::ostream`` support
* :ref:`fmt/args.h <args-api>`: dynamic argument lists
* :ref:`fmt/printf.h <printf-api>`: ``printf`` formatting
* :ref:`fmt/xchar.h <xchar-api>`: optional ``wchar_t`` support
All functions and types provided by the library reside in namespace ``fmt`` and
macros have prefix ``FMT_``.
.. _core-api:
Core API
========
``fmt/core.h`` defines the core API which provides main formatting functions
for ``char``/UTF-8 with C++20 compile-time checks. It has minimal include
dependencies for better compile times. This header is only beneficial when
using {fmt} as a library (the default) and not in the header-only mode.
It also provides ``formatter`` specializations for built-in and string types.
The following functions use :ref:`format string syntax <syntax>`
similar to that of Python's `str.format
<https://docs.python.org/3/library/stdtypes.html#str.format>`_.
They take *fmt* and *args* as arguments.
*fmt* is a format string that contains literal text and replacement fields
surrounded by braces ``{}``. The fields are replaced with formatted arguments
in the resulting string. `~fmt::format_string` is a format string which can be
implicitly constructed from a string literal or a ``constexpr`` string and is
checked at compile time in C++20. To pass a runtime format string wrap it in
`fmt::runtime`.
*args* is an argument list representing objects to be formatted.
.. _format:
.. doxygenfunction:: format(format_string<T...> fmt, T&&... args) -> std::string
.. doxygenfunction:: vformat(string_view fmt, format_args args) -> std::string
.. doxygenfunction:: format_to(OutputIt out, format_string<T...> fmt, T&&... args) -> OutputIt
.. doxygenfunction:: format_to_n(OutputIt out, size_t n, format_string<T...> fmt, T&&... args) -> format_to_n_result<OutputIt>
.. doxygenfunction:: formatted_size(format_string<T...> fmt, T&&... args) -> size_t
.. doxygenstruct:: fmt::format_to_n_result
:members:
.. _print:
.. doxygenfunction:: fmt::print(format_string<T...> fmt, T&&... args)
.. doxygenfunction:: fmt::vprint(string_view fmt, format_args args)
.. doxygenfunction:: print(std::FILE *f, format_string<T...> fmt, T&&... args)
.. doxygenfunction:: vprint(std::FILE *f, string_view fmt, format_args args)
Compile-Time Format String Checks
---------------------------------
Compile-time format string checks are enabled by default on compilers
that support C++20 ``consteval``. On older compilers you can use the
:ref:`FMT_STRING <legacy-checks>`: macro defined in ``fmt/format.h`` instead.
Unused arguments are allowed as in Python's `str.format` and ordinary functions.
.. doxygenclass:: fmt::basic_format_string
:members:
.. doxygentypedef:: fmt::format_string
.. doxygenfunction:: fmt::runtime(string_view) -> runtime_format_string<>
.. _udt:
Formatting User-Defined Types
-----------------------------
The {fmt} library provides formatters for many standard C++ types.
See :ref:`fmt/ranges.h <ranges-api>` for ranges and tuples including standard
containers such as ``std::vector``, :ref:`fmt/chrono.h <chrono-api>` for date
and time formatting and :ref:`fmt/std.h <std-api>` for other standard library
types.
There are two ways to make a user-defined type formattable: providing a
``format_as`` function or specializing the ``formatter`` struct template.
Use ``format_as`` if you want to make your type formattable as some other type
with the same format specifiers. The ``format_as`` function should take an
object of your type and return an object of a formattable type. It should be
defined in the same namespace as your type.
Example (https://godbolt.org/z/r7vvGE1v7)::
#include <fmt/format.h>
namespace kevin_namespacy {
enum class film {
house_of_cards, american_beauty, se7en = 7
};
auto format_as(film f) { return fmt::underlying(f); }
}
int main() {
fmt::print("{}\n", kevin_namespacy::film::se7en); // prints "7"
}
Using the specialization API is more complex but gives you full control over
parsing and formatting. To use this method specialize the ``formatter`` struct
template for your type and implement ``parse`` and ``format`` methods.
For example::
#include <fmt/core.h>
struct point {
double x, y;
};
template <> struct fmt::formatter<point> {
// Presentation format: 'f' - fixed, 'e' - exponential.
char presentation = 'f';
// Parses format specifications of the form ['f' | 'e'].
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator {
// [ctx.begin(), ctx.end()) is a character range that contains a part of
// the format string starting from the format specifications to be parsed,
// e.g. in
//
// fmt::format("{:f} - point of interest", point{1, 2});
//
// the range will contain "f} - point of interest". The formatter should
// parse specifiers until '}' or the end of the range. In this example
// the formatter should parse the 'f' specifier and return an iterator
// pointing to '}'.
// Please also note that this character range may be empty, in case of
// the "{}" format string, so therefore you should check ctx.begin()
// for equality with ctx.end().
// Parse the presentation format and store it in the formatter:
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;
// Check if reached the end of the range:
if (it != end && *it != '}') throw_format_error("invalid format");
// Return an iterator past the end of the parsed range:
return it;
}
// Formats the point p using the parsed format specification (presentation)
// stored in this formatter.
auto format(const point& p, format_context& ctx) const -> format_context::iterator {
// ctx.out() is an output iterator to write to.
return presentation == 'f'
? fmt::format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y)
: fmt::format_to(ctx.out(), "({:.1e}, {:.1e})", p.x, p.y);
}
};
Then you can pass objects of type ``point`` to any formatting function::
point p = {1, 2};
std::string s = fmt::format("{:f}", p);
// s == "(1.0, 2.0)"
You can also reuse existing formatters via inheritance or composition, for
example::
// color.h:
#include <fmt/core.h>
enum class color {red, green, blue};
template <> struct fmt::formatter<color>: formatter<string_view> {
// parse is inherited from formatter<string_view>.
auto format(color c, format_context& ctx) const;
};
// color.cc:
#include "color.h"
#include <fmt/format.h>
auto fmt::formatter<color>::format(color c, format_context& ctx) const {
string_view name = "unknown";
switch (c) {
case color::red: name = "red"; break;
case color::green: name = "green"; break;
case color::blue: name = "blue"; break;
}
return formatter<string_view>::format(name, ctx);
}
Note that ``formatter<string_view>::format`` is defined in ``fmt/format.h`` so
it has to be included in the source file.
Since ``parse`` is inherited from ``formatter<string_view>`` it will recognize
all string format specifications, for example
.. code-block:: c++
fmt::format("{:>10}", color::blue)
will return ``" blue"``.
You can also write a formatter for a hierarchy of classes::
// demo.h:
#include <type_traits>
#include <fmt/core.h>
struct A {
virtual ~A() {}
virtual std::string name() const { return "A"; }
};
struct B : A {
virtual std::string name() const { return "B"; }
};
template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
fmt::formatter<std::string> {
auto format(const A& a, format_context& ctx) const {
return fmt::formatter<std::string>::format(a.name(), ctx);
}
};
// demo.cc:
#include "demo.h"
#include <fmt/format.h>
int main() {
B b;
A& a = b;
fmt::print("{}", a); // prints "B"
}
Providing both a ``formatter`` specialization and a ``format_as`` overload is
disallowed.
Named Arguments
---------------
.. doxygenfunction:: fmt::arg(const S&, const T&)
Named arguments are not supported in compile-time checks at the moment.
Argument Lists
--------------
You can create your own formatting function with compile-time checks and small
binary footprint, for example (https://godbolt.org/z/vajfWEG4b):
.. code:: c++
#include <fmt/core.h>
void vlog(const char* file, int line, fmt::string_view format,
fmt::format_args args) {
fmt::print("{}: {}: ", file, line);
fmt::vprint(format, args);
}
template <typename... T>
void log(const char* file, int line, fmt::format_string<T...> format, T&&... args) {
vlog(file, line, format, fmt::make_format_args(args...));
}
#define MY_LOG(format, ...) log(__FILE__, __LINE__, format, __VA_ARGS__)
MY_LOG("invalid squishiness: {}", 42);
Note that ``vlog`` is not parameterized on argument types which improves compile
times and reduces binary code size compared to a fully parameterized version.
.. doxygenfunction:: fmt::make_format_args(const Args&...)
.. doxygenclass:: fmt::format_arg_store
:members:
.. doxygenclass:: fmt::basic_format_args
:members:
.. doxygentypedef:: fmt::format_args
.. doxygenclass:: fmt::basic_format_arg
:members:
.. doxygenclass:: fmt::basic_format_parse_context
:members:
.. doxygenclass:: fmt::basic_format_context
:members:
.. doxygentypedef:: fmt::format_context
.. _args-api:
Dynamic Argument Lists
----------------------
The header ``fmt/args.h`` provides ``dynamic_format_arg_store``, a builder-like
API that can be used to construct format argument lists dynamically.
.. doxygenclass:: fmt::dynamic_format_arg_store
:members:
Compatibility
-------------
.. doxygenclass:: fmt::basic_string_view
:members:
.. doxygentypedef:: fmt::string_view
.. _format-api:
Format API
==========
The following functions defined in ``fmt/format.h`` use :ref:`format string
syntax <syntax>` similar to the one used by Python's `str.format
<http://docs.python.org/3/library/stdtypes.html#str.format>`_ function.
They take *format_str* and *args* as arguments.
``fmt/format.h`` defines the full format API providing additional formatting
functions and locale support.
*format_str* is a format string that contains literal text and replacement
fields surrounded by braces ``{}``. The fields are replaced with formatted
arguments in the resulting string.
*args* is an argument list representing arbitrary arguments.
The `performance of the format API
<https://github.com/fmtlib/fmt/blob/master/README.rst#speed-tests>`_ is close
to that of glibc's ``printf`` and better than the performance of IOStreams.
For even better speed use the `write API`_.
.. _format:
.. doxygenfunction:: format(CStringRef, ArgList)
.. doxygenfunction:: operator""_format(const char *, std::size_t)
.. _print:
.. doxygenfunction:: print(CStringRef, ArgList)
.. doxygenfunction:: print(std::FILE *, CStringRef, ArgList)
.. doxygenclass:: fmt::BasicFormatter
:members:
Date and time formatting
------------------------
The library supports `strftime
<http://en.cppreference.com/w/cpp/chrono/c/strftime>`_-like date and time
formatting::
#include "fmt/time.h"
std::time_t t = std::time(nullptr);
// Prints "The date is 2016-04-29." (with the current date)
fmt::print("The date is {:%Y-%m-%d}.", *std::localtime(&t));
The format string syntax is described in the documentation of
`strftime <http://en.cppreference.com/w/cpp/chrono/c/strftime>`_.
Formatting user-defined types
-----------------------------
A custom ``format_arg`` function may be implemented and used to format any
user-defined type. That is how date and time formatting described in the
previous section is implemented in :file:`fmt/time.h`. The following example
shows how to implement custom formatting for a user-defined structure.
::
struct MyStruct { double a, b; };
void format_arg(fmt::BasicFormatter<char> &f,
const char *&format_str, const MyStruct &s) {
f.writer().write("[MyStruct: a={:.1f}, b={:.2f}]", s.a, s.b);
}
MyStruct m = { 1, 2 };
std::string s = fmt::format("m={}", n);
// s == "m=[MyStruct: a=1.0, b=2.00]"
Note in the example above the ``format_arg`` function ignores the contents of
``format_str`` so the type will always be formatted as specified. See
``format_arg`` in :file:`fmt/time.h` for an advanced example of how to use
the ``format_str`` argument to customize the formatted output.
This technique can also be used for formatting class hierarchies::
namespace local {
struct Parent {
Parent(int p) : p(p) {}
virtual void write(fmt::Writer &w) const {
w.write("Parent : p={}", p);
}
int p;
};
struct Child : Parent {
Child(int c, int p) : Parent(p), c(c) {}
virtual void write(fmt::Writer &w) const {
w.write("Child c={} : ", c);
Parent::write(w);
}
int c;
};
void format_arg(fmt::BasicFormatter<char> &f,
const char *&format_str, const Parent &p) {
p.write(f.writer());
}
}
Local::Child c(1,2);
Local::Parent &p = c;
fmt::print("via ref to base: {}\n", p);
fmt::print("direct to child: {}\n", c);
This section shows how to define a custom format function for a user-defined
type. The next section describes how to get ``fmt`` to use a conventional stream
output ``operator<<`` when one is defined for a user-defined type.
``std::ostream`` support
------------------------
The header ``fmt/ostream.h`` provides ``std::ostream`` support including
formatting of user-defined types that have overloaded ``operator<<``::
#include "fmt/ostream.h"
class Date {
int year_, month_, day_;
public:
Date(int year, int month, int day): year_(year), month_(month), day_(day) {}
friend std::ostream &operator<<(std::ostream &os, const Date &d) {
return os << d.year_ << '-' << d.month_ << '-' << d.day_;
}
};
std::string s = fmt::format("The date is {}", Date(2012, 12, 9));
// s == "The date is 2012-12-9"
.. doxygenfunction:: print(std::ostream&, CStringRef, ArgList)
Argument formatters
-------------------
It is possible to change the way arguments are formatted by providing a
custom argument formatter class::
// A custom argument formatter that formats negative integers as unsigned
// with the ``x`` format specifier.
class CustomArgFormatter :
public fmt::BasicArgFormatter<CustomArgFormatter, char> {
public:
CustomArgFormatter(fmt::BasicFormatter<char, CustomArgFormatter> &f,
fmt::FormatSpec &s, const char *fmt)
: fmt::BasicArgFormatter<CustomArgFormatter, char>(f, s, fmt) {}
void visit_int(int value) {
if (spec().type() == 'x')
visit_uint(value); // convert to unsigned and format
else
fmt::BasicArgFormatter<CustomArgFormatter, char>::visit_int(value);
}
};
std::string custom_format(const char *format_str, fmt::ArgList args) {
fmt::MemoryWriter writer;
// Pass custom argument formatter as a template arg to BasicFormatter.
fmt::BasicFormatter<char, CustomArgFormatter> formatter(args, writer);
formatter.format(format_str);
return writer.str();
}
FMT_VARIADIC(std::string, custom_format, const char *)
std::string s = custom_format("{:x}", -42); // s == "ffffffd6"
.. doxygenclass:: fmt::ArgVisitor
:members:
.. doxygenclass:: fmt::BasicArgFormatter
:members:
.. doxygenclass:: fmt::ArgFormatter
:members:
Printf formatting
Literal-Based API
-----------------
The header ``fmt/printf.h`` provides ``printf``-like formatting functionality.
The following functions use `printf format string syntax
<http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html>`_ with
the POSIX extension for positional arguments. Unlike their standard
counterparts, the ``fmt`` functions are type-safe and throw an exception if an
argument type doesn't match its format specification.
The following user-defined literals are defined in ``fmt/format.h``.
.. doxygenfunction:: printf(CStringRef, ArgList)
.. doxygenfunction:: fprintf(std::FILE *, CStringRef, ArgList)
.. doxygenfunction:: fprintf(std::ostream&, CStringRef, ArgList)
.. doxygenfunction:: sprintf(CStringRef, ArgList)
.. doxygenclass:: fmt::PrintfFormatter
:members:
.. doxygenclass:: fmt::BasicPrintfArgFormatter
:members:
.. doxygenclass:: fmt::PrintfArgFormatter
:members:
Write API
=========
The write API provides classes for writing formatted data into character
streams. It is usually faster than the `format API`_ but, as IOStreams,
may result in larger compiled code size. The main writer class is
`~fmt::BasicMemoryWriter` which stores its output in a memory buffer and
provides direct access to it. It is possible to create custom writers that
store output elsewhere by subclassing `~fmt::BasicWriter`.
.. doxygenclass:: fmt::BasicWriter
:members:
.. doxygenclass:: fmt::BasicMemoryWriter
:members:
.. doxygenclass:: fmt::BasicArrayWriter
:members:
.. doxygenclass:: fmt::BasicStringWriter
:members:
.. doxygenclass:: fmt::BasicContainerWriter
:members:
.. doxygenfunction:: bin(int)
.. doxygenfunction:: oct(int)
.. doxygenfunction:: hex(int)
.. doxygenfunction:: hexu(int)
.. doxygenfunction:: pad(int, unsigned, Char)
.. doxygenfunction:: operator""_a()
Utilities
=========
---------
.. doxygenfunction:: fmt::arg(StringRef, const T&)
.. doxygenfunction:: fmt::ptr(T p) -> const void*
.. doxygenfunction:: fmt::ptr(const std::unique_ptr<T, Deleter> &p) -> const void*
.. doxygenfunction:: fmt::ptr(const std::shared_ptr<T> &p) -> const void*
.. doxygenfunction:: operator""_a(const char *, std::size_t)
.. doxygenfunction:: fmt::underlying(Enum e) -> typename std::underlying_type<Enum>::type
.. doxygendefine:: FMT_CAPTURE
.. doxygenfunction:: fmt::to_string(const T &value) -> std::string
.. doxygendefine:: FMT_VARIADIC
.. doxygenfunction:: fmt::join(Range &&range, string_view sep) -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>>
.. doxygenclass:: fmt::ArgList
.. doxygenfunction:: fmt::join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel>
.. doxygenfunction:: fmt::group_digits(T value) -> group_digits_view<T>
.. doxygenclass:: fmt::detail::buffer
:members:
.. doxygenfunction:: fmt::to_string(const T&)
.. doxygenfunction:: fmt::to_wstring(const T&)
.. doxygenclass:: fmt::BasicStringRef
:members:
.. doxygenclass:: fmt::BasicCStringRef
:members:
.. doxygenclass:: fmt::Buffer
.. doxygenclass:: fmt::basic_memory_buffer
:protected-members:
:members:
System errors
=============
System Errors
-------------
.. doxygenclass:: fmt::SystemError
:members:
{fmt} does not use ``errno`` to communicate errors to the user, but it may call
system functions which set ``errno``. Users should not make any assumptions
about the value of ``errno`` being preserved by library functions.
.. doxygenfunction:: fmt::system_error
.. doxygenfunction:: fmt::format_system_error
.. doxygenclass:: fmt::WindowsError
:members:
Custom Allocators
-----------------
.. _formatstrings:
Custom allocators
=================
The fmt library supports custom dynamic memory allocators.
The {fmt} library supports custom dynamic memory allocators.
A custom allocator class can be specified as a template argument to
:class:`fmt::BasicMemoryWriter`::
:class:`fmt::basic_memory_buffer`::
typedef fmt::BasicMemoryWriter<char, CustomAllocator> CustomMemoryWriter;
using custom_memory_buffer =
fmt::basic_memory_buffer<char, fmt::inline_buffer_size, custom_allocator>;
It is also possible to write a formatting function that uses a custom
allocator::
typedef std::basic_string<char, std::char_traits<char>, CustomAllocator>
CustomString;
using custom_string =
std::basic_string<char, std::char_traits<char>, custom_allocator>;
CustomString format(CustomAllocator alloc, fmt::CStringRef format_str,
fmt::ArgList args) {
CustomMemoryWriter writer(alloc);
writer.write(format_str, args);
return CustomString(writer.data(), writer.size(), alloc);
custom_string vformat(custom_allocator alloc, fmt::string_view format_str,
fmt::format_args args) {
auto buf = custom_memory_buffer(alloc);
fmt::vformat_to(std::back_inserter(buf), format_str, args);
return custom_string(buf.data(), buf.size(), alloc);
}
FMT_VARIADIC(CustomString, format, CustomAllocator, fmt::CStringRef)
template <typename ...Args>
inline custom_string format(custom_allocator alloc,
fmt::string_view format_str,
const Args& ... args) {
return vformat(alloc, format_str, fmt::make_format_args(args...));
}
The allocator will be used for the output container only. Formatting functions
normally don't do any allocations for built-in and string types except for
non-default floating-point formatting that occasionally falls back on
``sprintf``.
Locale
------
All formatting is locale-independent by default. Use the ``'L'`` format
specifier to insert the appropriate number separator characters from the
locale::
#include <fmt/core.h>
#include <locale>
std::locale::global(std::locale("en_US.UTF-8"));
auto s = fmt::format("{:L}", 1000000); // s == "1,000,000"
``fmt/format.h`` provides the following overloads of formatting functions that
take ``std::locale`` as a parameter. The locale type is a template parameter to
avoid the expensive ``<locale>`` include.
.. doxygenfunction:: format(const Locale& loc, format_string<T...> fmt, T&&... args) -> std::string
.. doxygenfunction:: format_to(OutputIt out, const Locale& loc, format_string<T...> fmt, T&&... args) -> OutputIt
.. doxygenfunction:: formatted_size(const Locale& loc, format_string<T...> fmt, T&&... args) -> size_t
.. _legacy-checks:
Legacy Compile-Time Format String Checks
----------------------------------------
``FMT_STRING`` enables compile-time checks on older compilers. It requires C++14
or later and is a no-op in C++11.
.. doxygendefine:: FMT_STRING
To force the use of legacy compile-time checks, define the preprocessor variable
``FMT_ENFORCE_COMPILE_STRING``. When set, functions accepting ``FMT_STRING``
will fail to compile with regular strings.
.. _ranges-api:
Range and Tuple Formatting
==========================
The library also supports convenient formatting of ranges and tuples::
#include <fmt/ranges.h>
std::tuple<char, int, float> t{'a', 1, 2.0f};
// Prints "('a', 1, 2.0)"
fmt::print("{}", t);
NOTE: currently, the overload of ``fmt::join`` for iterables exists in the main
``format.h`` header, but expect this to change in the future.
Using ``fmt::join``, you can separate tuple elements with a custom separator::
#include <fmt/ranges.h>
std::tuple<int, char> t = {1, 'a'};
// Prints "1, a"
fmt::print("{}", fmt::join(t, ", "));
.. _chrono-api:
Date and Time Formatting
========================
``fmt/chrono.h`` provides formatters for
* `std::chrono::duration <https://en.cppreference.com/w/cpp/chrono/duration>`_
* `std::chrono::time_point
<https://en.cppreference.com/w/cpp/chrono/time_point>`_
* `std::tm <https://en.cppreference.com/w/cpp/chrono/c/tm>`_
The format syntax is described in :ref:`chrono-specs`.
**Example**::
#include <fmt/chrono.h>
int main() {
std::time_t t = std::time(nullptr);
// Prints "The date is 2020-11-07." (with the current date):
fmt::print("The date is {:%Y-%m-%d}.", fmt::localtime(t));
using namespace std::literals::chrono_literals;
// Prints "Default format: 42s 100ms":
fmt::print("Default format: {} {}\n", 42s, 100ms);
// Prints "strftime-like format: 03:15:30":
fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
}
.. doxygenfunction:: localtime(std::time_t time)
.. doxygenfunction:: gmtime(std::time_t time)
.. _std-api:
Standard Library Types Formatting
=================================
``fmt/std.h`` provides formatters for:
* `std::filesystem::path <https://en.cppreference.com/w/cpp/filesystem/path>`_
* `std::thread::id <https://en.cppreference.com/w/cpp/thread/thread/id>`_
* `std::monostate <https://en.cppreference.com/w/cpp/utility/variant/monostate>`_
* `std::variant <https://en.cppreference.com/w/cpp/utility/variant/variant>`_
* `std::optional <https://en.cppreference.com/w/cpp/utility/optional>`_
Formatting Variants
-------------------
A ``std::variant`` is only formattable if every variant alternative is formattable, and requires the
``__cpp_lib_variant`` `library feature <https://en.cppreference.com/w/cpp/feature_test>`_.
**Example**::
#include <fmt/std.h>
std::variant<char, float> v0{'x'};
// Prints "variant('x')"
fmt::print("{}", v0);
std::variant<std::monostate, char> v1;
// Prints "variant(monostate)"
.. _compile-api:
Format String Compilation
=========================
``fmt/compile.h`` provides format string compilation enabled via the
``FMT_COMPILE`` macro or the ``_cf`` user-defined literal. Format strings
marked with ``FMT_COMPILE`` or ``_cf`` are parsed, checked and converted into
efficient formatting code at compile-time. This supports arguments of built-in
and string types as well as user-defined types with ``format`` functions taking
the format context type as a template parameter in their ``formatter``
specializations. For example::
template <> struct fmt::formatter<point> {
constexpr auto parse(format_parse_context& ctx);
template <typename FormatContext>
auto format(const point& p, FormatContext& ctx) const;
};
Format string compilation can generate more binary code compared to the default
API and is only recommended in places where formatting is a performance
bottleneck.
.. doxygendefine:: FMT_COMPILE
.. doxygenfunction:: operator""_cf()
.. _color-api:
Terminal Color and Text Style
=============================
``fmt/color.h`` provides support for terminal color and text style output.
.. doxygenfunction:: print(const text_style &ts, const S &format_str, const Args&... args)
.. doxygenfunction:: fg(detail::color_type)
.. doxygenfunction:: bg(detail::color_type)
.. doxygenfunction:: styled(const T& value, text_style ts)
.. _os-api:
System APIs
===========
.. doxygenclass:: fmt::ostream
:members:
.. doxygenfunction:: fmt::windows_error
:members:
.. _ostream-api:
``std::ostream`` Support
========================
``fmt/ostream.h`` provides ``std::ostream`` support including formatting of
user-defined types that have an overloaded insertion operator (``operator<<``).
In order to make a type formattable via ``std::ostream`` you should provide a
``formatter`` specialization inherited from ``ostream_formatter``::
#include <fmt/ostream.h>
struct date {
int year, month, day;
friend std::ostream& operator<<(std::ostream& os, const date& d) {
return os << d.year << '-' << d.month << '-' << d.day;
}
};
template <> struct fmt::formatter<date> : ostream_formatter {};
std::string s = fmt::format("The date is {}", date{2012, 12, 9});
// s == "The date is 2012-12-9"
.. doxygenfunction:: streamed(const T &)
.. doxygenfunction:: print(std::ostream &os, format_string<T...> fmt, T&&... args)
.. _printf-api:
``printf`` Formatting
=====================
The header ``fmt/printf.h`` provides ``printf``-like formatting functionality.
The following functions use `printf format string syntax
<https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html>`_ with
the POSIX extension for positional arguments. Unlike their standard
counterparts, the ``fmt`` functions are type-safe and throw an exception if an
argument type doesn't match its format specification.
.. doxygenfunction:: printf(string_view fmt, const T&... args) -> int
.. doxygenfunction:: fprintf(std::FILE *f, const S &fmt, const T&... args) -> int
.. doxygenfunction:: sprintf(const S&, const T&...)
.. _xchar-api:
``wchar_t`` Support
===================
The optional header ``fmt/xchar.h`` provides support for ``wchar_t`` and exotic
character types.
.. doxygenstruct:: fmt::is_char
.. doxygentypedef:: fmt::wstring_view
.. doxygentypedef:: fmt::wformat_context
.. doxygenfunction:: fmt::to_wstring(const T &value)
Compatibility with C++20 ``std::format``
========================================
{fmt} implements nearly all of the `C++20 formatting library
<https://en.cppreference.com/w/cpp/utility/format>`_ with the following
differences:
* Names are defined in the ``fmt`` namespace instead of ``std`` to avoid
collisions with standard library implementations.
* Width calculation doesn't use grapheme clusterization. The latter has been
implemented in a separate branch but hasn't been integrated yet.
* Most C++20 chrono types are not supported yet.

View File

@ -90,12 +90,14 @@
VERSION: '{{ release|e }}',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
LINK_SUFFIX: '{{ link_suffix }}',
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}',
HAS_SOURCE: {{ has_source|lower }},
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{{ js_tag(scriptfile) }}
{%- endfor %}
{%- endmacro %}

View File

@ -1,81 +1,57 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Build the documentation.
from __future__ import print_function
import errno, os, shutil, sys, tempfile
from subprocess import check_call, check_output, CalledProcessError, Popen, PIPE
from distutils.version import LooseVersion
import errno, os, re, sys
from subprocess import check_call, CalledProcessError, Popen, PIPE, STDOUT
versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0']
versions = ['1.0.0', '1.1.0', '2.0.0', '3.0.2', '4.0.0', '4.1.0', '5.0.0', '5.1.0', '5.2.0', '5.2.1', '5.3.0', '6.0.0', '6.1.0', '6.1.1', '6.1.2', '6.2.0', '6.2.1', '7.0.0', '7.0.1', '7.0.2', '7.0.3', '7.1.0', '7.1.1', '7.1.2', '7.1.3', '8.0.0', '8.0.1', '8.1.0', '8.1.1', '9.0.0', '9.1.0', '10.0.0', '10.1.0', '10.1.1']
def pip_install(package, commit=None, **kwargs):
"Install package using pip."
min_version = kwargs.get('min_version')
if min_version:
from pkg_resources import get_distribution, DistributionNotFound
try:
installed_version = get_distribution(os.path.basename(package)).version
if LooseVersion(installed_version) >= min_version:
print('{} {} already installed'.format(package, min_version))
return
except DistributionNotFound:
pass
if commit:
package = 'git+https://github.com/{0}.git@{1}'.format(package, commit)
print('Installing {0}'.format(package))
check_call(['pip', 'install', package])
class Pip:
def __init__(self, venv_dir):
self.path = os.path.join(venv_dir, 'bin', 'pip')
def create_build_env(dirname='virtualenv'):
def install(self, package, commit=None):
"Install package using pip."
if commit:
package = 'git+https://github.com/{0}.git@{1}'.format(package, commit)
print('Installing {0}'.format(package))
check_call([self.path, 'install', package])
def create_build_env(venv_dir='virtualenv'):
# Create virtualenv.
if not os.path.exists(dirname):
check_call(['virtualenv', dirname])
import sysconfig
scripts_dir = os.path.basename(sysconfig.get_path('scripts'))
activate_this_file = os.path.join(dirname, scripts_dir, 'activate_this.py')
with open(activate_this_file) as f:
exec(f.read(), dict(__file__=activate_this_file))
# Import get_distribution after activating virtualenv to get info about
# the correct packages.
from pkg_resources import get_distribution, DistributionNotFound
# Upgrade pip because installation of sphinx with pip 1.1 available on Travis
# is broken (see #207) and it doesn't support the show command.
pip_version = get_distribution('pip').version
if LooseVersion(pip_version) < LooseVersion('1.5.4'):
print("Updating pip")
check_call(['pip', 'install', '--upgrade', 'pip'])
# Upgrade distribute because installation of sphinx with distribute 0.6.24
# available on Travis is broken (see #207).
try:
distribute_version = get_distribution('distribute').version
if LooseVersion(distribute_version) <= LooseVersion('0.6.24'):
print("Updating distribute")
check_call(['pip', 'install', '--upgrade', 'distribute'])
except DistributionNotFound:
pass
# Install Sphinx and Breathe.
pip_install('sphinx-doc/sphinx', '12b83372ac9316e8cbe86e7fed889296a4cc29ee',
min_version='1.4.1.dev20160531')
pip_install('michaeljones/breathe',
'6b1c5bb7a1866f15fc328b8716258354b10c1daa',
min_version='4.2.0')
if not os.path.exists(venv_dir):
check_call(['python3', '-m', 'venv', venv_dir])
# Install Sphinx and Breathe. Require the exact version of Sphinx which is
# compatible with Breathe.
pip = Pip(venv_dir)
pip.install('wheel')
pip.install('six')
# See: https://github.com/sphinx-doc/sphinx/issues/9777
pip.install('docutils==0.17.1')
# Jinja2 >= 3.1 incompatible with sphinx 3.3.0
# See: https://github.com/sphinx-doc/sphinx/issues/10291
pip.install('Jinja2<3.1')
pip.install('sphinx-doc/sphinx', 'v3.3.0')
pip.install('michaeljones/breathe', 'v4.25.0')
def build_docs(version='dev', **kwargs):
doc_dir = kwargs.get('doc_dir', os.path.dirname(os.path.realpath(__file__)))
work_dir = kwargs.get('work_dir', '.')
include_dir = kwargs.get('include_dir',
os.path.join(os.path.dirname(doc_dir), 'fmt'))
include_dir = kwargs.get(
'include_dir', os.path.join(os.path.dirname(doc_dir), 'include', 'fmt'))
# Build docs.
cmd = ['doxygen', '-']
p = Popen(cmd, stdin=PIPE)
p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
doxyxml_dir = os.path.join(work_dir, 'doxyxml')
p.communicate(input=r'''
out, _ = p.communicate(input=r'''
PROJECT_NAME = fmt
GENERATE_LATEX = NO
GENERATE_MAN = NO
GENERATE_RTF = NO
CASE_SENSE_NAMES = NO
INPUT = {0}/container.h {0}/format.h {0}/ostream.h \
{0}/printf.h {0}/string.h
INPUT = {0}/args.h {0}/chrono.h {0}/color.h {0}/core.h \
{0}/compile.h {0}/format.h {0}/os.h {0}/ostream.h \
{0}/printf.h {0}/xchar.h
QUIET = YES
JAVADOC_AUTOBRIEF = YES
AUTOLINK_SUPPORT = NO
@ -86,23 +62,49 @@ def build_docs(version='dev', **kwargs):
ALIASES += "endrst=\endverbatim"
MACRO_EXPANSION = YES
PREDEFINED = _WIN32=1 \
__linux__=1 \
FMT_ENABLE_IF(...)= \
FMT_USE_VARIADIC_TEMPLATES=1 \
FMT_USE_RVALUE_REFERENCES=1 \
FMT_USE_USER_DEFINED_LITERALS=1 \
FMT_API=
EXCLUDE_SYMBOLS = fmt::internal::* StringValue write_str
FMT_USE_ALIAS_TEMPLATES=1 \
FMT_USE_NONTYPE_TEMPLATE_ARGS=1 \
FMT_API= \
"FMT_BEGIN_NAMESPACE=namespace fmt {{" \
"FMT_END_NAMESPACE=}}" \
"FMT_STRING_ALIAS=1" \
"FMT_VARIADIC(...)=" \
"FMT_VARIADIC_W(...)=" \
"FMT_DOC=1"
EXCLUDE_SYMBOLS = fmt::formatter fmt::printf_formatter fmt::arg_join \
fmt::basic_format_arg::handle
'''.format(include_dir, doxyxml_dir).encode('UTF-8'))
out = out.decode('utf-8')
internal_symbols = [
'fmt::detail::.*',
'basic_data<>',
'fmt::type_identity'
]
noisy_warnings = [
'warning: (Compound|Member .* of class) (' + '|'.join(internal_symbols) + \
') is not documented.',
'warning: Internal inconsistency: .* does not belong to any container!'
]
for w in noisy_warnings:
out = re.sub('.*' + w + '\n', '', out)
print(out)
if p.returncode != 0:
raise CalledProcessError(p.returncode, cmd)
html_dir = os.path.join(work_dir, 'html')
main_versions = reversed(versions[-3:])
check_call(['sphinx-build',
check_call([os.path.join(work_dir, 'virtualenv', 'bin', 'sphinx-build'),
'-Dbreathe_projects.format=' + os.path.abspath(doxyxml_dir),
'-Dversion=' + version, '-Drelease=' + version,
'-Aversion=' + version, '-Aversions=' + ','.join(main_versions),
'-b', 'html', doc_dir, html_dir])
try:
check_call(['lessc', '--clean-css',
check_call(['lessc', '--verbose', '--clean-css',
'--include-path=' + os.path.join(doc_dir, 'bootstrap'),
os.path.join(doc_dir, 'fmt.less'),
os.path.join(html_dir, '_static', 'fmt.css')])

View File

@ -47,7 +47,7 @@ source_suffix = '.rst'
# General information about the project.
project = u'fmt'
copyright = u'2012-2015, Victor Zverovich'
copyright = u'2012-present, Victor Zverovich'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the

View File

@ -56,6 +56,11 @@ div.sphinxsidebar {
padding: 0;
}
// Override center alignment in tables.
td {
text-align: left;
}
p.rubric {
margin-top: 10px;
}

View File

@ -1,72 +1,68 @@
Overview
========
**fmt** (formerly cppformat) is an open-source formatting library.
It can be used as a safe alternative to printf or as a fast
alternative to C++ IOStreams.
**{fmt}** is an open-source formatting library providing a fast and safe
alternative to C stdio and C++ iostreams.
.. raw:: html
<div class="panel panel-default">
<div class="panel-heading">What users say:</div>
<div class="panel-body">
Thanks for creating this library. Its been a hole in C++ for a long
time. Ive used both boost::format and loki::SPrintf, and neither felt
like the right answer. This does.
Thanks for creating this library. Its been a hole in C++ for
a long time. Ive used both <code>boost::format</code> and
<code>loki::SPrintf</code>, and neither felt like the right answer.
This does.
</div>
</div>
.. _format-api:
.. _format-api-intro:
Format API
----------
The replacement-based Format API provides a safe alternative to ``printf``,
``sprintf`` and friends with comparable or `better performance
<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_.
The format API is similar in spirit to the C ``printf`` family of function but
is safer, simpler and several times `faster
<https://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
than common standard library implementations.
The `format string syntax <syntax.html>`_ is similar to the one used by
`str.format <http://docs.python.org/2/library/stdtypes.html#str.format>`_
in Python:
`str.format <https://docs.python.org/3/library/stdtypes.html#str.format>`_ in
Python:
.. code:: c++
fmt::format("The answer is {}", 42);
std::string s = fmt::format("The answer is {}.", 42);
The ``fmt::format`` function returns a string "The answer is 42". You can use
``fmt::MemoryWriter`` to avoid constructing ``std::string``:
The ``fmt::format`` function returns a string "The answer is 42.". You can use
``fmt::memory_buffer`` to avoid constructing ``std::string``:
.. code:: c++
fmt::MemoryWriter w;
w.write("Look, a {} string", 'C');
w.c_str(); // returns a C string (const char*)
auto out = fmt::memory_buffer();
fmt::format_to(std::back_inserter(out),
"For a moment, {} happened.", "nothing");
auto data = out.data(); // pointer to the formatted data
auto size = out.size(); // size of the formatted data
The ``fmt::print`` function performs formatting and writes the result to a file:
The ``fmt::print`` function performs formatting and writes the result to a stream:
.. code:: c++
fmt::print(stderr, "System error code = {}\n", errno);
The file argument can be omitted in which case the function prints to
``stdout``:
If you omit the file argument the function will print to ``stdout``:
.. code:: c++
fmt::print("Don't {}\n", "panic");
If your compiler supports C++11, then the formatting functions are implemented
with variadic templates. Otherwise variadic functions are emulated by generating
a set of lightweight wrappers. This ensures compatibility with older compilers
while providing a natural API.
The Format API also supports positional arguments useful for localization:
The format API also supports positional arguments useful for localization:
.. code:: c++
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
Named arguments can be created with ``fmt::arg``. This makes it easier to track
what goes where when multiple values are being inserted:
You can pass named arguments with ``fmt::arg``:
.. code:: c++
@ -78,135 +74,125 @@ an alternative, slightly terser syntax for named arguments:
.. code:: c++
using namespace fmt::literals;
fmt::print("Hello, {name}! The answer is {number}. Goodbye, {name}.",
"name"_a="World", "number"_a=42);
The ``_format`` suffix may be used to format string literals similar to Python:
.. code:: c++
std::string message = "{0}{1}{0}"_format("abra", "cad");
Other than the placement of the format string on the left of the operator,
``_format`` is functionally identical to ``fmt::format``. In order to use the
literal operators, they must be made visible with the directive
``using namespace fmt::literals;``. Note that this brings in only ``_a`` and
``_format`` but nothing else from the ``fmt`` namespace.
.. _write-api:
Write API
---------
The concatenation-based Write API (experimental) provides a `fast
<http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html>`_
stateless alternative to IOStreams:
.. code:: c++
fmt::MemoryWriter out;
out << "The answer in hexadecimal is " << hex(42);
.. _safety:
Safety
------
The library is fully type safe, automatic memory management prevents buffer
overflow, errors in format strings are reported using exceptions. For example,
the code
overflow, errors in format strings are reported using exceptions or at compile
time. For example, the code
.. code:: c++
fmt::format("The answer is {:d}", "forty-two");
throws a ``FormatError`` exception with description
"unknown format code 'd' for string", because the argument
``"forty-two"`` is a string while the format code ``d``
only applies to integers.
throws the ``format_error`` exception because the argument ``"forty-two"`` is a
string while the format code ``d`` only applies to integers.
Where possible, errors are caught at compile time. For example, the code
The code
.. code:: c++
format(FMT_STRING("The answer is {:d}"), "forty-two");
reports a compile-time error on compilers that support relaxed ``constexpr``.
See `here <api.html#compile-time-format-string-checks>`_ for details.
The following code
.. code:: c++
fmt::format("Cyrillic letter {}", L'\x42e');
produces a compile-time error because wide character ``L'\x42e'`` cannot be
formatted into a narrow string. You can use a wide format string instead:
formatted into a narrow string. For comparison, writing a wide character to
``std::ostream`` results in its numeric value being written to the stream
(i.e. 1070 instead of letter 'ю' which is represented by ``L'\x42e'`` if we
use Unicode) which is rarely desirable.
Compact Binary Code
-------------------
The library produces compact per-call compiled code. For example
(`godbolt <https://godbolt.org/g/TZU4KF>`_),
.. code:: c++
fmt::format(L"Cyrillic letter {}", L'\x42e');
#include <fmt/core.h>
For comparison, writing a wide character to ``std::ostream`` results in
its numeric value being written to the stream (i.e. 1070 instead of letter 'ю'
which is represented by ``L'\x42e'`` if we use Unicode) which is rarely what is
needed.
int main() {
fmt::print("The answer is {}.", 42);
}
Note that fmt does not use the value of the ``errno`` global to communicate
errors to the user, but it may call system functions which set ``errno``. Since
fmt does not attempt to preserve the value of ``errno``, users should not make
any assumptions about it and always set it to ``0`` before making any system
calls that convey error information via ``errno``.
compiles to just
.. code:: asm
main: # @main
sub rsp, 24
mov qword ptr [rsp], 42
mov rcx, rsp
mov edi, offset .L.str
mov esi, 17
mov edx, 1
call fmt::v7::vprint(fmt::v7::basic_string_view<char>, fmt::v7::format_args)
xor eax, eax
add rsp, 24
ret
.L.str:
.asciz "The answer is {}."
.. _portability:
Portability
-----------
The library is highly portable. Here is an incomplete list of operating systems
and compilers where it has been tested and known to work:
The library is highly portable and relies only on a small set of C++11 features:
* 64-bit (amd64) GNU/Linux with GCC 4.4.3,
`4.6.3 <https://travis-ci.org/fmtlib/fmt>`_, 4.7.2, 4.8.1, and Intel C++
Compiler (ICC) 14.0.2
* variadic templates
* type traits
* rvalue references
* decltype
* trailing return types
* deleted functions
* alias templates
* 32-bit (i386) GNU/Linux with GCC 4.4.3, 4.6.3
These are available in GCC 4.8, Clang 3.4, MSVC 19.0 (2015) and more recent
compiler version. For older compilers use {fmt} `version 4.x
<https://github.com/fmtlib/fmt/releases/tag/4.1.0>`_ which is maintained and
only requires C++98.
* Mac OS X with GCC 4.2.1 and Clang 4.2, 5.1.0
* 64-bit Windows with Visual C++ 2010, 2013 and
`2015 <https://ci.appveyor.com/project/vitaut/fmt>`_
* 32-bit Windows with Visual C++ 2010
Although the library uses C++11 features when available, it also works with
older compilers and standard library implementations. The only thing to keep in
mind for C++98 portability:
* Variadic templates: minimum GCC 4.4, Clang 2.9 or VS2013. This feature allows
the Format API to accept an unlimited number of arguments. With older
compilers the maximum is 15.
* User-defined literals: minimum GCC 4.7, Clang 3.1 or VS2015. The suffixes
``_format`` and ``_a`` are functionally equivalent to the functions
``fmt::format`` and ``fmt::arg``.
The output of all formatting functions is consistent across platforms. In
particular, formatting a floating-point infinity always gives ``inf`` while the
output of ``printf`` is platform-dependent in this case. For example,
The output of all formatting functions is consistent across platforms.
For example,
.. code::
fmt::print("{}", std::numeric_limits<double>::infinity());
always prints ``inf``.
always prints ``inf`` while the output of ``printf`` is platform-dependent.
.. _ease-of-use:
Ease of Use
-----------
fmt has a small self-contained code base with the core library consisting of
a single header file and a single source file and no external dependencies.
A permissive BSD `license <https://github.com/fmtlib/fmt#license>`_ allows
{fmt} has a small self-contained code base with the core library consisting of
just three header files and no external dependencies.
A permissive MIT `license <https://github.com/fmtlib/fmt#license>`_ allows
using the library both in open-source and commercial projects.
`Learn more... <contents.html>`_
.. raw:: html
<a class="btn btn-success" href="https://github.com/fmtlib/fmt">GitHub Repository</a>
<div class="section footer">
<iframe src="http://ghbtns.com/github-btn.html?user=fmtlib&amp;repo=fmt&amp;type=watch&amp;count=true"
<iframe src="https://ghbtns.com/github-btn.html?user=fmtlib&amp;repo=fmt&amp;type=watch&amp;count=true"
class="github-btn" width="100" height="20"></iframe>
</div>

View File

@ -4,8 +4,9 @@
Format String Syntax
********************
Formatting functions such as :ref:`fmt::format() <format>` and :ref:`fmt::print() <print>`
use the same format string syntax described in this section.
Formatting functions such as :ref:`fmt::format() <format>` and
:ref:`fmt::print() <print>` use the same format string syntax described in this
section.
Format strings contain "replacement fields" surrounded by curly braces ``{}``.
Anything that is not contained in braces is considered literal text, which is
@ -15,7 +16,7 @@ literal text, it can be escaped by doubling: ``{{`` and ``}}``.
The grammar for a replacement field is as follows:
.. productionlist:: sf
replacement_field: "{" [`arg_id`] [":" `format_spec`] "}"
replacement_field: "{" [`arg_id`] [":" (`format_spec` | `chrono_format_spec`)] "}"
arg_id: `integer` | `identifier`
integer: `digit`+
digit: "0"..."9"
@ -26,8 +27,8 @@ The grammar for a replacement field is as follows:
In less formal terms, the replacement field can start with an *arg_id*
that specifies the argument whose value is to be formatted and inserted into
the output instead of the replacement field.
The *arg_id* is optionally followed by a *format_spec*, which is preceded
by a colon ``':'``. These specify a non-default format for the replacement value.
The *arg_id* is optionally followed by a *format_spec*, which is preceded by a
colon ``':'``. These specify a non-default format for the replacement value.
See also the :ref:`formatspec` section.
@ -53,8 +54,8 @@ described in the next section.
A *format_spec* field can also include nested replacement fields in certain
positions within it. These nested replacement fields can contain only an
argument id; format specifications are not allowed. This allows the
formatting of a value to be dynamically specified.
argument id; format specifications are not allowed. This allows the formatting
of a value to be dynamically specified.
See the :ref:`formatexamples` section for some examples.
@ -74,20 +75,20 @@ although some of the formatting options are only supported by the numeric types.
The general form of a *standard format specifier* is:
.. productionlist:: sf
format_spec: [[`fill`]`align`][`sign`]["#"]["0"][`width`]["." `precision`][`type`]
format_spec: [[`fill`]`align`][`sign`]["#"]["0"][`width`]["." `precision`]["L"][`type`]
fill: <a character other than '{' or '}'>
align: "<" | ">" | "=" | "^"
align: "<" | ">" | "^"
sign: "+" | "-" | " "
width: `integer` | "{" `arg_id` "}"
precision: `integer` | "{" `arg_id` "}"
type: `int_type` | "a" | "A" | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "p" | "s"
int_type: "b" | "B" | "d" | "n" | "o" | "x" | "X"
width: `integer` | "{" [`arg_id`] "}"
precision: `integer` | "{" [`arg_id`] "}"
type: "a" | "A" | "b" | "B" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" |
: "o" | "p" | "s" | "x" | "X"
The *fill* character can be any character other than '{' or '}'. The presence
of a fill character is signaled by the character following it, which must be
one of the alignment options. If the second character of *format_spec* is not
a valid alignment option, then it is assumed that both the fill character and
the alignment option are absent.
The *fill* character can be any Unicode code point other than ``'{'`` or
``'}'``. The presence of a fill character is signaled by the character following
it, which must be one of the alignment options. If the second character of
*format_spec* is not a valid alignment option, then it is assumed that both the
fill character and the alignment option are absent.
The meaning of the various alignment options is as follows:
@ -100,11 +101,6 @@ The meaning of the various alignment options is as follows:
| ``'>'`` | Forces the field to be right-aligned within the |
| | available space (this is the default for numbers). |
+---------+----------------------------------------------------------+
| ``'='`` | Forces the padding to be placed after the sign (if any) |
| | but before the digits. This is used for printing fields |
| | in the form '+000000120'. This alignment option is only |
| | valid for numeric types. |
+---------+----------------------------------------------------------+
| ``'^'`` | Forces the field to be centered within the available |
| | space. |
+---------+----------------------------------------------------------+
@ -113,21 +109,21 @@ Note that unless a minimum field width is defined, the field width will always
be the same size as the data to fill it, so that the alignment option has no
meaning in this case.
The *sign* option is only valid for number types, and can be one of the
following:
The *sign* option is only valid for floating point and signed integer types,
and can be one of the following:
+---------+----------------------------------------------------------+
| Option | Meaning |
+=========+==========================================================+
| ``'+'`` | indicates that a sign should be used for both |
| | positive as well as negative numbers. |
+---------+----------------------------------------------------------+
| ``'-'`` | indicates that a sign should be used only for negative |
| | numbers (this is the default behavior). |
+---------+----------------------------------------------------------+
| space | indicates that a leading space should be used on |
| | positive numbers, and a minus sign on negative numbers. |
+---------+----------------------------------------------------------+
+---------+------------------------------------------------------------+
| Option | Meaning |
+=========+============================================================+
| ``'+'`` | indicates that a sign should be used for both |
| | nonnegative as well as negative numbers. |
+---------+------------------------------------------------------------+
| ``'-'`` | indicates that a sign should be used only for negative |
| | numbers (this is the default behavior). |
+---------+------------------------------------------------------------+
| space | indicates that a leading space should be used on |
| | nonnegative numbers, and a minus sign on negative numbers. |
+---------+------------------------------------------------------------+
The ``'#'`` option causes the "alternate form" to be used for the
conversion. The alternate form is defined differently for different
@ -147,15 +143,17 @@ conversions, trailing zeros are not removed from the result.
.. ifconfig:: False
The ``','`` option signals the use of a comma for a thousands separator.
For a locale aware separator, use the ``'n'`` integer presentation type
For a locale aware separator, use the ``'L'`` integer presentation type
instead.
*width* is a decimal integer defining the minimum field width. If not
specified, then the field width will be determined by the content.
Preceding the *width* field by a zero (``'0'``) character enables
sign-aware zero-padding for numeric types. This is equivalent to a *fill*
character of ``'0'`` with an *alignment* type of ``'='``.
Preceding the *width* field by a zero (``'0'``) character enables sign-aware
zero-padding for numeric types. It forces the padding to be placed after the
sign or base (if any) but before the digits. This is used for printing fields in
the form '+000000120'. This option is only valid for numeric types and it has no
effect on formatting of infinity and NaN.
The *precision* is a decimal number indicating how many digits should be
displayed after the decimal point for a floating-point value formatted with
@ -163,7 +161,11 @@ displayed after the decimal point for a floating-point value formatted with
value formatted with ``'g'`` or ``'G'``. For non-number types the field
indicates the maximum field size - in other words, how many characters will be
used from the field content. The *precision* is not allowed for integer,
character, Boolean, and pointer values.
character, Boolean, and pointer values. Note that a C string must be
null-terminated even if precision is specified.
The ``'L'`` option uses the current locale setting to insert the appropriate
number separator characters. This option is only valid for numeric types.
Finally, the *type* determines how the data should be presented.
@ -202,6 +204,8 @@ The available integer presentation types are:
| | ``'#'`` option with this type adds the prefix ``"0B"`` |
| | to the output value. |
+---------+----------------------------------------------------------+
| ``'c'`` | Character format. Outputs the number as a character. |
+---------+----------------------------------------------------------+
| ``'d'`` | Decimal integer. Outputs the number in base 10. |
+---------+----------------------------------------------------------+
| ``'o'`` | Octal format. Outputs the number in base 8. |
@ -216,10 +220,6 @@ The available integer presentation types are:
| | ``'#'`` option with this type adds the prefix ``"0X"`` |
| | to the output value. |
+---------+----------------------------------------------------------+
| ``'n'`` | Number. This is the same as ``'d'``, except that it uses |
| | the current locale setting to insert the appropriate |
| | number separator characters. |
+---------+----------------------------------------------------------+
| none | The same as ``'d'``. |
+---------+----------------------------------------------------------+
@ -243,7 +243,7 @@ The available presentation types for floating-point values are:
| | notation using the letter 'e' to indicate the exponent. |
+---------+----------------------------------------------------------+
| ``'E'`` | Exponent notation. Same as ``'e'`` except it uses an |
| | upper-case 'E' as the separator character. |
| | upper-case ``'E'`` as the separator character. |
+---------+----------------------------------------------------------+
| ``'f'`` | Fixed point. Displays the number as a fixed-point |
| | number. |
@ -263,11 +263,10 @@ The available presentation types for floating-point values are:
| | ``'E'`` if the number gets too large. The |
| | representations of infinity and NaN are uppercased, too. |
+---------+----------------------------------------------------------+
| none | The same as ``'g'``. |
| none | Similar to ``'g'``, except that the default precision is |
| | as high as needed to represent the particular value. |
+---------+----------------------------------------------------------+
Floating-point formatting is locale-dependent.
.. ifconfig:: False
+---------+----------------------------------------------------------+
@ -300,9 +299,215 @@ The available presentation types for pointers are:
| none | The same as ``'p'``. |
+---------+----------------------------------------------------------+
.. _chrono-specs:
Chrono Format Specifications
============================
Format specifications for chrono duration and time point types as well as
``std::tm`` have the following syntax:
.. productionlist:: sf
chrono_format_spec: [[`fill`]`align`][`width`]["." `precision`][`chrono_specs`]
chrono_specs: [`chrono_specs`] `conversion_spec` | `chrono_specs` `literal_char`
conversion_spec: "%" [`modifier`] `chrono_type`
literal_char: <a character other than '{', '}' or '%'>
modifier: "E" | "O"
chrono_type: "a" | "A" | "b" | "B" | "c" | "C" | "d" | "D" | "e" | "F" |
: "g" | "G" | "h" | "H" | "I" | "j" | "m" | "M" | "n" | "p" |
: "q" | "Q" | "r" | "R" | "S" | "t" | "T" | "u" | "U" | "V" |
: "w" | "W" | "x" | "X" | "y" | "Y" | "z" | "Z" | "%"
Literal chars are copied unchanged to the output. Precision is valid only for
``std::chrono::duration`` types with a floating-point representation type.
The available presentation types (*chrono_type*) are:
+---------+--------------------------------------------------------------------+
| Type | Meaning |
+=========+====================================================================+
| ``'a'`` | The abbreviated weekday name, e.g. "Sat". If the value does not |
| | contain a valid weekday, an exception of type ``format_error`` is |
| | thrown. |
+---------+--------------------------------------------------------------------+
| ``'A'`` | The full weekday name, e.g. "Saturday". If the value does not |
| | contain a valid weekday, an exception of type ``format_error`` is |
| | thrown. |
+---------+--------------------------------------------------------------------+
| ``'b'`` | The abbreviated month name, e.g. "Nov". If the value does not |
| | contain a valid month, an exception of type ``format_error`` is |
| | thrown. |
+---------+--------------------------------------------------------------------+
| ``'B'`` | The full month name, e.g. "November". If the value does not |
| | contain a valid month, an exception of type ``format_error`` is |
| | thrown. |
+---------+--------------------------------------------------------------------+
| ``'c'`` | The date and time representation, e.g. "Sat Nov 12 22:04:00 1955". |
| | The modified command ``%Ec`` produces the locale's alternate date |
| | and time representation. |
+---------+--------------------------------------------------------------------+
| ``'C'`` | The year divided by 100 using floored division, e.g. "55". If the |
| | result is a single decimal digit, it is prefixed with 0. |
| | The modified command ``%EC`` produces the locale's alternative |
| | representation of the century. |
+---------+--------------------------------------------------------------------+
| ``'d'`` | The day of month as a decimal number. If the result is a single |
| | decimal digit, it is prefixed with 0. The modified command ``%Od`` |
| | produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'D'`` | Equivalent to ``%m/%d/%y``, e.g. "11/12/55". |
+---------+--------------------------------------------------------------------+
| ``'e'`` | The day of month as a decimal number. If the result is a single |
| | decimal digit, it is prefixed with a space. The modified command |
| | ``%Oe`` produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'F'`` | Equivalent to ``%Y-%m-%d``, e.g. "1955-11-12". |
+---------+--------------------------------------------------------------------+
| ``'g'`` | The last two decimal digits of the ISO week-based year. If the |
| | result is a single digit it is prefixed by 0. |
+---------+--------------------------------------------------------------------+
| ``'G'`` | The ISO week-based year as a decimal number. If the result is less |
| | than four digits it is left-padded with 0 to four digits. |
+---------+--------------------------------------------------------------------+
| ``'h'`` | Equivalent to ``%b``, e.g. "Nov". |
+---------+--------------------------------------------------------------------+
| ``'H'`` | The hour (24-hour clock) as a decimal number. If the result is a |
| | single digit, it is prefixed with 0. The modified command ``%OH`` |
| | produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'I'`` | The hour (12-hour clock) as a decimal number. If the result is a |
| | single digit, it is prefixed with 0. The modified command ``%OI`` |
| | produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'j'`` | If the type being formatted is a specialization of duration, the |
| | decimal number of days without padding. Otherwise, the day of the |
| | year as a decimal number. Jan 1 is 001. If the result is less than |
| | three digits, it is left-padded with 0 to three digits. |
+---------+--------------------------------------------------------------------+
| ``'m'`` | The month as a decimal number. Jan is 01. If the result is a |
| | single digit, it is prefixed with 0. The modified command ``%Om`` |
| | produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'M'`` | The minute as a decimal number. If the result is a single digit, |
| | it is prefixed with 0. The modified command ``%OM`` produces the |
| | locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'n'`` | A new-line character. |
+---------+--------------------------------------------------------------------+
| ``'p'`` | The AM/PM designations associated with a 12-hour clock. |
+---------+--------------------------------------------------------------------+
| ``'q'`` | The duration's unit suffix. |
+---------+--------------------------------------------------------------------+
| ``'Q'`` | The duration's numeric value (as if extracted via ``.count()``). |
+---------+--------------------------------------------------------------------+
| ``'r'`` | The 12-hour clock time, e.g. "10:04:00 PM". |
+---------+--------------------------------------------------------------------+
| ``'R'`` | Equivalent to ``%H:%M``, e.g. "22:04". |
+---------+--------------------------------------------------------------------+
| ``'S'`` | Seconds as a decimal number. If the number of seconds is less than |
| | 10, the result is prefixed with 0. If the precision of the input |
| | cannot be exactly represented with seconds, then the format is a |
| | decimal floating-point number with a fixed format and a precision |
| | matching that of the precision of the input (or to a microseconds |
| | precision if the conversion to floating-point decimal seconds |
| | cannot be made within 18 fractional digits). The character for the |
| | decimal point is localized according to the locale. The modified |
| | command ``%OS`` produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'t'`` | A horizontal-tab character. |
+---------+--------------------------------------------------------------------+
| ``'T'`` | Equivalent to ``%H:%M:%S``. |
+---------+--------------------------------------------------------------------+
| ``'u'`` | The ISO weekday as a decimal number (1-7), where Monday is 1. The |
| | modified command ``%Ou`` produces the locale's alternative |
| | representation. |
+---------+--------------------------------------------------------------------+
| ``'U'`` | The week number of the year as a decimal number. The first Sunday |
| | of the year is the first day of week 01. Days of the same year |
| | prior to that are in week 00. If the result is a single digit, it |
| | is prefixed with 0. The modified command ``%OU`` produces the |
| | locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'V'`` | The ISO week-based week number as a decimal number. If the result |
| | is a single digit, it is prefixed with 0. The modified command |
| | ``%OV`` produces the locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'w'`` | The weekday as a decimal number (0-6), where Sunday is 0. |
| | The modified command ``%Ow`` produces the locale's alternative |
| | representation. |
+---------+--------------------------------------------------------------------+
| ``'W'`` | The week number of the year as a decimal number. The first Monday |
| | of the year is the first day of week 01. Days of the same year |
| | prior to that are in week 00. If the result is a single digit, it |
| | is prefixed with 0. The modified command ``%OW`` produces the |
| | locale's alternative representation. |
+---------+--------------------------------------------------------------------+
| ``'x'`` | The date representation, e.g. "11/12/55". The modified command |
| | ``%Ex`` produces the locale's alternate date representation. |
+---------+--------------------------------------------------------------------+
| ``'X'`` | The time representation, e.g. "10:04:00". The modified command |
| | ``%EX`` produces the locale's alternate time representation. |
+---------+--------------------------------------------------------------------+
| ``'y'`` | The last two decimal digits of the year. If the result is a single |
| | digit it is prefixed by 0. The modified command ``%Oy`` produces |
| | the locale's alternative representation. The modified command |
| | ``%Ey`` produces the locale's alternative representation of offset |
| | from ``%EC`` (year only). |
+---------+--------------------------------------------------------------------+
| ``'Y'`` | The year as a decimal number. If the result is less than four |
| | digits it is left-padded with 0 to four digits. The modified |
| | command ``%EY`` produces the locale's alternative full year |
| | representation. |
+---------+--------------------------------------------------------------------+
| ``'z'`` | The offset from UTC in the ISO 8601:2004 format. For example -0430 |
| | refers to 4 hours 30 minutes behind UTC. If the offset is zero, |
| | +0000 is used. The modified commands ``%Ez`` and ``%Oz`` insert a |
| | ``:`` between the hours and minutes: -04:30. If the offset |
| | information is not available, an exception of type |
| | ``format_error`` is thrown. |
+---------+--------------------------------------------------------------------+
| ``'Z'`` | The time zone abbreviation. If the time zone abbreviation is not |
| | available, an exception of type ``format_error`` is thrown. |
+---------+--------------------------------------------------------------------+
| ``'%'`` | A % character. |
+---------+--------------------------------------------------------------------+
Specifiers that have a calendaric component such as ``'d'`` (the day of month)
are valid only for ``std::tm`` and time points but not durations.
.. range-specs:
Range Format Specifications
===========================
Format specifications for range types have the following syntax:
.. productionlist:: sf
range_format_spec: [":" [`underlying_spec`]]
The `underlying_spec` is parsed based on the formatter of the range's
reference type.
By default, a range of characters or strings is printed escaped and quoted. But
if any `underlying_spec` is provided (even if it is empty), then the characters
or strings are printed according to the provided specification.
Examples::
fmt::format("{}", std::vector{10, 20, 30});
// Result: [10, 20, 30]
fmt::format("{::#x}", std::vector{10, 20, 30});
// Result: [0xa, 0x14, 0x1e]
fmt::format("{}", vector{'h', 'e', 'l', 'l', 'o'});
// Result: ['h', 'e', 'l', 'l', 'o']
fmt::format("{::}", vector{'h', 'e', 'l', 'l', 'o'});
// Result: [h, e, l, l, o]
fmt::format("{::d}", vector{'h', 'e', 'l', 'l', 'o'});
// Result: [104, 101, 108, 108, 111]
.. _formatexamples:
Format examples
Format Examples
===============
This section contains examples of the format syntax and comparison with
@ -317,67 +522,94 @@ following examples.
Accessing arguments by position::
format("{0}, {1}, {2}", 'a', 'b', 'c');
fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
// Result: "a, b, c"
format("{}, {}, {}", 'a', 'b', 'c');
fmt::format("{}, {}, {}", 'a', 'b', 'c');
// Result: "a, b, c"
format("{2}, {1}, {0}", 'a', 'b', 'c');
fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
// Result: "c, b, a"
format("{0}{1}{0}", "abra", "cad"); // arguments' indices can be repeated
fmt::format("{0}{1}{0}", "abra", "cad"); // arguments' indices can be repeated
// Result: "abracadabra"
Aligning the text and specifying a width::
format("{:<30}", "left aligned");
fmt::format("{:<30}", "left aligned");
// Result: "left aligned "
format("{:>30}", "right aligned");
fmt::format("{:>30}", "right aligned");
// Result: " right aligned"
format("{:^30}", "centered");
fmt::format("{:^30}", "centered");
// Result: " centered "
format("{:*^30}", "centered"); // use '*' as a fill char
fmt::format("{:*^30}", "centered"); // use '*' as a fill char
// Result: "***********centered***********"
Dynamic width::
format("{:<{}}", "left aligned", 30);
fmt::format("{:<{}}", "left aligned", 30);
// Result: "left aligned "
Dynamic precision::
format("{:.{}f}", 3.14, 1);
fmt::format("{:.{}f}", 3.14, 1);
// Result: "3.1"
Replacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign::
format("{:+f}; {:+f}", 3.14, -3.14); // show it always
fmt::format("{:+f}; {:+f}", 3.14, -3.14); // show it always
// Result: "+3.140000; -3.140000"
format("{: f}; {: f}", 3.14, -3.14); // show a space for positive numbers
fmt::format("{: f}; {: f}", 3.14, -3.14); // show a space for positive numbers
// Result: " 3.140000; -3.140000"
format("{:-f}; {:-f}", 3.14, -3.14); // show only the minus -- same as '{:f}; {:f}'
fmt::format("{:-f}; {:-f}", 3.14, -3.14); // show only the minus -- same as '{:f}; {:f}'
// Result: "3.140000; -3.140000"
Replacing ``%x`` and ``%o`` and converting the value to different bases::
format("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
fmt::format("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
// Result: "int: 42; hex: 2a; oct: 52; bin: 101010"
// with 0x or 0 or 0b as prefix:
format("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}", 42);
// Result: "int: 42; hex: 0x2a; oct: 052; bin: 0b101010"
fmt::format("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}", 42);
// Result: "int: 42; hex: 0x2a; oct: 052; bin: 0b101010"
Padded hex byte with prefix and always prints both hex characters::
fmt::format("{:#04x}", 0);
// Result: "0x00"
Box drawing using Unicode fill::
fmt::print(
"┌{0:─^{2}}┐\n"
"│{1: ^{2}}│\n"
"└{0:─^{2}}┘\n", "", "Hello, world!", 20);
prints::
┌────────────────────┐
│ Hello, world! │
└────────────────────┘
Using type-specific formatting::
#include <fmt/chrono.h>
auto t = tm();
t.tm_year = 2010 - 1900;
t.tm_mon = 7;
t.tm_mday = 4;
t.tm_hour = 12;
t.tm_min = 15;
t.tm_sec = 58;
fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
// Prints: 2010-08-04 12:15:58
Using the comma as a thousands separator::
#include <fmt/format.h>
auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
// s == "1,234,567,890"
.. ifconfig:: False
Using the comma as a thousands separator::
format("{:,}", 1234567890);
'1,234,567,890'
Using type-specific formatting::
>>> import datetime
>>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)
Format("{:%Y-%m-%d %H:%M:%S}") << d)
'2010-07-04 12:15:58'
Nesting arguments and more complex examples::
>>> for align, text in zip('<^>', ['left', 'center', 'right']):
@ -406,4 +638,3 @@ Replacing ``%x`` and ``%o`` and converting the value to different bases::
9 9 11 1001
10 A 12 1010
11 B 13 1011

View File

@ -2,26 +2,20 @@
Usage
*****
To use the fmt library, add :file:`format.h` and :file:`format.cc` from
a `release archive <https://github.com/fmtlib/fmt/releases/latest>`_
or the `Git repository <https://github.com/fmtlib/fmt>`_ to your project.
To use the {fmt} library, add :file:`fmt/core.h`, :file:`fmt/format.h`,
:file:`fmt/format-inl.h`, :file:`src/format.cc` and optionally other headers
from a `release archive <https://github.com/fmtlib/fmt/releases/latest>`_ or
the `Git repository <https://github.com/fmtlib/fmt>`_ to your project.
Alternatively, you can :ref:`build the library with CMake <building>`.
If you are using Visual C++ with precompiled headers, you might need to add
the line ::
#include "stdafx.h"
before other includes in :file:`format.cc`.
.. _building:
Building the library
Building the Library
====================
The included `CMake build script`__ can be used to build the fmt
library on a wide range of platforms. CMake is freely available for
download from http://www.cmake.org/download/.
download from https://www.cmake.org/download/.
__ https://github.com/fmtlib/fmt/blob/master/CMakeLists.txt
@ -31,7 +25,7 @@ workflow starts with::
mkdir build # Create a directory to hold the build output.
cd build
cmake <path/to/fmt> # Generate native build scripts.
cmake .. # Generate native build scripts.
where :file:`{<path/to/fmt>}` is a path to the ``fmt`` repository.
@ -45,7 +39,7 @@ You can control generation of the make ``test`` target with the ``FMT_TEST``
CMake option. This can be useful if you include fmt as a subdirectory in
your project but don't want to add fmt's tests to your ``test`` target.
If you use Windows and have Visual Studio installed, a :file:`FORMAT.sln`
If you use Windows and have Visual Studio installed, a :file:`FMT.sln`
file and several :file:`.vcproj` files will be created. You can then build them
using Visual Studio or msbuild.
@ -56,26 +50,91 @@ To build a `shared library`__ set the ``BUILD_SHARED_LIBS`` CMake variable to
cmake -DBUILD_SHARED_LIBS=TRUE ...
__ http://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries
__ https://en.wikipedia.org/wiki/Library_%28computing%29#Shared_libraries
Header-only usage with CMake
============================
In order to add ``fmtlib`` into an existing ``CMakeLists.txt`` file, you can add the ``fmt`` library directory into your main project, which will enable the ``fmt`` library::
To build a `static library` with position independent code (required if the main
consumer of the fmt library is a shared library i.e. a Python extension) set the
``CMAKE_POSITION_INDEPENDENT_CODE`` CMake variable to ``TRUE``::
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE ...
Installing the Library
======================
After building the library you can install it on a Unix-like system by running
:command:`sudo make install`.
Usage with CMake
================
You can add the ``fmt`` library directory into your project and include it in
your ``CMakeLists.txt`` file::
add_subdirectory(fmt)
If you have a project called ``foo`` that you would like to link against the fmt library in a header-only fashion, you can enable with with::
target_link_libraries(foo PRIVATE fmt::fmt-header-only)
And then to ensure that the ``fmt`` library does not always get built, you can modify the call to ``add_subdirectory`` to read ::
or
::
add_subdirectory(fmt EXCLUDE_FROM_ALL)
This will ensure that the ``fmt`` library is exluded from calls to ``make``, ``make all``, or ``cmake --build .``.
Building the documentation
to exclude it from ``make``, ``make all``, or ``cmake --build .``.
You can detect and use an installed version of {fmt} as follows::
find_package(fmt)
target_link_libraries(<your-target> fmt::fmt)
Setting up your target to use a header-only version of ``fmt`` is equally easy::
target_link_libraries(<your-target> PRIVATE fmt::fmt-header-only)
Usage with build2
=================
You can use `build2 <https://build2.org>`_, a dependency manager and a
build-system combined, to use ``fmt``.
Currently this package is available in these package repositories:
- **https://cppget.org/fmt/** for released and published versions.
- `The git repository with the sources of the build2 package of fmt <https://github.com/build2-packaging/fmt.git>`_
for unreleased or custom revisions of ``fmt``.
**Usage:**
- ``build2`` package name: ``fmt``
- Library target name : ``lib{fmt}``
For example, to make your ``build2`` project depend on ``fmt``:
- Add one of the repositories to your configurations, or in your
``repositories.manifest``, if not already there::
:
role: prerequisite
location: https://pkg.cppget.org/1/stable
- Add this package as a dependency to your ``./manifest`` file
(example for ``v7.0.x``)::
depends: fmt ~7.0.0
- Import the target and use it as a prerequisite to your own target
using `fmt` in the appropriate ``buildfile``::
import fmt = fmt%lib{fmt}
lib{mylib} : cxx{**} ... $fmt
Then build your project as usual with `b` or `bdep update`.
For ``build2`` newcomers or to get more details and use cases, you can read the
``build2``
`toolchain introduction <https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml>`_.
Building the Documentation
==========================
To build the documentation you need the following software installed on your
@ -95,7 +154,45 @@ the previous section. Then compile the ``doc`` target/project, for example::
make doc
This will generate the HTML documentation in ``doc/html``.
Conda
=====
fmt can be installed on Linux, macOS and Windows with
`Conda <https://docs.conda.io/en/latest/>`__, using its
`conda-forge <https://conda-forge.org>`__
`package <https://github.com/conda-forge/fmt-feedstock>`__, as follows::
conda install -c conda-forge fmt
Vcpkg
=====
You can download and install fmt using the `vcpkg
<https://github.com/Microsoft/vcpkg>`__ dependency manager::
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install fmt
The fmt port in vcpkg is kept up to date by Microsoft team members and community
contributors. If the version is out of date, please `create an issue or pull
request <https://github.com/Microsoft/vcpkg>`__ on the vcpkg repository.
LHelper
=======
You can download and install fmt using
`lhelper <https://github.com/franko/lhelper>`__ dependency manager::
lhelper activate <some-environment>
lhelper install fmt
All the recipes for lhelper are kept in the
`lhelper's recipe <https://github.com/franko/lhelper-recipes>`__ repository.
Android NDK
===========
@ -105,11 +202,11 @@ For an example of using fmt with Android NDK, see the
`android-ndk-example <https://github.com/fmtlib/android-ndk-example>`_
repository.
__ https://github.com/fmtlib/fmt/blob/master/Android.mk
__ https://github.com/fmtlib/fmt/blob/master/support/Android.mk
Homebrew
========
fmt can be installed on OS X using `Homebrew <http://brew.sh/>`_::
fmt can be installed on OS X using `Homebrew <https://brew.sh/>`_::
brew install fmt

1
fmt.pri Normal file
View File

@ -0,0 +1 @@
QMAKE_CXXFLAGS += -isystem $$PWD/include

View File

@ -1,95 +0,0 @@
# Define the fmt library, its includes and the needed defines.
# *.cc are added to FMT_HEADERS for the header-only configuration.
set(FMT_HEADERS container.h format.h format.cc ostream.h ostream.cc printf.h
printf.cc string.h time.h)
if (HAVE_OPEN)
set(FMT_HEADERS ${FMT_HEADERS} posix.h)
set(FMT_SOURCES ${FMT_SOURCES} posix.cc)
endif ()
add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS} ../README.rst ../ChangeLog.rst)
add_library(fmt::fmt ALIAS fmt)
# Starting with cmake 3.1 the CXX_STANDARD property can be used instead.
# Note: Don't make -std=c++11 public or interface, since it breaks projects
# that use C++14.
target_compile_options(fmt PRIVATE ${CPP11_FLAG})
if (FMT_PEDANTIC)
target_compile_options(fmt PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
target_include_directories(fmt PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
set_target_properties(fmt PROPERTIES
VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
set_target_properties(fmt PROPERTIES DEBUG_POSTFIX d)
if (BUILD_SHARED_LIBS)
if (UNIX AND NOT APPLE)
# Fix rpmlint warning:
# unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
target_link_libraries(fmt -Wl,--as-needed)
endif ()
target_compile_definitions(fmt PRIVATE FMT_EXPORT INTERFACE FMT_SHARED)
endif ()
#------------------------------------------------------------------------------
# additionally define a header only library when cmake is new enough
if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0)
add_library(fmt-header-only INTERFACE)
add_library(fmt::fmt-header-only ALIAS fmt-header-only)
target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
target_include_directories(fmt-header-only INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
endif ()
# Install targets.
if (FMT_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING
"Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake)
set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake)
set(targets_export_name fmt-targets)
set (INSTALL_TARGETS fmt)
if (TARGET fmt-header-only)
set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only)
endif ()
set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING
"Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.")
# Generate the version, config and target files into the build directory.
write_basic_package_version_file(
${version_config}
VERSION ${FMT_VERSION}
COMPATIBILITY AnyNewerVersion)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in
${project_config}
INSTALL_DESTINATION ${FMT_CMAKE_DIR})
export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt::
FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
# Install version, config and target files.
install(
FILES ${project_config} ${version_config}
DESTINATION ${FMT_CMAKE_DIR})
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR}
NAMESPACE fmt::)
# Install the library and headers.
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name}
DESTINATION ${FMT_LIB_DIR})
install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR})
endif ()

View File

@ -1,82 +0,0 @@
/*
Formatting library for C++ - standard container utilities
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_CONTAINER_H_
#define FMT_CONTAINER_H_
#include "format.h"
namespace fmt {
namespace internal {
/**
\rst
A "buffer" that appends data to a standard container (e.g. typically a
``std::vector`` or ``std::basic_string``).
\endrst
*/
template <typename Container>
class ContainerBuffer : public Buffer<typename Container::value_type> {
private:
Container& container_;
protected:
virtual void grow(std::size_t size) FMT_OVERRIDE {
container_.resize(size);
this->ptr_ = &container_[0];
this->capacity_ = size;
}
public:
explicit ContainerBuffer(Container& container) : container_(container) {
this->size_ = container_.size();
if (this->size_ > 0) {
this->ptr_ = &container_[0];
this->capacity_ = this->size_;
}
}
};
} // namespace internal
/**
\rst
This class template provides operations for formatting and appending data
to a standard *container* like ``std::vector`` or ``std::basic_string``.
**Example**::
void vecformat(std::vector<char>& dest, fmt::BasicCStringRef<char> format,
fmt::ArgList args) {
fmt::BasicContainerWriter<std::vector<char> > appender(dest);
appender.write(format, args);
}
FMT_VARIADIC(void, vecformat, std::vector<char>&,
fmt::BasicCStringRef<char>);
\endrst
*/
template <class Container>
class BasicContainerWriter
: public BasicWriter<typename Container::value_type> {
private:
internal::ContainerBuffer<Container> buffer_;
public:
/**
\rst
Constructs a :class:`fmt::BasicContainerWriter` object.
\endrst
*/
explicit BasicContainerWriter(Container& dest)
: BasicWriter<typename Container::value_type>(buffer_), buffer_(dest) {}
};
} // namespace fmt
#endif // FMT_CONTAINER_H_

View File

@ -1,495 +0,0 @@
/*
Formatting library for C++
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "format.h"
#include <string.h>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstddef> // for std::ptrdiff_t
#if defined(_WIN32) && defined(__MINGW32__)
# include <cstring>
#endif
#if FMT_USE_WINDOWS_H
# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# endif
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
# include <windows.h>
# else
# define NOMINMAX
# include <windows.h>
# undef NOMINMAX
# endif
#endif
#if FMT_EXCEPTIONS
# define FMT_TRY try
# define FMT_CATCH(x) catch (x)
#else
# define FMT_TRY if (true)
# define FMT_CATCH(x) if (false)
#endif
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4702) // unreachable code
// Disable deprecation warning for strerror. The latter is not called but
// MSVC fails to detect it.
# pragma warning(disable: 4996)
#endif
// Dummy implementations of strerror_r and strerror_s called if corresponding
// system functions are not available.
FMT_MAYBE_UNUSED
static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
return fmt::internal::Null<>();
}
FMT_MAYBE_UNUSED
static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
return fmt::internal::Null<>();
}
namespace fmt {
FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {}
FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {}
FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {}
namespace {
#ifndef _MSC_VER
# define FMT_SNPRINTF snprintf
#else // _MSC_VER
inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
va_list args;
va_start(args, format);
int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
va_end(args);
return result;
}
# define FMT_SNPRINTF fmt_snprintf
#endif // _MSC_VER
#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
# define FMT_SWPRINTF snwprintf
#else
# define FMT_SWPRINTF swprintf
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
const char RESET_COLOR[] = "\x1b[0m";
typedef void (*FormatFunc)(Writer &, int, StringRef);
// Portable thread-safe version of strerror.
// Sets buffer to point to a string describing the error code.
// This can be either a pointer to a string stored in buffer,
// or a pointer to some static immutable string.
// Returns one of the following values:
// 0 - success
// ERANGE - buffer is not large enough to store the error message
// other - failure
// Buffer should be at least of size 1.
int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
class StrError {
private:
int error_code_;
char *&buffer_;
std::size_t buffer_size_;
// A noop assignment operator to avoid bogus warnings.
void operator=(const StrError &) {}
// Handle the result of XSI-compliant version of strerror_r.
int handle(int result) {
// glibc versions before 2.13 return result in errno.
return result == -1 ? errno : result;
}
// Handle the result of GNU-specific version of strerror_r.
int handle(char *message) {
// If the buffer is full then the message is probably truncated.
if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
return ERANGE;
buffer_ = message;
return 0;
}
// Handle the case when strerror_r is not available.
int handle(internal::Null<>) {
return fallback(strerror_s(buffer_, buffer_size_, error_code_));
}
// Fallback to strerror_s when strerror_r is not available.
int fallback(int result) {
// If the buffer is full then the message is probably truncated.
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
ERANGE : result;
}
#ifdef __c2__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// Fallback to strerror if strerror_r and strerror_s are not available.
int fallback(internal::Null<>) {
errno = 0;
buffer_ = strerror(error_code_);
return errno;
}
#ifdef __c2__
# pragma clang diagnostic pop
#endif
public:
StrError(int err_code, char *&buf, std::size_t buf_size)
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
int run() {
return handle(strerror_r(error_code_, buffer_, buffer_size_));
}
};
return StrError(error_code, buffer, buffer_size).run();
}
void format_error_code(Writer &out, int error_code,
StringRef message) FMT_NOEXCEPT {
// Report error code making sure that the output fits into
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// bad_alloc.
out.clear();
static const char SEP[] = ": ";
static const char ERROR_STR[] = "error ";
// Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
typedef internal::IntTraits<int>::MainType MainType;
MainType abs_value = static_cast<MainType>(error_code);
if (internal::is_negative(error_code)) {
abs_value = 0 - abs_value;
++error_code_size;
}
error_code_size += internal::count_digits(abs_value);
if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
out << message << SEP;
out << ERROR_STR << error_code;
assert(out.size() <= internal::INLINE_BUFFER_SIZE);
}
void report_error(FormatFunc func, int error_code,
StringRef message) FMT_NOEXCEPT {
MemoryWriter full_message;
func(full_message, error_code, message);
// Use Writer::data instead of Writer::c_str to avoid potential memory
// allocation.
std::fwrite(full_message.data(), full_message.size(), 1, stderr);
std::fputc('\n', stderr);
}
} // namespace
FMT_FUNC void SystemError::init(
int err_code, CStringRef format_str, ArgList args) {
error_code_ = err_code;
MemoryWriter w;
format_system_error(w, err_code, format(format_str, args));
std::runtime_error &base = *this;
base = std::runtime_error(w.str());
}
template <typename T>
int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, T value) {
if (width == 0) {
return precision < 0 ?
FMT_SNPRINTF(buffer, size, format, value) :
FMT_SNPRINTF(buffer, size, format, precision, value);
}
return precision < 0 ?
FMT_SNPRINTF(buffer, size, format, width, value) :
FMT_SNPRINTF(buffer, size, format, width, precision, value);
}
template <typename T>
int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, T value) {
if (width == 0) {
return precision < 0 ?
FMT_SWPRINTF(buffer, size, format, value) :
FMT_SWPRINTF(buffer, size, format, precision, value);
}
return precision < 0 ?
FMT_SWPRINTF(buffer, size, format, width, value) :
FMT_SWPRINTF(buffer, size, format, width, precision, value);
}
template <typename T>
const char internal::BasicData<T>::DIGITS[] =
"0001020304050607080910111213141516171819"
"2021222324252627282930313233343536373839"
"4041424344454647484950515253545556575859"
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";
#define FMT_POWERS_OF_10(factor) \
factor * 10, \
factor * 100, \
factor * 1000, \
factor * 10000, \
factor * 100000, \
factor * 1000000, \
factor * 10000000, \
factor * 100000000, \
factor * 1000000000
template <typename T>
const uint32_t internal::BasicData<T>::POWERS_OF_10_32[] = {
0, FMT_POWERS_OF_10(1)
};
template <typename T>
const uint64_t internal::BasicData<T>::POWERS_OF_10_64[] = {
0,
FMT_POWERS_OF_10(1),
FMT_POWERS_OF_10(ULongLong(1000000000)),
// Multiply several constants instead of using a single long long constant
// to avoid warnings about C++98 not supporting long long.
ULongLong(1000000000) * ULongLong(1000000000) * 10
};
FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
(void)type;
if (std::isprint(static_cast<unsigned char>(code))) {
FMT_THROW(FormatError(
format("unknown format code '{}' for {}", code, type)));
}
FMT_THROW(FormatError(
format("unknown format code '\\x{:02x}' for {}",
static_cast<unsigned>(code), type)));
}
#if FMT_USE_WINDOWS_H
FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(StringRef s) {
static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
if (s.size() > INT_MAX)
FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
int s_size = static_cast<int>(s.size());
int length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, FMT_NULL, 0);
if (length == 0)
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
buffer_.resize(length + 1);
length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
if (length == 0)
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
buffer_[length] = 0;
}
FMT_FUNC internal::UTF16ToUTF8::UTF16ToUTF8(WStringRef s) {
if (int error_code = convert(s)) {
FMT_THROW(WindowsError(error_code,
"cannot convert string from UTF-16 to UTF-8"));
}
}
FMT_FUNC int internal::UTF16ToUTF8::convert(WStringRef s) {
if (s.size() > INT_MAX)
return ERROR_INVALID_PARAMETER;
int s_size = static_cast<int>(s.size());
int length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, FMT_NULL, 0, FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_[length] = 0;
return 0;
}
FMT_FUNC void WindowsError::init(
int err_code, CStringRef format_str, ArgList args) {
error_code_ = err_code;
MemoryWriter w;
internal::format_windows_error(w, err_code, format(format_str, args));
std::runtime_error &base = *this;
base = std::runtime_error(w.str());
}
FMT_FUNC void internal::format_windows_error(
Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
FMT_TRY {
MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
buffer.resize(INLINE_BUFFER_SIZE);
for (;;) {
wchar_t *system_message = &buffer[0];
int result = FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
system_message, static_cast<uint32_t>(buffer.size()), FMT_NULL);
if (result != 0) {
UTF16ToUTF8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
out << message << ": " << utf8_message;
return;
}
break;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break; // Can't get error message, report error code instead.
buffer.resize(buffer.size() * 2);
}
} FMT_CATCH(...) {}
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
}
#endif // FMT_USE_WINDOWS_H
FMT_FUNC void format_system_error(
Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
FMT_TRY {
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
buffer.resize(internal::INLINE_BUFFER_SIZE);
for (;;) {
char *system_message = &buffer[0];
int result = safe_strerror(error_code, system_message, buffer.size());
if (result == 0) {
out << message << ": " << system_message;
return;
}
if (result != ERANGE)
break; // Can't get error message, report error code instead.
buffer.resize(buffer.size() * 2);
}
} FMT_CATCH(...) {}
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
}
template <typename Char>
void internal::FixedBuffer<Char>::grow(std::size_t) {
FMT_THROW(std::runtime_error("buffer overflow"));
}
FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg(
unsigned arg_index, const char *&error) {
internal::Arg arg = args_[arg_index];
switch (arg.type) {
case internal::Arg::NONE:
error = "argument index out of range";
break;
case internal::Arg::NAMED_ARG:
arg = *static_cast<const internal::Arg*>(arg.pointer);
break;
default:
/*nothing*/;
}
return arg;
}
FMT_FUNC void report_system_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
report_error(format_system_error, error_code, message);
}
#if FMT_USE_WINDOWS_H
FMT_FUNC void report_windows_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
report_error(internal::format_windows_error, error_code, message);
}
#endif
FMT_FUNC void print(std::FILE *f, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
std::fwrite(w.data(), 1, w.size(), f);
}
FMT_FUNC void print(CStringRef format_str, ArgList args) {
print(stdout, format_str, args);
}
FMT_FUNC void print_colored(Color c, CStringRef format, ArgList args) {
char escape[] = "\x1b[30m";
escape[3] = static_cast<char>('0' + c);
std::fputs(escape, stdout);
print(format, args);
std::fputs(RESET_COLOR, stdout);
}
#ifndef FMT_HEADER_ONLY
template struct internal::BasicData<void>;
// Explicit instantiations for char.
template void internal::FixedBuffer<char>::grow(std::size_t);
template FMT_API int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, double value);
template FMT_API int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, long double value);
// Explicit instantiations for wchar_t.
template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
template FMT_API int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, double value);
template FMT_API int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, long double value);
#endif // FMT_HEADER_ONLY
} // namespace fmt
#ifdef _MSC_VER
# pragma warning(pop)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +0,0 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#include "ostream.h"
namespace fmt {
namespace internal {
FMT_FUNC void write(std::ostream &os, Writer &w) {
const char *data = w.data();
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
UnsignedStreamSize size = w.size();
UnsignedStreamSize max_size =
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
do {
UnsignedStreamSize n = size <= max_size ? size : max_size;
os.write(data, static_cast<std::streamsize>(n));
data += n;
size -= n;
} while (size != 0);
}
}
FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
internal::write(os, w);
}
} // namespace fmt

View File

@ -1,108 +0,0 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include "format.h"
#include <ostream>
namespace fmt {
namespace internal {
template <class Char>
class FormatBuf : public std::basic_streambuf<Char> {
private:
typedef typename std::basic_streambuf<Char>::int_type int_type;
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
Buffer<Char> &buffer_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {}
protected:
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
// disadvantage is that each call to sputc always results in a (virtual) call
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<Char>(ch));
return ch;
}
std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
buffer_.append(s, s + count);
return count;
}
};
Yes &convert(std::ostream &);
struct DummyStream : std::ostream {
DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
template <typename T>
typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
};
No &operator<<(std::ostream &, int);
template <typename T>
struct ConvertToIntImpl<T, true> {
// Convert to int only if T doesn't have an overloaded operator<<.
enum {
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
};
};
// Write the content of w to os.
FMT_API void write(std::ostream &os, Writer &w);
} // namespace internal
// Formats a value.
template <typename Char, typename ArgFormatter_, typename T>
void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
const Char *&format_str, const T &value) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
output << value;
BasicStringRef<Char> str(&buffer[0], buffer.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str));
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
print(cerr, "Don't {}!", "panic");
\endrst
*/
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "ostream.cc"
#endif
#endif // FMT_OSTREAM_H_

View File

@ -1,241 +0,0 @@
/*
A C++ interface to POSIX functions.
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
// Disable bogus MSVC warnings.
#ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "posix.h"
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _WIN32
# include <unistd.h>
#else
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <io.h>
# define O_CREAT _O_CREAT
# define O_TRUNC _O_TRUNC
# ifndef S_IRUSR
# define S_IRUSR _S_IREAD
# endif
# ifndef S_IWUSR
# define S_IWUSR _S_IWRITE
# endif
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# endif
#endif // _WIN32
#ifdef fileno
# undef fileno
#endif
namespace {
#ifdef _WIN32
// Return type of read and write functions.
typedef int RWResult;
// On Windows the count argument to read and write is unsigned, so convert
// it from size_t preventing integer overflow.
inline unsigned convert_rwcount(std::size_t count) {
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
}
#else
// Return type of read and write functions.
typedef ssize_t RWResult;
inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif
}
fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT {
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
fmt::report_system_error(errno, "cannot close file");
}
fmt::BufferedFile::BufferedFile(
fmt::CStringRef filename, fmt::CStringRef mode) {
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), 0);
if (!file_)
FMT_THROW(SystemError(errno, "cannot open file {}", filename));
}
void fmt::BufferedFile::close() {
if (!file_)
return;
int result = FMT_SYSTEM(fclose(file_));
file_ = FMT_NULL;
if (result != 0)
FMT_THROW(SystemError(errno, "cannot close file"));
}
// A macro used to prevent expansion of fileno on broken versions of MinGW.
#define FMT_ARGS
int fmt::BufferedFile::fileno() const {
int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_));
if (fd == -1)
FMT_THROW(SystemError(errno, "cannot get file descriptor"));
return fd;
}
fmt::File::File(fmt::CStringRef path, int oflag) {
int mode = S_IRUSR | S_IWUSR;
#if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode));
#else
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode)));
#endif
if (fd_ == -1)
FMT_THROW(SystemError(errno, "cannot open file {}", path));
}
fmt::File::~File() FMT_NOEXCEPT {
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
fmt::report_system_error(errno, "cannot close file");
}
void fmt::File::close() {
if (fd_ == -1)
return;
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
int result = FMT_POSIX_CALL(close(fd_));
fd_ = -1;
if (result != 0)
FMT_THROW(SystemError(errno, "cannot close file"));
}
fmt::LongLong fmt::File::size() const {
#ifdef _WIN32
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
// is less than 0x0500 as is the case with some default MinGW builds.
// Both functions support large file sizes.
DWORD size_upper = 0;
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
if (size_lower == INVALID_FILE_SIZE) {
DWORD error = GetLastError();
if (error != NO_ERROR)
FMT_THROW(WindowsError(GetLastError(), "cannot get file size"));
}
fmt::ULongLong long_size = size_upper;
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
#else
typedef struct stat Stat;
Stat file_stat = Stat();
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
FMT_THROW(SystemError(errno, "cannot get file attributes"));
FMT_STATIC_ASSERT(sizeof(fmt::LongLong) >= sizeof(file_stat.st_size),
"return type of File::size is not large enough");
return file_stat.st_size;
#endif
}
std::size_t fmt::File::read(void *buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
if (result < 0)
FMT_THROW(SystemError(errno, "cannot read from file"));
return internal::to_unsigned(result);
}
std::size_t fmt::File::write(const void *buffer, std::size_t count) {
RWResult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
if (result < 0)
FMT_THROW(SystemError(errno, "cannot write to file"));
return internal::to_unsigned(result);
}
fmt::File fmt::File::dup(int fd) {
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int new_fd = FMT_POSIX_CALL(dup(fd));
if (new_fd == -1)
FMT_THROW(SystemError(errno, "cannot duplicate file descriptor {}", fd));
return File(new_fd);
}
void fmt::File::dup2(int fd) {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) {
FMT_THROW(SystemError(errno,
"cannot duplicate file descriptor {} to {}", fd_, fd));
}
}
void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1)
ec = ErrorCode(errno);
}
void fmt::File::pipe(File &read_end, File &write_end) {
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end.close();
write_end.close();
int fds[2] = {};
#ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
#else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
#endif
if (result != 0)
FMT_THROW(SystemError(errno, "cannot create pipe"));
// The following assignments don't throw because read_fd and write_fd
// are closed.
read_end = File(fds[0]);
write_end = File(fds[1]);
}
fmt::BufferedFile fmt::File::fdopen(const char *mode) {
// Don't retry as fdopen doesn't return EINTR.
FILE *f = FMT_POSIX_CALL(fdopen(fd_, mode));
if (!f)
FMT_THROW(SystemError(errno, "cannot associate stream with file descriptor"));
BufferedFile file(f);
fd_ = -1;
return file;
}
long fmt::getpagesize() {
#ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
#else
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
if (size < 0)
FMT_THROW(SystemError(errno, "cannot get memory page size"));
return size;
#endif
}

View File

@ -1,367 +0,0 @@
/*
A C++ interface to POSIX functions.
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_POSIX_H_
#define FMT_POSIX_H_
#if defined(__MINGW32__) || defined(__CYGWIN__)
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#endif
#include <errno.h>
#include <fcntl.h> // for O_RDONLY
#include <locale.h> // for locale_t
#include <stdio.h>
#include <stdlib.h> // for strtod_l
#include <cstddef>
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
result = (expression); \
} while (result == error_result && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
namespace fmt {
// An error code.
class ErrorCode {
private:
int value_;
public:
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT { return value_; }
};
// A buffered file.
class BufferedFile {
private:
FILE *file_;
friend class File;
explicit BufferedFile(FILE *f) : file_(f) {}
public:
// Constructs a BufferedFile object which doesn't represent any file.
BufferedFile() FMT_NOEXCEPT : file_(FMT_NULL) {}
// Destroys the object closing the file it represents if any.
FMT_API ~BufferedFile() FMT_NOEXCEPT;
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
FILE *file;
};
public:
// A "move constructor" for moving from a temporary.
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
// A "move constructor" for moving from an lvalue.
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
f.file_ = FMT_NULL;
}
// A "move assignment operator" for moving from a temporary.
BufferedFile &operator=(Proxy p) {
close();
file_ = p.file;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
BufferedFile &operator=(BufferedFile &other) {
close();
file_ = other.file_;
other.file_ = FMT_NULL;
return *this;
}
// Returns a proxy object for moving from a temporary:
// BufferedFile file = BufferedFile(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {file_};
file_ = FMT_NULL;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
public:
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = FMT_NULL;
}
BufferedFile& operator=(BufferedFile &&other) {
close();
file_ = other.file_;
other.file_ = FMT_NULL;
return *this;
}
#endif
// Opens a file.
FMT_API BufferedFile(CStringRef filename, CStringRef mode);
// Closes the file.
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE *get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
FMT_API int (fileno)() const;
void print(CStringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
}
FMT_VARIADIC(void, print, CStringRef)
};
// A file. Closed file is represented by a File object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::SystemError in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class File {
private:
int fd_; // File descriptor.
// Constructs a File object with a given descriptor.
explicit File(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
};
// Constructs a File object which doesn't represent any file.
File() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a File object representing this file.
FMT_API File(CStringRef path, int oflag);
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
int fd;
};
public:
// A "move constructor" for moving from a temporary.
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
// A "move constructor" for moving from an lvalue.
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
// A "move assignment operator" for moving from a temporary.
File &operator=(Proxy p) {
close();
fd_ = p.fd;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
File &operator=(File &other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Returns a proxy object for moving from a temporary:
// File file = File(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {fd_};
fd_ = -1;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(File);
public:
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
File& operator=(File &&other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
#endif
// Destroys the object closing the file it represents if any.
FMT_API ~File() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
FMT_API void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
FMT_API LongLong size() const;
// Attempts to read count bytes from the file into the specified buffer.
FMT_API std::size_t read(void *buffer, std::size_t count);
// Attempts to write count bytes from the specified buffer to the file.
FMT_API std::size_t write(const void *buffer, std::size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
FMT_API static File dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
FMT_API void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
FMT_API static void pipe(File &read_end, File &write_end);
// Creates a BufferedFile object associated with this file and detaches
// this File object from the file.
FMT_API BufferedFile fdopen(const char *mode);
};
// Returns the memory page size.
long getpagesize();
#if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
!defined(__ANDROID__) && !defined(__CYGWIN__)
# define FMT_LOCALE
#endif
#ifdef FMT_LOCALE
// A "C" numeric locale.
class Locale {
private:
# ifdef _MSC_VER
typedef _locale_t locale_t;
enum { LC_NUMERIC_MASK = LC_NUMERIC };
static locale_t newlocale(int category_mask, const char *locale, locale_t) {
return _create_locale(category_mask, locale);
}
static void freelocale(locale_t locale) {
_free_locale(locale);
}
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
return _strtod_l(nptr, endptr, locale);
}
# endif
locale_t locale_;
FMT_DISALLOW_COPY_AND_ASSIGN(Locale);
public:
typedef locale_t Type;
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL)) {
if (!locale_)
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
}
~Locale() { freelocale(locale_); }
Type get() const { return locale_; }
// Converts string to floating-point number and advances str past the end
// of the parsed input.
double strtod(const char *&str) const {
char *end = FMT_NULL;
double result = strtod_l(str, &end, locale_);
str = end;
return result;
}
};
#endif // FMT_LOCALE
} // namespace fmt
#if !FMT_USE_RVALUE_REFERENCES
namespace std {
// For compatibility with C++98.
inline fmt::BufferedFile &move(fmt::BufferedFile &f) { return f; }
inline fmt::File &move(fmt::File &f) { return f; }
}
#endif
#endif // FMT_POSIX_H_

View File

@ -1,32 +0,0 @@
/*
Formatting library for C++
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#include "format.h"
#include "printf.h"
namespace fmt {
template <typename Char>
void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args);
FMT_FUNC int fprintf(std::FILE *f, CStringRef format, ArgList args) {
MemoryWriter w;
printf(w, format, args);
std::size_t size = w.size();
return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
}
#ifndef FMT_HEADER_ONLY
template void PrintfFormatter<char>::format(CStringRef format);
template void PrintfFormatter<wchar_t>::format(WCStringRef format);
#endif // FMT_HEADER_ONLY
} // namespace fmt

View File

@ -1,603 +0,0 @@
/*
Formatting library for C++
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_
#include <algorithm> // std::fill_n
#include <limits> // std::numeric_limits
#include "ostream.h"
namespace fmt {
namespace internal {
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned>
struct IntChecker {
template <typename T>
static bool fits_in_int(T value) {
unsigned max = std::numeric_limits<int>::max();
return value <= max;
}
static bool fits_in_int(bool) { return true; }
};
template <>
struct IntChecker<true> {
template <typename T>
static bool fits_in_int(T value) {
return value >= std::numeric_limits<int>::min() &&
value <= std::numeric_limits<int>::max();
}
static bool fits_in_int(int) { return true; }
};
class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
public:
void report_unhandled_arg() {
FMT_THROW(FormatError("precision is not integer"));
}
template <typename T>
int visit_any_int(T value) {
if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(FormatError("number is too big"));
return static_cast<int>(value);
}
};
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
public:
template <typename T>
bool visit_any_int(T value) { return value == 0; }
};
// returns the default type for format specific "%s"
class DefaultType : public ArgVisitor<DefaultType, char> {
public:
char visit_char(int) { return 'c'; }
char visit_bool(bool) { return 's'; }
char visit_pointer(const void *) { return 'p'; }
template <typename T>
char visit_any_int(T) { return 'd'; }
template <typename T>
char visit_any_double(T) { return 'g'; }
char visit_unhandled_arg() { return 's'; }
};
template <typename T, typename U>
struct is_same {
enum { value = 0 };
};
template <typename T>
struct is_same<T, T> {
enum { value = 1 };
};
// An argument visitor that converts an integer argument to T for printf,
// if T is an integral type. If T is void, the argument is converted to
// corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned)
template <typename T = void>
class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
private:
internal::Arg &arg_;
wchar_t type_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
public:
ArgConverter(internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {}
void visit_bool(bool value) {
if (type_ != 's')
visit_any_int(value);
}
void visit_char(int value) {
if (type_ != 's')
visit_any_int(value);
}
template <typename U>
void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
if (type_ == 's') {
is_signed = std::numeric_limits<U>::is_signed;
}
using internal::Arg;
typedef typename internal::Conditional<
is_same<T, void>::value, U, T>::type TargetType;
if (const_check(sizeof(TargetType) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_.type = Arg::INT;
arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
} else {
arg_.type = Arg::UINT;
typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
}
} else {
if (is_signed) {
arg_.type = Arg::LONG_LONG;
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_.long_long_value = static_cast<LongLong>(value);
} else {
arg_.type = Arg::ULONG_LONG;
arg_.ulong_long_value =
static_cast<typename internal::MakeUnsigned<U>::Type>(value);
}
}
}
};
// Converts an integer argument to char for printf.
class CharConverter : public ArgVisitor<CharConverter, void> {
private:
internal::Arg &arg_;
FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
public:
explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
template <typename T>
void visit_any_int(T value) {
arg_.type = internal::Arg::CHAR;
arg_.int_value = static_cast<char>(value);
}
};
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
private:
FormatSpec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
public:
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
void report_unhandled_arg() {
FMT_THROW(FormatError("width is not integer"));
}
template <typename T>
unsigned visit_any_int(T value) {
typedef typename internal::IntTraits<T>::MainType UnsignedType;
UnsignedType width = static_cast<UnsignedType>(value);
if (internal::is_negative(value)) {
spec_.align_ = ALIGN_LEFT;
width = 0 - width;
}
unsigned int_max = std::numeric_limits<int>::max();
if (width > int_max)
FMT_THROW(FormatError("number is too big"));
return static_cast<unsigned>(width);
}
};
} // namespace internal
/**
\rst
A ``printf`` argument formatter based on the `curiously recurring template
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
or all of the visit methods with the same signatures as the methods in
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
Pass the subclass as the *Impl* template parameter. When a formatting
function processes an argument, it will dispatch to a visit method
specific to the argument type. For example, if the argument type is
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
will be called. If the subclass doesn't contain a method with this signature,
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
superclass will be called.
\endrst
*/
template <typename Impl, typename Char, typename Spec>
class BasicPrintfArgFormatter :
public internal::ArgFormatterBase<Impl, Char, Spec> {
private:
void write_null_pointer() {
this->spec().type_ = 0;
this->write("(nil)");
}
typedef internal::ArgFormatterBase<Impl, Char, Spec> Base;
public:
/**
\rst
Constructs an argument formatter object.
*writer* is a reference to the output writer and *spec* contains format
specifier information for standard argument types.
\endrst
*/
BasicPrintfArgFormatter(BasicWriter<Char> &w, Spec &s)
: internal::ArgFormatterBase<Impl, Char, Spec>(w, s) {}
/** Formats an argument of type ``bool``. */
void visit_bool(bool value) {
Spec &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return this->visit_any_int(value);
fmt_spec.type_ = 0;
this->write(value);
}
/** Formats a character. */
void visit_char(int value) {
const Spec &fmt_spec = this->spec();
BasicWriter<Char> &w = this->writer();
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
w.write_int(value, fmt_spec);
typedef typename BasicWriter<Char>::CharPtr CharPtr;
CharPtr out = CharPtr();
if (fmt_spec.width_ > 1) {
Char fill = ' ';
out = w.grow_buffer(fmt_spec.width_);
if (fmt_spec.align_ != ALIGN_LEFT) {
std::fill_n(out, fmt_spec.width_ - 1, fill);
out += fmt_spec.width_ - 1;
} else {
std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
}
} else {
out = w.grow_buffer(1);
}
*out = static_cast<Char>(value);
}
/** Formats a null-terminated C string. */
void visit_cstring(const char *value) {
if (value)
Base::visit_cstring(value);
else if (this->spec().type_ == 'p')
write_null_pointer();
else
this->write("(null)");
}
/** Formats a pointer. */
void visit_pointer(const void *value) {
if (value)
return Base::visit_pointer(value);
this->spec().type_ = 0;
write_null_pointer();
}
/** Formats an argument of a custom (user-defined) type. */
void visit_custom(internal::Arg::CustomValue c) {
BasicFormatter<Char> formatter(ArgList(), this->writer());
const Char format_str[] = {'}', 0};
const Char *format = format_str;
c.format(&formatter, c.value, &format);
}
};
/** The default printf argument formatter. */
template <typename Char>
class PrintfArgFormatter :
public BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec> {
public:
/** Constructs an argument formatter object. */
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: BasicPrintfArgFormatter<PrintfArgFormatter<Char>, Char, FormatSpec>(w, s) {}
};
/** This template formats data and writes the output to a writer. */
template <typename Char, typename ArgFormatter = PrintfArgFormatter<Char> >
class PrintfFormatter : private internal::FormatterBase {
private:
BasicWriter<Char> &writer_;
void parse_flags(FormatSpec &spec, const Char *&s);
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
internal::Arg get_arg(
const Char *s,
unsigned arg_index = (std::numeric_limits<unsigned>::max)());
// Parses argument index, flags and width and returns the argument index.
unsigned parse_header(const Char *&s, FormatSpec &spec);
public:
/**
\rst
Constructs a ``PrintfFormatter`` object. References to the arguments and
the writer are stored in the formatter object so make sure they have
appropriate lifetimes.
\endrst
*/
explicit PrintfFormatter(const ArgList &al, BasicWriter<Char> &w)
: FormatterBase(al), writer_(w) {}
/** Formats stored arguments and writes the output to the writer. */
void format(BasicCStringRef<Char> format_str);
};
template <typename Char, typename AF>
void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) {
for (;;) {
switch (*s++) {
case '-':
spec.align_ = ALIGN_LEFT;
break;
case '+':
spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
break;
case '0':
spec.fill_ = '0';
break;
case ' ':
spec.flags_ |= SIGN_FLAG;
break;
case '#':
spec.flags_ |= HASH_FLAG;
break;
default:
--s;
return;
}
}
}
template <typename Char, typename AF>
internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
unsigned arg_index) {
(void)s;
const char *error = FMT_NULL;
internal::Arg arg = arg_index == std::numeric_limits<unsigned>::max() ?
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
if (error)
FMT_THROW(FormatError(!*s ? "invalid format string" : error));
return arg;
}
template <typename Char, typename AF>
unsigned PrintfFormatter<Char, AF>::parse_header(
const Char *&s, FormatSpec &spec) {
unsigned arg_index = std::numeric_limits<unsigned>::max();
Char c = *s;
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
unsigned value = internal::parse_nonnegative_int(s);
if (*s == '$') { // value is an argument index
++s;
arg_index = value;
} else {
if (c == '0')
spec.fill_ = '0';
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
spec.width_ = value;
return arg_index;
}
}
}
parse_flags(spec, s);
// Parse width.
if (*s >= '0' && *s <= '9') {
spec.width_ = internal::parse_nonnegative_int(s);
} else if (*s == '*') {
++s;
spec.width_ = internal::WidthHandler(spec).visit(get_arg(s));
}
return arg_index;
}
template <typename Char, typename AF>
void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str) {
const Char *start = format_str.c_str();
const Char *s = start;
while (*s) {
Char c = *s++;
if (c != '%') continue;
if (*s == c) {
write(writer_, start, s);
start = ++s;
continue;
}
write(writer_, start, s - 1);
FormatSpec spec;
spec.align_ = ALIGN_RIGHT;
// Parse argument index, flags and width.
unsigned arg_index = parse_header(s, spec);
// Parse precision.
if (*s == '.') {
++s;
if ('0' <= *s && *s <= '9') {
spec.precision_ = static_cast<int>(internal::parse_nonnegative_int(s));
} else if (*s == '*') {
++s;
spec.precision_ = internal::PrecisionHandler().visit(get_arg(s));
} else {
spec.precision_ = 0;
}
}
using internal::Arg;
Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && internal::IsZeroInt().visit(arg))
spec.flags_ &= ~internal::to_unsigned<int>(HASH_FLAG);
if (spec.fill_ == '0') {
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
spec.align_ = ALIGN_NUMERIC;
else
spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
using internal::ArgConverter;
switch (*s++) {
case 'h':
if (*s == 'h')
ArgConverter<signed char>(arg, *++s).visit(arg);
else
ArgConverter<short>(arg, *s).visit(arg);
break;
case 'l':
if (*s == 'l')
ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
else
ArgConverter<long>(arg, *s).visit(arg);
break;
case 'j':
ArgConverter<intmax_t>(arg, *s).visit(arg);
break;
case 'z':
ArgConverter<std::size_t>(arg, *s).visit(arg);
break;
case 't':
ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--s;
ArgConverter<void>(arg, *s).visit(arg);
}
// Parse type.
if (!*s)
FMT_THROW(FormatError("invalid format string"));
spec.type_ = static_cast<char>(*s++);
if (spec.type_ == 's') {
// set the format type to the default if 's' is specified
spec.type_ = internal::DefaultType().visit(arg);
}
if (arg.type <= Arg::LAST_INTEGER_TYPE) {
// Normalize type.
switch (spec.type_) {
case 'i': case 'u':
spec.type_ = 'd';
break;
case 'c':
// TODO: handle wchar_t
internal::CharConverter(arg).visit(arg);
break;
}
}
start = s;
// Format argument.
AF(writer_, spec).visit(arg);
}
write(writer_, start, s);
}
inline void printf(Writer &w, CStringRef format, ArgList args) {
PrintfFormatter<char>(args, w).format(format);
}
FMT_VARIADIC(void, printf, Writer &, CStringRef)
inline void printf(WWriter &w, WCStringRef format, ArgList args) {
PrintfFormatter<wchar_t>(args, w).format(format);
}
FMT_VARIADIC(void, printf, WWriter &, WCStringRef)
/**
\rst
Formats arguments and returns the result as a string.
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
*/
inline std::string sprintf(CStringRef format, ArgList args) {
MemoryWriter w;
printf(w, format, args);
return w.str();
}
FMT_VARIADIC(std::string, sprintf, CStringRef)
inline std::wstring sprintf(WCStringRef format, ArgList args) {
WMemoryWriter w;
printf(w, format, args);
return w.str();
}
FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef)
/**
\rst
Prints formatted data to the file *f*.
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
FMT_API int fprintf(std::FILE *f, CStringRef format, ArgList args);
FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
/**
\rst
Prints formatted data to ``stdout``.
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
*/
inline int printf(CStringRef format, ArgList args) {
return fprintf(stdout, format, args);
}
FMT_VARIADIC(int, printf, CStringRef)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
inline int fprintf(std::ostream &os, CStringRef format_str, ArgList args) {
MemoryWriter w;
printf(w, format_str, args);
internal::write(os, w);
return static_cast<int>(w.size());
}
FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "printf.cc"
#endif
#endif // FMT_PRINTF_H_

View File

@ -1,148 +0,0 @@
/*
Formatting library for C++ - string utilities
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifdef FMT_INCLUDE
# error "Add the fmt's parent directory and not fmt itself to includes."
#endif
#ifndef FMT_STRING_H_
#define FMT_STRING_H_
#include "format.h"
namespace fmt {
namespace internal {
// A buffer that stores data in ``std::basic_string``.
template <typename Char, typename Allocator = std::allocator<Char> >
class StringBuffer : public Buffer<Char> {
public:
typedef std::basic_string<Char, std::char_traits<Char>, Allocator> StringType;
private:
StringType data_;
protected:
virtual void grow(std::size_t size) FMT_OVERRIDE {
data_.resize(size);
this->ptr_ = &data_[0];
this->capacity_ = size;
}
public:
explicit StringBuffer(const Allocator &allocator = Allocator())
: data_(allocator) {}
// Moves the data to ``str`` clearing the buffer.
void move_to(StringType &str) {
data_.resize(this->size_);
str.swap(data_);
this->capacity_ = this->size_ = 0;
this->ptr_ = FMT_NULL;
}
};
} // namespace internal
/**
\rst
This class template provides operations for formatting and writing data
into a character stream. The output is stored in a ``std::basic_string``
that grows dynamically.
You can use one of the following typedefs for common character types
and the standard allocator:
+---------------+----------------------------+
| Type | Definition |
+===============+============================+
| StringWriter | BasicStringWriter<char> |
+---------------+----------------------------+
| WStringWriter | BasicStringWriter<wchar_t> |
+---------------+----------------------------+
**Example**::
StringWriter out;
out << "The answer is " << 42 << "\n";
This will write the following output to the ``out`` object:
.. code-block:: none
The answer is 42
The output can be moved to a ``std::basic_string`` with ``out.move_to()``.
\endrst
*/
template <typename Char, typename Allocator = std::allocator<Char> >
class BasicStringWriter : public BasicWriter<Char> {
private:
internal::StringBuffer<Char, Allocator> buffer_;
public:
/**
\rst
Constructs a :class:`fmt::BasicStringWriter` object.
\endrst
*/
explicit BasicStringWriter(const Allocator &allocator = Allocator())
: BasicWriter<Char>(buffer_), buffer_(allocator) {}
/**
\rst
Moves the buffer content to *str* clearing the buffer.
\endrst
*/
void move_to(std::basic_string<Char, std::char_traits<Char>, Allocator> &str) {
buffer_.move_to(str);
}
};
typedef BasicStringWriter<char> StringWriter;
typedef BasicStringWriter<wchar_t> WStringWriter;
/**
\rst
Converts *value* to ``std::string`` using the default format for type *T*.
**Example**::
#include "fmt/string.h"
std::string answer = fmt::to_string(42);
\endrst
*/
template <typename T>
std::string to_string(const T &value) {
fmt::MemoryWriter w;
w << value;
return w.str();
}
/**
\rst
Converts *value* to ``std::wstring`` using the default format for type *T*.
**Example**::
#include "fmt/string.h"
std::wstring answer = fmt::to_wstring(42);
\endrst
*/
template <typename T>
std::wstring to_wstring(const T &value) {
fmt::WMemoryWriter w;
w << value;
return w.str();
}
}
#endif // FMT_STRING_H_

View File

@ -1,143 +0,0 @@
/*
Formatting library for C++ - time formatting
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#ifndef FMT_TIME_H_
#define FMT_TIME_H_
#include "format.h"
#include <ctime>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4702) // unreachable code
# pragma warning(disable: 4996) // "deprecated" functions
#endif
namespace fmt {
template <typename ArgFormatter>
void format_arg(BasicFormatter<char, ArgFormatter> &f,
const char *&format_str, const std::tm &tm) {
if (*format_str == ':')
++format_str;
const char *end = format_str;
while (*end && *end != '}')
++end;
if (*end != '}')
FMT_THROW(FormatError("missing '}' in format string"));
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
format.append(format_str, end + 1);
format[format.size() - 1] = '\0';
Buffer<char> &buffer = f.writer().buffer();
std::size_t start = buffer.size();
for (;;) {
std::size_t size = buffer.capacity() - start;
std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
if (count != 0) {
buffer.resize(start + count);
break;
}
if (size >= format.size() * 256) {
// If the buffer is 256 times larger than the format string, assume
// that `strftime` gives an empty result. There doesn't seem to be a
// better way to distinguish the two cases:
// https://github.com/fmtlib/fmt/issues/367
break;
}
const std::size_t MIN_GROWTH = 10;
buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
}
format_str = end + 1;
}
namespace internal{
inline Null<> localtime_r(...) { return Null<>(); }
inline Null<> localtime_s(...) { return Null<>(); }
inline Null<> gmtime_r(...) { return Null<>(); }
inline Null<> gmtime_s(...) { return Null<>(); }
}
// Thread-safe replacement for std::localtime
inline std::tm localtime(std::time_t time) {
struct LocalTime {
std::time_t time_;
std::tm tm_;
LocalTime(std::time_t t): time_(t) {}
bool run() {
using namespace fmt::internal;
return handle(localtime_r(&time_, &tm_));
}
bool handle(std::tm *tm) { return tm != FMT_NULL; }
bool handle(internal::Null<>) {
using namespace fmt::internal;
return fallback(localtime_s(&tm_, &time_));
}
bool fallback(int res) { return res == 0; }
bool fallback(internal::Null<>) {
using namespace fmt::internal;
std::tm *tm = std::localtime(&time_);
if (tm) tm_ = *tm;
return tm != FMT_NULL;
}
};
LocalTime lt(time);
if (lt.run())
return lt.tm_;
// Too big time values may be unsupported.
FMT_THROW(fmt::FormatError("time_t value out of range"));
return std::tm();
}
// Thread-safe replacement for std::gmtime
inline std::tm gmtime(std::time_t time) {
struct GMTime {
std::time_t time_;
std::tm tm_;
GMTime(std::time_t t): time_(t) {}
bool run() {
using namespace fmt::internal;
return handle(gmtime_r(&time_, &tm_));
}
bool handle(std::tm *tm) { return tm != FMT_NULL; }
bool handle(internal::Null<>) {
using namespace fmt::internal;
return fallback(gmtime_s(&tm_, &time_));
}
bool fallback(int res) { return res == 0; }
bool fallback(internal::Null<>) {
std::tm *tm = std::gmtime(&time_);
if (tm != FMT_NULL) tm_ = *tm;
return tm != FMT_NULL;
}
};
GMTime gt(time);
if (gt.run())
return gt.tm_;
// Too big time values may be unsupported.
FMT_THROW(fmt::FormatError("time_t value out of range"));
return std::tm();
}
} //namespace fmt
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif // FMT_TIME_H_

4
fmt_src.pri Normal file
View File

@ -0,0 +1,4 @@
HEADERS +=
SOURCES += \
$$PWD/src/format.cc

234
include/fmt/args.h Normal file
View File

@ -0,0 +1,234 @@
// Formatting library for C++ - dynamic argument lists
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_ARGS_H_
#define FMT_ARGS_H_
#include <functional> // std::reference_wrapper
#include <memory> // std::unique_ptr
#include <vector>
#include "core.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T> struct is_reference_wrapper : std::false_type {};
template <typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
template <typename T> const T& unwrap(const T& v) { return v; }
template <typename T> const T& unwrap(const std::reference_wrapper<T>& v) {
return static_cast<const T&>(v);
}
class dynamic_arg_list {
// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
// templates it doesn't complain about inability to deduce single translation
// unit for placing vtable. So storage_node_base is made a fake template.
template <typename = void> struct node {
virtual ~node() = default;
std::unique_ptr<node<>> next;
};
template <typename T> struct typed_node : node<> {
T value;
template <typename Arg>
FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
template <typename Char>
FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)
: value(arg.data(), arg.size()) {}
};
std::unique_ptr<node<>> head_;
public:
template <typename T, typename Arg> const T& push(const Arg& arg) {
auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
auto& value = new_node->value;
new_node->next = std::move(head_);
head_ = std::move(new_node);
return value;
}
};
} // namespace detail
/**
\rst
A dynamic version of `fmt::format_arg_store`.
It's equipped with a storage to potentially temporary objects which lifetimes
could be shorter than the format arguments object.
It can be implicitly converted into `~fmt::basic_format_args` for passing
into type-erased formatting functions such as `~fmt::vformat`.
\endrst
*/
template <typename Context>
class dynamic_format_arg_store
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround a GCC template argument substitution bug.
: public basic_format_args<Context>
#endif
{
private:
using char_type = typename Context::char_type;
template <typename T> struct need_copy {
static constexpr detail::type mapped_type =
detail::mapped_type_constant<T, Context>::value;
enum {
value = !(detail::is_reference_wrapper<T>::value ||
std::is_same<T, basic_string_view<char_type>>::value ||
std::is_same<T, detail::std_string_view<char_type>>::value ||
(mapped_type != detail::type::cstring_type &&
mapped_type != detail::type::string_type &&
mapped_type != detail::type::custom_type))
};
};
template <typename T>
using stored_type = conditional_t<
std::is_convertible<T, std::basic_string<char_type>>::value &&
!detail::is_reference_wrapper<T>::value,
std::basic_string<char_type>, T>;
// Storage of basic_format_arg must be contiguous.
std::vector<basic_format_arg<Context>> data_;
std::vector<detail::named_arg_info<char_type>> named_info_;
// Storage of arguments not fitting into basic_format_arg must grow
// without relocation because items in data_ refer to it.
detail::dynamic_arg_list dynamic_args_;
friend class basic_format_args<Context>;
unsigned long long get_types() const {
return detail::is_unpacked_bit | data_.size() |
(named_info_.empty()
? 0ULL
: static_cast<unsigned long long>(detail::has_named_args_bit));
}
const basic_format_arg<Context>* data() const {
return named_info_.empty() ? data_.data() : data_.data() + 1;
}
template <typename T> void emplace_arg(const T& arg) {
data_.emplace_back(detail::make_arg<Context>(arg));
}
template <typename T>
void emplace_arg(const detail::named_arg<char_type, T>& arg) {
if (named_info_.empty()) {
constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
data_.insert(data_.begin(), {zero_ptr, 0});
}
data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
data->pop_back();
};
std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
guard{&data_, pop_one};
named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
guard.release();
}
public:
constexpr dynamic_format_arg_store() = default;
/**
\rst
Adds an argument into the dynamic store for later passing to a formatting
function.
Note that custom types and string types (but not string views) are copied
into the store dynamically allocating memory if necessary.
**Example**::
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(42);
store.push_back("abc");
store.push_back(1.5f);
std::string result = fmt::vformat("{} and {} and {}", store);
\endrst
*/
template <typename T> void push_back(const T& arg) {
if (detail::const_check(need_copy<T>::value))
emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
else
emplace_arg(detail::unwrap(arg));
}
/**
\rst
Adds a reference to the argument into the dynamic store for later passing to
a formatting function.
**Example**::
fmt::dynamic_format_arg_store<fmt::format_context> store;
char band[] = "Rolling Stones";
store.push_back(std::cref(band));
band[9] = 'c'; // Changing str affects the output.
std::string result = fmt::vformat("{}", store);
// result == "Rolling Scones"
\endrst
*/
template <typename T> void push_back(std::reference_wrapper<T> arg) {
static_assert(
need_copy<T>::value,
"objects of built-in types and string views are always copied");
emplace_arg(arg.get());
}
/**
Adds named argument into the dynamic store for later passing to a formatting
function. ``std::reference_wrapper`` is supported to avoid copying of the
argument. The name is always copied into the store.
*/
template <typename T>
void push_back(const detail::named_arg<char_type, T>& arg) {
const char_type* arg_name =
dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
if (detail::const_check(need_copy<T>::value)) {
emplace_arg(
fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
} else {
emplace_arg(fmt::arg(arg_name, arg.value));
}
}
/** Erase all elements from the store */
void clear() {
data_.clear();
named_info_.clear();
dynamic_args_ = detail::dynamic_arg_list();
}
/**
\rst
Reserves space to store at least *new_cap* arguments including
*new_cap_named* named arguments.
\endrst
*/
void reserve(size_t new_cap, size_t new_cap_named) {
FMT_ASSERT(new_cap >= new_cap_named,
"Set of arguments includes set of named arguments");
data_.reserve(new_cap);
named_info_.reserve(new_cap_named);
}
};
FMT_END_NAMESPACE
#endif // FMT_ARGS_H_

2208
include/fmt/chrono.h Normal file

File diff suppressed because it is too large Load Diff

632
include/fmt/color.h Normal file
View File

@ -0,0 +1,632 @@
// Formatting library for C++ - color support
//
// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COLOR_H_
#define FMT_COLOR_H_
#include "format.h"
FMT_BEGIN_NAMESPACE
FMT_BEGIN_EXPORT
enum class color : uint32_t {
alice_blue = 0xF0F8FF, // rgb(240,248,255)
antique_white = 0xFAEBD7, // rgb(250,235,215)
aqua = 0x00FFFF, // rgb(0,255,255)
aquamarine = 0x7FFFD4, // rgb(127,255,212)
azure = 0xF0FFFF, // rgb(240,255,255)
beige = 0xF5F5DC, // rgb(245,245,220)
bisque = 0xFFE4C4, // rgb(255,228,196)
black = 0x000000, // rgb(0,0,0)
blanched_almond = 0xFFEBCD, // rgb(255,235,205)
blue = 0x0000FF, // rgb(0,0,255)
blue_violet = 0x8A2BE2, // rgb(138,43,226)
brown = 0xA52A2A, // rgb(165,42,42)
burly_wood = 0xDEB887, // rgb(222,184,135)
cadet_blue = 0x5F9EA0, // rgb(95,158,160)
chartreuse = 0x7FFF00, // rgb(127,255,0)
chocolate = 0xD2691E, // rgb(210,105,30)
coral = 0xFF7F50, // rgb(255,127,80)
cornflower_blue = 0x6495ED, // rgb(100,149,237)
cornsilk = 0xFFF8DC, // rgb(255,248,220)
crimson = 0xDC143C, // rgb(220,20,60)
cyan = 0x00FFFF, // rgb(0,255,255)
dark_blue = 0x00008B, // rgb(0,0,139)
dark_cyan = 0x008B8B, // rgb(0,139,139)
dark_golden_rod = 0xB8860B, // rgb(184,134,11)
dark_gray = 0xA9A9A9, // rgb(169,169,169)
dark_green = 0x006400, // rgb(0,100,0)
dark_khaki = 0xBDB76B, // rgb(189,183,107)
dark_magenta = 0x8B008B, // rgb(139,0,139)
dark_olive_green = 0x556B2F, // rgb(85,107,47)
dark_orange = 0xFF8C00, // rgb(255,140,0)
dark_orchid = 0x9932CC, // rgb(153,50,204)
dark_red = 0x8B0000, // rgb(139,0,0)
dark_salmon = 0xE9967A, // rgb(233,150,122)
dark_sea_green = 0x8FBC8F, // rgb(143,188,143)
dark_slate_blue = 0x483D8B, // rgb(72,61,139)
dark_slate_gray = 0x2F4F4F, // rgb(47,79,79)
dark_turquoise = 0x00CED1, // rgb(0,206,209)
dark_violet = 0x9400D3, // rgb(148,0,211)
deep_pink = 0xFF1493, // rgb(255,20,147)
deep_sky_blue = 0x00BFFF, // rgb(0,191,255)
dim_gray = 0x696969, // rgb(105,105,105)
dodger_blue = 0x1E90FF, // rgb(30,144,255)
fire_brick = 0xB22222, // rgb(178,34,34)
floral_white = 0xFFFAF0, // rgb(255,250,240)
forest_green = 0x228B22, // rgb(34,139,34)
fuchsia = 0xFF00FF, // rgb(255,0,255)
gainsboro = 0xDCDCDC, // rgb(220,220,220)
ghost_white = 0xF8F8FF, // rgb(248,248,255)
gold = 0xFFD700, // rgb(255,215,0)
golden_rod = 0xDAA520, // rgb(218,165,32)
gray = 0x808080, // rgb(128,128,128)
green = 0x008000, // rgb(0,128,0)
green_yellow = 0xADFF2F, // rgb(173,255,47)
honey_dew = 0xF0FFF0, // rgb(240,255,240)
hot_pink = 0xFF69B4, // rgb(255,105,180)
indian_red = 0xCD5C5C, // rgb(205,92,92)
indigo = 0x4B0082, // rgb(75,0,130)
ivory = 0xFFFFF0, // rgb(255,255,240)
khaki = 0xF0E68C, // rgb(240,230,140)
lavender = 0xE6E6FA, // rgb(230,230,250)
lavender_blush = 0xFFF0F5, // rgb(255,240,245)
lawn_green = 0x7CFC00, // rgb(124,252,0)
lemon_chiffon = 0xFFFACD, // rgb(255,250,205)
light_blue = 0xADD8E6, // rgb(173,216,230)
light_coral = 0xF08080, // rgb(240,128,128)
light_cyan = 0xE0FFFF, // rgb(224,255,255)
light_golden_rod_yellow = 0xFAFAD2, // rgb(250,250,210)
light_gray = 0xD3D3D3, // rgb(211,211,211)
light_green = 0x90EE90, // rgb(144,238,144)
light_pink = 0xFFB6C1, // rgb(255,182,193)
light_salmon = 0xFFA07A, // rgb(255,160,122)
light_sea_green = 0x20B2AA, // rgb(32,178,170)
light_sky_blue = 0x87CEFA, // rgb(135,206,250)
light_slate_gray = 0x778899, // rgb(119,136,153)
light_steel_blue = 0xB0C4DE, // rgb(176,196,222)
light_yellow = 0xFFFFE0, // rgb(255,255,224)
lime = 0x00FF00, // rgb(0,255,0)
lime_green = 0x32CD32, // rgb(50,205,50)
linen = 0xFAF0E6, // rgb(250,240,230)
magenta = 0xFF00FF, // rgb(255,0,255)
maroon = 0x800000, // rgb(128,0,0)
medium_aquamarine = 0x66CDAA, // rgb(102,205,170)
medium_blue = 0x0000CD, // rgb(0,0,205)
medium_orchid = 0xBA55D3, // rgb(186,85,211)
medium_purple = 0x9370DB, // rgb(147,112,219)
medium_sea_green = 0x3CB371, // rgb(60,179,113)
medium_slate_blue = 0x7B68EE, // rgb(123,104,238)
medium_spring_green = 0x00FA9A, // rgb(0,250,154)
medium_turquoise = 0x48D1CC, // rgb(72,209,204)
medium_violet_red = 0xC71585, // rgb(199,21,133)
midnight_blue = 0x191970, // rgb(25,25,112)
mint_cream = 0xF5FFFA, // rgb(245,255,250)
misty_rose = 0xFFE4E1, // rgb(255,228,225)
moccasin = 0xFFE4B5, // rgb(255,228,181)
navajo_white = 0xFFDEAD, // rgb(255,222,173)
navy = 0x000080, // rgb(0,0,128)
old_lace = 0xFDF5E6, // rgb(253,245,230)
olive = 0x808000, // rgb(128,128,0)
olive_drab = 0x6B8E23, // rgb(107,142,35)
orange = 0xFFA500, // rgb(255,165,0)
orange_red = 0xFF4500, // rgb(255,69,0)
orchid = 0xDA70D6, // rgb(218,112,214)
pale_golden_rod = 0xEEE8AA, // rgb(238,232,170)
pale_green = 0x98FB98, // rgb(152,251,152)
pale_turquoise = 0xAFEEEE, // rgb(175,238,238)
pale_violet_red = 0xDB7093, // rgb(219,112,147)
papaya_whip = 0xFFEFD5, // rgb(255,239,213)
peach_puff = 0xFFDAB9, // rgb(255,218,185)
peru = 0xCD853F, // rgb(205,133,63)
pink = 0xFFC0CB, // rgb(255,192,203)
plum = 0xDDA0DD, // rgb(221,160,221)
powder_blue = 0xB0E0E6, // rgb(176,224,230)
purple = 0x800080, // rgb(128,0,128)
rebecca_purple = 0x663399, // rgb(102,51,153)
red = 0xFF0000, // rgb(255,0,0)
rosy_brown = 0xBC8F8F, // rgb(188,143,143)
royal_blue = 0x4169E1, // rgb(65,105,225)
saddle_brown = 0x8B4513, // rgb(139,69,19)
salmon = 0xFA8072, // rgb(250,128,114)
sandy_brown = 0xF4A460, // rgb(244,164,96)
sea_green = 0x2E8B57, // rgb(46,139,87)
sea_shell = 0xFFF5EE, // rgb(255,245,238)
sienna = 0xA0522D, // rgb(160,82,45)
silver = 0xC0C0C0, // rgb(192,192,192)
sky_blue = 0x87CEEB, // rgb(135,206,235)
slate_blue = 0x6A5ACD, // rgb(106,90,205)
slate_gray = 0x708090, // rgb(112,128,144)
snow = 0xFFFAFA, // rgb(255,250,250)
spring_green = 0x00FF7F, // rgb(0,255,127)
steel_blue = 0x4682B4, // rgb(70,130,180)
tan = 0xD2B48C, // rgb(210,180,140)
teal = 0x008080, // rgb(0,128,128)
thistle = 0xD8BFD8, // rgb(216,191,216)
tomato = 0xFF6347, // rgb(255,99,71)
turquoise = 0x40E0D0, // rgb(64,224,208)
violet = 0xEE82EE, // rgb(238,130,238)
wheat = 0xF5DEB3, // rgb(245,222,179)
white = 0xFFFFFF, // rgb(255,255,255)
white_smoke = 0xF5F5F5, // rgb(245,245,245)
yellow = 0xFFFF00, // rgb(255,255,0)
yellow_green = 0x9ACD32 // rgb(154,205,50)
}; // enum class color
enum class terminal_color : uint8_t {
black = 30,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright_black = 90,
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_magenta,
bright_cyan,
bright_white
};
enum class emphasis : uint8_t {
bold = 1,
faint = 1 << 1,
italic = 1 << 2,
underline = 1 << 3,
blink = 1 << 4,
reverse = 1 << 5,
conceal = 1 << 6,
strikethrough = 1 << 7,
};
// rgb is a struct for red, green and blue colors.
// Using the name "rgb" makes some editors show the color in a tooltip.
struct rgb {
FMT_CONSTEXPR rgb() : r(0), g(0), b(0) {}
FMT_CONSTEXPR rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
FMT_CONSTEXPR rgb(uint32_t hex)
: r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
FMT_CONSTEXPR rgb(color hex)
: r((uint32_t(hex) >> 16) & 0xFF),
g((uint32_t(hex) >> 8) & 0xFF),
b(uint32_t(hex) & 0xFF) {}
uint8_t r;
uint8_t g;
uint8_t b;
};
namespace detail {
// color is a struct of either a rgb color or a terminal color.
struct color_type {
FMT_CONSTEXPR color_type() noexcept : is_rgb(), value{} {}
FMT_CONSTEXPR color_type(color rgb_color) noexcept : is_rgb(true), value{} {
value.rgb_color = static_cast<uint32_t>(rgb_color);
}
FMT_CONSTEXPR color_type(rgb rgb_color) noexcept : is_rgb(true), value{} {
value.rgb_color = (static_cast<uint32_t>(rgb_color.r) << 16) |
(static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b;
}
FMT_CONSTEXPR color_type(terminal_color term_color) noexcept
: is_rgb(), value{} {
value.term_color = static_cast<uint8_t>(term_color);
}
bool is_rgb;
union color_union {
uint8_t term_color;
uint32_t rgb_color;
} value;
};
} // namespace detail
/** A text style consisting of foreground and background colors and emphasis. */
class text_style {
public:
FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
: set_foreground_color(), set_background_color(), ems(em) {}
FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) {
if (!set_foreground_color) {
set_foreground_color = rhs.set_foreground_color;
foreground_color = rhs.foreground_color;
} else if (rhs.set_foreground_color) {
if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
foreground_color.value.rgb_color |= rhs.foreground_color.value.rgb_color;
}
if (!set_background_color) {
set_background_color = rhs.set_background_color;
background_color = rhs.background_color;
} else if (rhs.set_background_color) {
if (!background_color.is_rgb || !rhs.background_color.is_rgb)
FMT_THROW(format_error("can't OR a terminal color"));
background_color.value.rgb_color |= rhs.background_color.value.rgb_color;
}
ems = static_cast<emphasis>(static_cast<uint8_t>(ems) |
static_cast<uint8_t>(rhs.ems));
return *this;
}
friend FMT_CONSTEXPR text_style operator|(text_style lhs,
const text_style& rhs) {
return lhs |= rhs;
}
FMT_CONSTEXPR bool has_foreground() const noexcept {
return set_foreground_color;
}
FMT_CONSTEXPR bool has_background() const noexcept {
return set_background_color;
}
FMT_CONSTEXPR bool has_emphasis() const noexcept {
return static_cast<uint8_t>(ems) != 0;
}
FMT_CONSTEXPR detail::color_type get_foreground() const noexcept {
FMT_ASSERT(has_foreground(), "no foreground specified for this style");
return foreground_color;
}
FMT_CONSTEXPR detail::color_type get_background() const noexcept {
FMT_ASSERT(has_background(), "no background specified for this style");
return background_color;
}
FMT_CONSTEXPR emphasis get_emphasis() const noexcept {
FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
return ems;
}
private:
FMT_CONSTEXPR text_style(bool is_foreground,
detail::color_type text_color) noexcept
: set_foreground_color(), set_background_color(), ems() {
if (is_foreground) {
foreground_color = text_color;
set_foreground_color = true;
} else {
background_color = text_color;
set_background_color = true;
}
}
friend FMT_CONSTEXPR text_style fg(detail::color_type foreground) noexcept;
friend FMT_CONSTEXPR text_style bg(detail::color_type background) noexcept;
detail::color_type foreground_color;
detail::color_type background_color;
bool set_foreground_color;
bool set_background_color;
emphasis ems;
};
/** Creates a text style from the foreground (text) color. */
FMT_CONSTEXPR inline text_style fg(detail::color_type foreground) noexcept {
return text_style(true, foreground);
}
/** Creates a text style from the background color. */
FMT_CONSTEXPR inline text_style bg(detail::color_type background) noexcept {
return text_style(false, background);
}
FMT_CONSTEXPR inline text_style operator|(emphasis lhs, emphasis rhs) noexcept {
return text_style(lhs) | rhs;
}
namespace detail {
template <typename Char> struct ansi_color_escape {
FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color,
const char* esc) noexcept {
// If we have a terminal color, we need to output another escape code
// sequence.
if (!text_color.is_rgb) {
bool is_background = esc == string_view("\x1b[48;2;");
uint32_t value = text_color.value.term_color;
// Background ASCII codes are the same as the foreground ones but with
// 10 more.
if (is_background) value += 10u;
size_t index = 0;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
if (value >= 100u) {
buffer[index++] = static_cast<Char>('1');
value %= 100u;
}
buffer[index++] = static_cast<Char>('0' + value / 10u);
buffer[index++] = static_cast<Char>('0' + value % 10u);
buffer[index++] = static_cast<Char>('m');
buffer[index++] = static_cast<Char>('\0');
return;
}
for (int i = 0; i < 7; i++) {
buffer[i] = static_cast<Char>(esc[i]);
}
rgb color(text_color.value.rgb_color);
to_esc(color.r, buffer + 7, ';');
to_esc(color.g, buffer + 11, ';');
to_esc(color.b, buffer + 15, 'm');
buffer[19] = static_cast<Char>(0);
}
FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {
uint8_t em_codes[num_emphases] = {};
if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1;
if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2;
if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3;
if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4;
if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5;
if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7;
if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
size_t index = 0;
for (size_t i = 0; i < num_emphases; ++i) {
if (!em_codes[i]) continue;
buffer[index++] = static_cast<Char>('\x1b');
buffer[index++] = static_cast<Char>('[');
buffer[index++] = static_cast<Char>('0' + em_codes[i]);
buffer[index++] = static_cast<Char>('m');
}
buffer[index++] = static_cast<Char>(0);
}
FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
FMT_CONSTEXPR const Char* begin() const noexcept { return buffer; }
FMT_CONSTEXPR_CHAR_TRAITS const Char* end() const noexcept {
return buffer + std::char_traits<Char>::length(buffer);
}
private:
static constexpr size_t num_emphases = 8;
Char buffer[7u + 3u * num_emphases + 1u];
static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
char delimiter) noexcept {
out[0] = static_cast<Char>('0' + c / 100);
out[1] = static_cast<Char>('0' + c / 10 % 10);
out[2] = static_cast<Char>('0' + c % 10);
out[3] = static_cast<Char>(delimiter);
}
static FMT_CONSTEXPR bool has_emphasis(emphasis em, emphasis mask) noexcept {
return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask);
}
};
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_foreground_color(
detail::color_type foreground) noexcept {
return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_background_color(
detail::color_type background) noexcept {
return ansi_color_escape<Char>(background, "\x1b[48;2;");
}
template <typename Char>
FMT_CONSTEXPR ansi_color_escape<Char> make_emphasis(emphasis em) noexcept {
return ansi_color_escape<Char>(em);
}
template <typename Char> inline void reset_color(buffer<Char>& buffer) {
auto reset_color = string_view("\x1b[0m");
buffer.append(reset_color.begin(), reset_color.end());
}
template <typename T> struct styled_arg {
const T& value;
text_style style;
};
template <typename Char>
void vformat_to(buffer<Char>& buf, const text_style& ts,
basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
buf.append(emphasis.begin(), emphasis.end());
}
if (ts.has_foreground()) {
has_style = true;
auto foreground = detail::make_foreground_color<Char>(ts.get_foreground());
buf.append(foreground.begin(), foreground.end());
}
if (ts.has_background()) {
has_style = true;
auto background = detail::make_background_color<Char>(ts.get_background());
buf.append(background.begin(), background.end());
}
detail::vformat_to(buf, format_str, args, {});
if (has_style) detail::reset_color<Char>(buf);
}
} // namespace detail
inline void vprint(std::FILE* f, const text_style& ts, string_view fmt,
format_args args) {
// Legacy wide streams are not supported.
auto buf = memory_buffer();
detail::vformat_to(buf, ts, fmt, args);
if (detail::is_utf8()) {
detail::print(f, string_view(buf.begin(), buf.size()));
return;
}
buf.push_back('\0');
int result = std::fputs(buf.data(), f);
if (result < 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
}
/**
\rst
Formats a string and prints it to the specified file stream using ANSI
escape sequences to specify text formatting.
**Example**::
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(std::FILE* f, const text_style& ts, const S& format_str,
const Args&... args) {
vprint(f, ts, format_str,
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
}
/**
\rst
Formats a string and prints it to stdout using ANSI escape sequences to
specify text formatting.
**Example**::
fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
"Elapsed time: {0:.2f} seconds", 1.23);
\endrst
*/
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_string<S>::value)>
void print(const text_style& ts, const S& format_str, const Args&... args) {
return print(stdout, ts, format_str, args...);
}
template <typename S, typename Char = char_t<S>>
inline std::basic_string<Char> vformat(
const text_style& ts, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
basic_memory_buffer<Char> buf;
detail::vformat_to(buf, ts, detail::to_string_view(format_str), args);
return fmt::to_string(buf);
}
/**
\rst
Formats arguments and returns the result as a string using ANSI
escape sequences to specify text formatting.
**Example**::
#include <fmt/color.h>
std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
"The answer is {}", 42);
\endrst
*/
template <typename S, typename... Args, typename Char = char_t<S>>
inline std::basic_string<Char> format(const text_style& ts, const S& format_str,
const Args&... args) {
return fmt::vformat(ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}
/**
Formats a string with the given text_style and writes the output to ``out``.
*/
template <typename OutputIt, typename Char,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
OutputIt vformat_to(
OutputIt out, const text_style& ts, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, ts, format_str, args);
return detail::get_iterator(buf, out);
}
/**
\rst
Formats arguments with the given text_style, writes the result to the output
iterator ``out`` and returns the iterator past the end of the output range.
**Example**::
std::vector<char> out;
fmt::format_to(std::back_inserter(out),
fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
\endrst
*/
template <typename OutputIt, typename S, typename... Args,
bool enable = detail::is_output_iterator<OutputIt, char_t<S>>::value&&
detail::is_string<S>::value>
inline auto format_to(OutputIt out, const text_style& ts, const S& format_str,
Args&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, ts, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<char_t<S>>>(args...));
}
template <typename T, typename Char>
struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
template <typename FormatContext>
auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const
-> decltype(ctx.out()) {
const auto& ts = arg.style;
const auto& value = arg.value;
auto out = ctx.out();
bool has_style = false;
if (ts.has_emphasis()) {
has_style = true;
auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
out = std::copy(emphasis.begin(), emphasis.end(), out);
}
if (ts.has_foreground()) {
has_style = true;
auto foreground =
detail::make_foreground_color<Char>(ts.get_foreground());
out = std::copy(foreground.begin(), foreground.end(), out);
}
if (ts.has_background()) {
has_style = true;
auto background =
detail::make_background_color<Char>(ts.get_background());
out = std::copy(background.begin(), background.end(), out);
}
out = formatter<T, Char>::format(value, ctx);
if (has_style) {
auto reset_color = string_view("\x1b[0m");
out = std::copy(reset_color.begin(), reset_color.end(), out);
}
return out;
}
};
/**
\rst
Returns an argument that will be formatted using ANSI escape sequences,
to be used in a formatting function.
**Example**::
fmt::print("Elapsed time: {0:.2f} seconds",
fmt::styled(1.23, fmt::fg(fmt::color::green) |
fmt::bg(fmt::color::blue)));
\endrst
*/
template <typename T>
FMT_CONSTEXPR auto styled(const T& value, text_style ts)
-> detail::styled_arg<remove_cvref_t<T>> {
return detail::styled_arg<remove_cvref_t<T>>{value, ts};
}
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_COLOR_H_

534
include/fmt/compile.h Normal file
View File

@ -0,0 +1,534 @@
// Formatting library for C++ - experimental format string compilation
//
// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_COMPILE_H_
#define FMT_COMPILE_H_
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char, typename InputIt>
FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
return it + (end - begin);
}
// A compile-time string which is compiled into fast formatting code.
class compiled_string {};
template <typename S>
struct is_compiled_string : std::is_base_of<compiled_string, S> {};
/**
\rst
Converts a string literal *s* into a format string that will be parsed at
compile time and converted into efficient formatting code. Requires C++17
``constexpr if`` compiler support.
**Example**::
// Converts 42 into std::string using the most efficient method and no
// runtime format string processing.
std::string s = fmt::format(FMT_COMPILE("{}"), 42);
\endrst
*/
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
# define FMT_COMPILE(s) \
FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit)
#else
# define FMT_COMPILE(s) FMT_STRING(s)
#endif
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <typename Char, size_t N,
fmt::detail_exported::fixed_string<Char, N> Str>
struct udl_compiled_string : compiled_string {
using char_type = Char;
explicit constexpr operator basic_string_view<char_type>() const {
return {Str.data, N - 1};
}
};
#endif
template <typename T, typename... Tail>
const T& first(const T& value, const Tail&...) {
return value;
}
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
template <typename... Args> struct type_list {};
// Returns a reference to the argument at index N from [first, rest...].
template <int N, typename T, typename... Args>
constexpr const auto& get([[maybe_unused]] const T& first,
[[maybe_unused]] const Args&... rest) {
static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
if constexpr (N == 0)
return first;
else
return detail::get<N - 1>(rest...);
}
template <typename Char, typename... Args>
constexpr int get_arg_index_by_name(basic_string_view<Char> name,
type_list<Args...>) {
return get_arg_index_by_name<Args...>(name);
}
template <int N, typename> struct get_type_impl;
template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
using type =
remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>;
};
template <int N, typename T>
using get_type = typename get_type_impl<N, T>::type;
template <typename T> struct is_compiled_format : std::false_type {};
template <typename Char> struct text {
basic_string_view<Char> data;
using char_type = Char;
template <typename OutputIt, typename... Args>
constexpr OutputIt format(OutputIt out, const Args&...) const {
return write<Char>(out, data);
}
};
template <typename Char>
struct is_compiled_format<text<Char>> : std::true_type {};
template <typename Char>
constexpr text<Char> make_text(basic_string_view<Char> s, size_t pos,
size_t size) {
return {{&s[pos], size}};
}
template <typename Char> struct code_unit {
Char value;
using char_type = Char;
template <typename OutputIt, typename... Args>
constexpr OutputIt format(OutputIt out, const Args&...) const {
*out++ = value;
return out;
}
};
// This ensures that the argument type is convertible to `const T&`.
template <typename T, int N, typename... Args>
constexpr const T& get_arg_checked(const Args&... args) {
const auto& arg = detail::get<N>(args...);
if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {
return arg.value;
} else {
return arg;
}
}
template <typename Char>
struct is_compiled_format<code_unit<Char>> : std::true_type {};
// A replacement field that refers to argument N.
template <typename Char, typename T, int N> struct field {
using char_type = Char;
template <typename OutputIt, typename... Args>
constexpr OutputIt format(OutputIt out, const Args&... args) const {
const T& arg = get_arg_checked<T, N>(args...);
if constexpr (std::is_convertible_v<T, basic_string_view<Char>>) {
auto s = basic_string_view<Char>(arg);
return copy_str<Char>(s.begin(), s.end(), out);
}
return write<Char>(out, arg);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<field<Char, T, N>> : std::true_type {};
// A replacement field that refers to argument with name.
template <typename Char> struct runtime_named_field {
using char_type = Char;
basic_string_view<Char> name;
template <typename OutputIt, typename T>
constexpr static bool try_format_argument(
OutputIt& out,
// [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
[[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) {
if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {
if (arg_name == arg.name) {
out = write<Char>(out, arg.value);
return true;
}
}
return false;
}
template <typename OutputIt, typename... Args>
constexpr OutputIt format(OutputIt out, const Args&... args) const {
bool found = (try_format_argument(out, name, args) || ...);
if (!found) {
FMT_THROW(format_error("argument with specified name is not found"));
}
return out;
}
};
template <typename Char>
struct is_compiled_format<runtime_named_field<Char>> : std::true_type {};
// A replacement field that refers to argument N and has format specifiers.
template <typename Char, typename T, int N> struct spec_field {
using char_type = Char;
formatter<T, Char> fmt;
template <typename OutputIt, typename... Args>
constexpr FMT_INLINE OutputIt format(OutputIt out,
const Args&... args) const {
const auto& vargs =
fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
basic_format_context<OutputIt, Char> ctx(out, vargs);
return fmt.format(get_arg_checked<T, N>(args...), ctx);
}
};
template <typename Char, typename T, int N>
struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
template <typename L, typename R> struct concat {
L lhs;
R rhs;
using char_type = typename L::char_type;
template <typename OutputIt, typename... Args>
constexpr OutputIt format(OutputIt out, const Args&... args) const {
out = lhs.format(out, args...);
return rhs.format(out, args...);
}
};
template <typename L, typename R>
struct is_compiled_format<concat<L, R>> : std::true_type {};
template <typename L, typename R>
constexpr concat<L, R> make_concat(L lhs, R rhs) {
return {lhs, rhs};
}
struct unknown_format {};
template <typename Char>
constexpr size_t parse_text(basic_string_view<Char> str, size_t pos) {
for (size_t size = str.size(); pos != size; ++pos) {
if (str[pos] == '{' || str[pos] == '}') break;
}
return pos;
}
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str);
template <typename Args, size_t POS, int ID, typename T, typename S>
constexpr auto parse_tail(T head, S format_str) {
if constexpr (POS !=
basic_string_view<typename S::char_type>(format_str).size()) {
constexpr auto tail = compile_format_string<Args, POS, ID>(format_str);
if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
unknown_format>())
return tail;
else
return make_concat(head, tail);
} else {
return head;
}
}
template <typename T, typename Char> struct parse_specs_result {
formatter<T, Char> fmt;
size_t end;
int next_arg_id;
};
enum { manual_indexing_id = -1 };
template <typename T, typename Char>
constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
size_t pos, int next_arg_id) {
str.remove_prefix(pos);
auto ctx =
compile_parse_context<Char>(str, max_value<int>(), nullptr, next_arg_id);
auto f = formatter<T, Char>();
auto end = f.parse(ctx);
return {f, pos + fmt::detail::to_unsigned(end - str.data()),
next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
}
template <typename Char> struct arg_id_handler {
arg_ref<Char> arg_id;
constexpr int on_auto() {
FMT_ASSERT(false, "handler cannot be used with automatic indexing");
return 0;
}
constexpr int on_index(int id) {
arg_id = arg_ref<Char>(id);
return 0;
}
constexpr int on_name(basic_string_view<Char> id) {
arg_id = arg_ref<Char>(id);
return 0;
}
};
template <typename Char> struct parse_arg_id_result {
arg_ref<Char> arg_id;
const Char* arg_id_end;
};
template <int ID, typename Char>
constexpr auto parse_arg_id(const Char* begin, const Char* end) {
auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
auto arg_id_end = parse_arg_id(begin, end, handler);
return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
}
template <typename T, typename Enable = void> struct field_type {
using type = remove_cvref_t<T>;
};
template <typename T>
struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {
using type = remove_cvref_t<decltype(T::value)>;
};
template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
typename S>
constexpr auto parse_replacement_field_then_tail(S format_str) {
using char_type = typename S::char_type;
constexpr auto str = basic_string_view<char_type>(format_str);
constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
if constexpr (c == '}') {
return parse_tail<Args, END_POS + 1, NEXT_ID>(
field<char_type, typename field_type<T>::type, ARG_INDEX>(),
format_str);
} else if constexpr (c != ':') {
FMT_THROW(format_error("expected ':'"));
} else {
constexpr auto result = parse_specs<typename field_type<T>::type>(
str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
if constexpr (result.end >= str.size() || str[result.end] != '}') {
FMT_THROW(format_error("expected '}'"));
return 0;
} else {
return parse_tail<Args, result.end + 1, result.next_arg_id>(
spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
result.fmt},
format_str);
}
}
}
// Compiles a non-empty format string and returns the compiled representation
// or unknown_format() on unrecognized input.
template <typename Args, size_t POS, int ID, typename S>
constexpr auto compile_format_string(S format_str) {
using char_type = typename S::char_type;
constexpr auto str = basic_string_view<char_type>(format_str);
if constexpr (str[POS] == '{') {
if constexpr (POS + 1 == str.size())
FMT_THROW(format_error("unmatched '{' in format string"));
if constexpr (str[POS + 1] == '{') {
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
static_assert(ID != manual_indexing_id,
"cannot switch from manual to automatic argument indexing");
constexpr auto next_id =
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
POS + 1, ID, next_id>(
format_str);
} else {
constexpr auto arg_id_result =
parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();
constexpr char_type c =
arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
static_assert(c == '}' || c == ':', "missing '}' in format string");
if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) {
static_assert(
ID == manual_indexing_id || ID == 0,
"cannot switch from automatic to manual argument indexing");
constexpr auto arg_index = arg_id_result.arg_id.val.index;
return parse_replacement_field_then_tail<get_type<arg_index, Args>,
Args, arg_id_end_pos,
arg_index, manual_indexing_id>(
format_str);
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
constexpr auto arg_index =
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
if constexpr (arg_index >= 0) {
constexpr auto next_id =
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
return parse_replacement_field_then_tail<
decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
arg_index, next_id>(format_str);
} else if constexpr (c == '}') {
return parse_tail<Args, arg_id_end_pos + 1, ID>(
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
format_str);
} else if constexpr (c == ':') {
return unknown_format(); // no type info for specs parsing
}
}
}
} else if constexpr (str[POS] == '}') {
if constexpr (POS + 1 == str.size())
FMT_THROW(format_error("unmatched '}' in format string"));
return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), format_str);
} else {
constexpr auto end = parse_text(str, POS + 1);
if constexpr (end - POS > 1) {
return parse_tail<Args, end, ID>(make_text(str, POS, end - POS),
format_str);
} else {
return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]},
format_str);
}
}
}
template <typename... Args, typename S,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
constexpr auto compile(S format_str) {
constexpr auto str = basic_string_view<typename S::char_type>(format_str);
if constexpr (str.size() == 0) {
return detail::make_text(str, 0, 0);
} else {
constexpr auto result =
detail::compile_format_string<detail::type_list<Args...>, 0, 0>(
format_str);
return result;
}
}
#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
} // namespace detail
FMT_BEGIN_EXPORT
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
template <typename CompiledFormat, typename... Args,
typename Char = typename CompiledFormat::char_type,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
FMT_INLINE std::basic_string<Char> format(const CompiledFormat& cf,
const Args&... args) {
auto s = std::basic_string<Char>();
cf.format(std::back_inserter(s), args...);
return s;
}
template <typename OutputIt, typename CompiledFormat, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
constexpr FMT_INLINE OutputIt format_to(OutputIt out, const CompiledFormat& cf,
const Args&... args) {
return cf.format(out, args...);
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_INLINE std::basic_string<typename S::char_type> format(const S&,
Args&&... args) {
if constexpr (std::is_same<typename S::char_type, char>::value) {
constexpr auto str = basic_string_view<typename S::char_type>(S());
if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {
const auto& first = detail::first(args...);
if constexpr (detail::is_named_arg<
remove_cvref_t<decltype(first)>>::value) {
return fmt::to_string(first.value);
} else {
return fmt::to_string(first);
}
}
}
constexpr auto compiled = detail::compile<Args...>(S());
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
detail::unknown_format>()) {
return fmt::format(
static_cast<basic_string_view<typename S::char_type>>(S()),
std::forward<Args>(args)...);
} else {
return fmt::format(compiled, std::forward<Args>(args)...);
}
}
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) {
constexpr auto compiled = detail::compile<Args...>(S());
if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
detail::unknown_format>()) {
return fmt::format_to(
out, static_cast<basic_string_view<typename S::char_type>>(S()),
std::forward<Args>(args)...);
} else {
return fmt::format_to(out, compiled, std::forward<Args>(args)...);
}
}
#endif
template <typename OutputIt, typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
const S& format_str, Args&&... args) {
using traits = detail::fixed_buffer_traits;
auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
format_to(std::back_inserter(buf), format_str, std::forward<Args>(args)...);
return {buf.out(), buf.count()};
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
FMT_CONSTEXPR20 size_t formatted_size(const S& format_str,
const Args&... args) {
return fmt::format_to(detail::counting_iterator(), format_str, args...)
.count();
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
void print(std::FILE* f, const S& format_str, const Args&... args) {
memory_buffer buffer;
fmt::format_to(std::back_inserter(buffer), format_str, args...);
detail::print(f, {buffer.data(), buffer.size()});
}
template <typename S, typename... Args,
FMT_ENABLE_IF(detail::is_compiled_string<S>::value)>
void print(const S& format_str, const Args&... args) {
print(stdout, format_str, args...);
}
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
inline namespace literals {
template <detail_exported::fixed_string Str> constexpr auto operator""_cf() {
using char_t = remove_cvref_t<decltype(Str.data[0])>;
return detail::udl_compiled_string<char_t, sizeof(Str.data) / sizeof(char_t),
Str>();
}
} // namespace literals
#endif
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_COMPILE_H_

2922
include/fmt/core.h Normal file

File diff suppressed because it is too large Load Diff

1662
include/fmt/format-inl.h Normal file

File diff suppressed because it is too large Load Diff

4510
include/fmt/format.h Normal file

File diff suppressed because it is too large Load Diff

451
include/fmt/os.h Normal file
View File

@ -0,0 +1,451 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OS_H_
#define FMT_OS_H_
#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <system_error> // std::system_error
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
#endif
#include "format.h"
#ifndef FMT_USE_FCNTL
// UWP doesn't provide _pipe.
# if FMT_HAS_INCLUDE("winapifamily.h")
# include <winapifamily.h>
# endif
# if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
defined(__linux__)) && \
(!defined(WINAPI_FAMILY) || \
(WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
# include <fcntl.h> // for O_RDONLY
# define FMT_USE_FCNTL 1
# else
# define FMT_USE_FCNTL 0
# endif
#endif
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) ::call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
(result) = (expression); \
} while ((result) == (error_result) && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
FMT_BEGIN_NAMESPACE
FMT_BEGIN_EXPORT
/**
\rst
A reference to a null-terminated string. It can be constructed from a C
string or ``std::string``.
You can use one of the following type aliases for common character types:
+---------------+-----------------------------+
| Type | Definition |
+===============+=============================+
| cstring_view | basic_cstring_view<char> |
+---------------+-----------------------------+
| wcstring_view | basic_cstring_view<wchar_t> |
+---------------+-----------------------------+
This class is most useful as a parameter type to allow passing
different types of strings to a function, for example::
template <typename... Args>
std::string format(cstring_view format_str, const Args & ... args);
format("{}", 42);
format(std::string("{}"), 42);
\endrst
*/
template <typename Char> class basic_cstring_view {
private:
const Char* data_;
public:
/** Constructs a string reference object from a C string. */
basic_cstring_view(const Char* s) : data_(s) {}
/**
\rst
Constructs a string reference from an ``std::string`` object.
\endrst
*/
basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
/** Returns the pointer to a C string. */
const Char* c_str() const { return data_; }
};
using cstring_view = basic_cstring_view<char>;
using wcstring_view = basic_cstring_view<wchar_t>;
#ifdef _WIN32
FMT_API const std::error_category& system_category() noexcept;
namespace detail {
FMT_API void format_windows_error(buffer<char>& out, int error_code,
const char* message) noexcept;
}
FMT_API std::system_error vwindows_error(int error_code, string_view format_str,
format_args args);
/**
\rst
Constructs a :class:`std::system_error` object with the description
of the form
.. parsed-literal::
*<message>*: *<system-message>*
where *<message>* is the formatted message and *<system-message>* is the
system message corresponding to the error code.
*error_code* is a Windows error code as given by ``GetLastError``.
If *error_code* is not a valid error code such as -1, the system message
will look like "error -1".
**Example**::
// This throws a system_error with the description
// cannot open file 'madeup': The system cannot find the file specified.
// or similar (system message may vary).
const char *filename = "madeup";
LPOFSTRUCT of = LPOFSTRUCT();
HFILE file = OpenFile(filename, &of, OF_READ);
if (file == HFILE_ERROR) {
throw fmt::windows_error(GetLastError(),
"cannot open file '{}'", filename);
}
\endrst
*/
template <typename... Args>
std::system_error windows_error(int error_code, string_view message,
const Args&... args) {
return vwindows_error(error_code, message, fmt::make_format_args(args...));
}
// Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors.
FMT_API void report_windows_error(int error_code, const char* message) noexcept;
#else
inline const std::error_category& system_category() noexcept {
return std::system_category();
}
#endif // _WIN32
// std::system is not available on some platforms such as iOS (#2248).
#ifdef __OSX__
template <typename S, typename... Args, typename Char = char_t<S>>
void say(const S& format_str, Args&&... args) {
std::system(format("say \"{}\"", format(format_str, args...)).c_str());
}
#endif
// A buffered file.
class buffered_file {
private:
FILE* file_;
friend class file;
explicit buffered_file(FILE* f) : file_(f) {}
public:
buffered_file(const buffered_file&) = delete;
void operator=(const buffered_file&) = delete;
// Constructs a buffered_file object which doesn't represent any file.
buffered_file() noexcept : file_(nullptr) {}
// Destroys the object closing the file it represents if any.
FMT_API ~buffered_file() noexcept;
public:
buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
other.file_ = nullptr;
}
buffered_file& operator=(buffered_file&& other) {
close();
file_ = other.file_;
other.file_ = nullptr;
return *this;
}
// Opens a file.
FMT_API buffered_file(cstring_view filename, cstring_view mode);
// Closes the file.
FMT_API void close();
// Returns the pointer to a FILE object representing this file.
FILE* get() const noexcept { return file_; }
FMT_API int descriptor() const;
void vprint(string_view format_str, format_args args) {
fmt::vprint(file_, format_str, args);
}
template <typename... Args>
inline void print(string_view format_str, const Args&... args) {
vprint(format_str, fmt::make_format_args(args...));
}
};
#if FMT_USE_FCNTL
// A file. Closed file is represented by a file object with descriptor -1.
// Methods that are not declared with noexcept may throw
// fmt::system_error in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class FMT_API file {
private:
int fd_; // File descriptor.
// Constructs a file object with a given descriptor.
explicit file(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
APPEND = FMT_POSIX(O_APPEND), // Open in append mode.
TRUNC = FMT_POSIX(O_TRUNC) // Truncate the content of the file.
};
// Constructs a file object which doesn't represent any file.
file() noexcept : fd_(-1) {}
// Opens a file and constructs a file object representing this file.
file(cstring_view path, int oflag);
public:
file(const file&) = delete;
void operator=(const file&) = delete;
file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
// Move assignment is not noexcept because close may throw.
file& operator=(file&& other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Destroys the object closing the file it represents if any.
~file() noexcept;
// Returns the file descriptor.
int descriptor() const noexcept { return fd_; }
// Closes the file.
void close();
// Returns the file size. The size has signed type for consistency with
// stat::st_size.
long long size() const;
// Attempts to read count bytes from the file into the specified buffer.
size_t read(void* buffer, size_t count);
// Attempts to write count bytes from the specified buffer to the file.
size_t write(const void* buffer, size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
static file dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd, std::error_code& ec) noexcept;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
static void pipe(file& read_end, file& write_end);
// Creates a buffered_file object associated with this file and detaches
// this file object from the file.
buffered_file fdopen(const char* mode);
# if defined(_WIN32) && !defined(__MINGW32__)
// Opens a file and constructs a file object representing this file by
// wcstring_view filename. Windows only.
static file open_windows_file(wcstring_view path, int oflag);
# endif
};
// Returns the memory page size.
long getpagesize();
namespace detail {
struct buffer_size {
buffer_size() = default;
size_t value = 0;
buffer_size operator=(size_t val) const {
auto bs = buffer_size();
bs.value = val;
return bs;
}
};
struct ostream_params {
int oflag = file::WRONLY | file::CREATE | file::TRUNC;
size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
ostream_params() {}
template <typename... T>
ostream_params(T... params, int new_oflag) : ostream_params(params...) {
oflag = new_oflag;
}
template <typename... T>
ostream_params(T... params, detail::buffer_size bs)
: ostream_params(params...) {
this->buffer_size = bs.value;
}
// Intel has a bug that results in failure to deduce a constructor
// for empty parameter packs.
# if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
ostream_params(int new_oflag) : oflag(new_oflag) {}
ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {}
# endif
};
class file_buffer final : public buffer<char> {
file file_;
FMT_API void grow(size_t) override;
public:
FMT_API file_buffer(cstring_view path, const ostream_params& params);
FMT_API file_buffer(file_buffer&& other);
FMT_API ~file_buffer();
void flush() {
if (size() == 0) return;
file_.write(data(), size() * sizeof(data()[0]));
clear();
}
void close() {
flush();
file_.close();
}
};
} // namespace detail
// Added {} below to work around default constructor error known to
// occur in Xcode versions 7.2.1 and 8.2.1.
constexpr detail::buffer_size buffer_size{};
/** A fast output stream which is not thread-safe. */
class FMT_API ostream {
private:
FMT_MSC_WARNING(suppress : 4251)
detail::file_buffer buffer_;
ostream(cstring_view path, const detail::ostream_params& params)
: buffer_(path, params) {}
public:
ostream(ostream&& other) : buffer_(std::move(other.buffer_)) {}
~ostream();
void flush() { buffer_.flush(); }
template <typename... T>
friend ostream output_file(cstring_view path, T... params);
void close() { buffer_.close(); }
/**
Formats ``args`` according to specifications in ``fmt`` and writes the
output to the file.
*/
template <typename... T> void print(format_string<T...> fmt, T&&... args) {
vformat_to(detail::buffer_appender<char>(buffer_), fmt,
fmt::make_format_args(args...));
}
};
/**
\rst
Opens a file for writing. Supported parameters passed in *params*:
* ``<integer>``: Flags passed to `open
<https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html>`_
(``file::WRONLY | file::CREATE | file::TRUNC`` by default)
* ``buffer_size=<integer>``: Output buffer size
**Example**::
auto out = fmt::output_file("guide.txt");
out.print("Don't {}", "Panic");
\endrst
*/
template <typename... T>
inline ostream output_file(cstring_view path, T... params) {
return {path, detail::ostream_params(params...)};
}
#endif // FMT_USE_FCNTL
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_OS_H_

209
include/fmt/ostream.h Normal file
View File

@ -0,0 +1,209 @@
// Formatting library for C++ - std::ostream support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include <fstream> // std::filebuf
#if defined(_WIN32) && defined(__GLIBCXX__)
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
# include <__std_stream>
#endif
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
// Generate a unique explicit instantion in every translation unit using a tag
// type in an anonymous namespace.
namespace {
struct file_access_tag {};
} // namespace
template <typename Tag, typename BufType, FILE* BufType::*FileMemberPtr>
class file_access {
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
};
#if FMT_MSC_VERSION
template class file_access<file_access_tag, std::filebuf,
&std::filebuf::_Myfile>;
auto get_file(std::filebuf&) -> FILE*;
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
template class file_access<file_access_tag, std::__stdoutbuf<char>,
&std::__stdoutbuf<char>::__file_>;
auto get_file(std::__stdoutbuf<char>&) -> FILE*;
#endif
inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) {
#if FMT_MSC_VERSION
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#elif defined(_WIN32) && defined(__GLIBCXX__)
auto* rdbuf = os.rdbuf();
FILE* c_file;
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
c_file = sfbuf->file();
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
c_file = fbuf->file();
else
return false;
if (c_file) return write_console(c_file, data);
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
if (auto* buf = dynamic_cast<std::__stdoutbuf<char>*>(os.rdbuf()))
if (FILE* f = get_file(*buf)) return write_console(f, data);
#else
ignore_unused(os, data);
#endif
return false;
}
inline bool write_ostream_unicode(std::wostream&,
fmt::basic_string_view<wchar_t>) {
return false;
}
// Write the content of buf to os.
// It is a separate function rather than a part of vprint to simplify testing.
template <typename Char>
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
const Char* buf_data = buf.data();
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
unsigned_streamsize size = buf.size();
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
do {
unsigned_streamsize n = size <= max_size ? size : max_size;
os.write(buf_data, static_cast<std::streamsize>(n));
buf_data += n;
size -= n;
} while (size != 0);
}
template <typename Char, typename T>
void format_value(buffer<Char>& buf, const T& value,
locale_ref loc = locale_ref()) {
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
auto&& output = std::basic_ostream<Char>(&format_buf);
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
if (loc) output.imbue(loc.get<std::locale>());
#endif
output << value;
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
}
template <typename T> struct streamed_view { const T& value; };
} // namespace detail
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename Char>
struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
void set_debug_format() = delete;
template <typename T, typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
-> OutputIt {
auto buffer = basic_memory_buffer<Char>();
detail::format_value(buffer, value, ctx.locale());
return formatter<basic_string_view<Char>, Char>::format(
{buffer.data(), buffer.size()}, ctx);
}
};
using ostream_formatter = basic_ostream_formatter<char>;
template <typename T, typename Char>
struct formatter<detail::streamed_view<T>, Char>
: basic_ostream_formatter<Char> {
template <typename OutputIt>
auto format(detail::streamed_view<T> view,
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
return basic_ostream_formatter<Char>::format(view.value, ctx);
}
};
/**
\rst
Returns a view that formats `value` via an ostream ``operator<<``.
**Example**::
fmt::print("Current thread id: {}\n",
fmt::streamed(std::this_thread::get_id()));
\endrst
*/
template <typename T>
auto streamed(const T& value) -> detail::streamed_view<T> {
return {value};
}
namespace detail {
inline void vprint_directly(std::ostream& os, string_view format_str,
format_args args) {
auto buffer = memory_buffer();
detail::vformat_to(buffer, format_str, args);
detail::write_buffer(os, buffer);
}
} // namespace detail
FMT_EXPORT template <typename Char>
void vprint(std::basic_ostream<Char>& os,
basic_string_view<type_identity_t<Char>> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
auto buffer = basic_memory_buffer<Char>();
detail::vformat_to(buffer, format_str, args);
if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return;
detail::write_buffer(os, buffer);
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fmt::print(cerr, "Don't {}!", "panic");
\endrst
*/
FMT_EXPORT template <typename... T>
void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
const auto& vargs = fmt::make_format_args(args...);
if (detail::is_utf8())
vprint(os, fmt, vargs);
else
detail::vprint_directly(os, fmt, vargs);
}
FMT_EXPORT
template <typename... Args>
void print(std::wostream& os,
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
Args&&... args) {
vprint(os, fmt, fmt::make_format_args<buffer_context<wchar_t>>(args...));
}
FMT_EXPORT template <typename... T>
void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
fmt::print(os, "{}\n", fmt::format(fmt, std::forward<T>(args)...));
}
FMT_EXPORT
template <typename... Args>
void println(std::wostream& os,
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
Args&&... args) {
print(os, L"{}\n", fmt::format(fmt, std::forward<Args>(args)...));
}
FMT_END_NAMESPACE
#endif // FMT_OSTREAM_H_

667
include/fmt/printf.h Normal file
View File

@ -0,0 +1,667 @@
// Formatting library for C++ - legacy printf implementation
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_PRINTF_H_
#define FMT_PRINTF_H_
#include <algorithm> // std::max
#include <limits> // std::numeric_limits
#include "format.h"
FMT_BEGIN_NAMESPACE
FMT_BEGIN_EXPORT
template <typename T> struct printf_formatter { printf_formatter() = delete; };
template <typename Char> class basic_printf_context {
private:
detail::buffer_appender<Char> out_;
basic_format_args<basic_printf_context> args_;
public:
using char_type = Char;
using parse_context_type = basic_format_parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>;
/**
\rst
Constructs a ``printf_context`` object. References to the arguments are
stored in the context object so make sure they have appropriate lifetimes.
\endrst
*/
basic_printf_context(detail::buffer_appender<Char> out,
basic_format_args<basic_printf_context> args)
: out_(out), args_(args) {}
auto out() -> detail::buffer_appender<Char> { return out_; }
void advance_to(detail::buffer_appender<Char>) {}
auto locale() -> detail::locale_ref { return {}; }
auto arg(int id) const -> basic_format_arg<basic_printf_context> {
return args_.get(id);
}
FMT_CONSTEXPR void on_error(const char* message) {
detail::error_handler().on_error(message);
}
};
namespace detail {
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned> struct int_checker {
template <typename T> static auto fits_in_int(T value) -> bool {
unsigned max = max_value<int>();
return value <= max;
}
static auto fits_in_int(bool) -> bool { return true; }
};
template <> struct int_checker<true> {
template <typename T> static auto fits_in_int(T value) -> bool {
return value >= (std::numeric_limits<int>::min)() &&
value <= max_value<int>();
}
static auto fits_in_int(int) -> bool { return true; }
};
struct printf_precision_handler {
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
auto operator()(T value) -> int {
if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
throw_format_error("number is too big");
return (std::max)(static_cast<int>(value), 0);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
auto operator()(T) -> int {
throw_format_error("precision is not integer");
return 0;
}
};
// An argument visitor that returns true iff arg is a zero integer.
struct is_zero_int {
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
auto operator()(T value) -> bool {
return value == 0;
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
auto operator()(T) -> bool {
return false;
}
};
template <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};
template <> struct make_unsigned_or_bool<bool> { using type = bool; };
template <typename T, typename Context> class arg_converter {
private:
using char_type = typename Context::char_type;
basic_format_arg<Context>& arg_;
char_type type_;
public:
arg_converter(basic_format_arg<Context>& arg, char_type type)
: arg_(arg), type_(type) {}
void operator()(bool value) {
if (type_ != 's') operator()<bool>(value);
}
template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
void operator()(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
if (const_check(sizeof(target_type) <= sizeof(int))) {
// Extra casts are used to silence warnings.
if (is_signed) {
auto n = static_cast<int>(static_cast<target_type>(value));
arg_ = detail::make_arg<Context>(n);
} else {
using unsigned_type = typename make_unsigned_or_bool<target_type>::type;
auto n = static_cast<unsigned>(static_cast<unsigned_type>(value));
arg_ = detail::make_arg<Context>(n);
}
} else {
if (is_signed) {
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
auto n = static_cast<long long>(value);
arg_ = detail::make_arg<Context>(n);
} else {
auto n = static_cast<typename make_unsigned_or_bool<U>::type>(value);
arg_ = detail::make_arg<Context>(n);
}
}
}
template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>
void operator()(U) {} // No conversion needed for non-integral types.
};
// Converts an integer argument to T for printf, if T is an integral type.
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template <typename T, typename Context, typename Char>
void convert_arg(basic_format_arg<Context>& arg, Char type) {
visit_format_arg(arg_converter<T, Context>(arg, type), arg);
}
// Converts an integer argument to char for printf.
template <typename Context> class char_converter {
private:
basic_format_arg<Context>& arg_;
public:
explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
void operator()(T value) {
auto c = static_cast<typename Context::char_type>(value);
arg_ = detail::make_arg<Context>(c);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
void operator()(T) {} // No conversion needed for non-integral types.
};
// An argument visitor that return a pointer to a C string if argument is a
// string or null otherwise.
template <typename Char> struct get_cstring {
template <typename T> auto operator()(T) -> const Char* { return nullptr; }
auto operator()(const Char* s) -> const Char* { return s; }
};
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
template <typename Char> class printf_width_handler {
private:
format_specs<Char>& specs_;
public:
explicit printf_width_handler(format_specs<Char>& specs) : specs_(specs) {}
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
auto operator()(T value) -> unsigned {
auto width = static_cast<uint32_or_64_or_128_t<T>>(value);
if (detail::is_negative(value)) {
specs_.align = align::left;
width = 0 - width;
}
unsigned int_max = max_value<int>();
if (width > int_max) throw_format_error("number is too big");
return static_cast<unsigned>(width);
}
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
auto operator()(T) -> unsigned {
throw_format_error("width is not integer");
return 0;
}
};
// Workaround for a bug with the XL compiler when initializing
// printf_arg_formatter's base class.
template <typename Char>
auto make_arg_formatter(buffer_appender<Char> iter, format_specs<Char>& s)
-> arg_formatter<Char> {
return {iter, s, locale_ref()};
}
// The ``printf`` argument formatter.
template <typename Char>
class printf_arg_formatter : public arg_formatter<Char> {
private:
using base = arg_formatter<Char>;
using context_type = basic_printf_context<Char>;
context_type& context_;
void write_null_pointer(bool is_string = false) {
auto s = this->specs;
s.type = presentation_type::none;
write_bytes(this->out, is_string ? "(null)" : "(nil)", s);
}
public:
printf_arg_formatter(buffer_appender<Char> iter, format_specs<Char>& s,
context_type& ctx)
: base(make_arg_formatter(iter, s)), context_(ctx) {}
void operator()(monostate value) { base::operator()(value); }
template <typename T, FMT_ENABLE_IF(detail::is_integral<T>::value)>
void operator()(T value) {
// MSVC2013 fails to compile separate overloads for bool and Char so use
// std::is_same instead.
if (!std::is_same<T, Char>::value) {
base::operator()(value);
return;
}
format_specs<Char> fmt_specs = this->specs;
if (fmt_specs.type != presentation_type::none &&
fmt_specs.type != presentation_type::chr) {
return (*this)(static_cast<int>(value));
}
fmt_specs.sign = sign::none;
fmt_specs.alt = false;
fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types.
// align::numeric needs to be overwritten here since the '0' flag is
// ignored for non-numeric types
if (fmt_specs.align == align::none || fmt_specs.align == align::numeric)
fmt_specs.align = align::right;
write<Char>(this->out, static_cast<Char>(value), fmt_specs);
}
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
void operator()(T value) {
base::operator()(value);
}
/** Formats a null-terminated C string. */
void operator()(const char* value) {
if (value)
base::operator()(value);
else
write_null_pointer(this->specs.type != presentation_type::pointer);
}
/** Formats a null-terminated wide C string. */
void operator()(const wchar_t* value) {
if (value)
base::operator()(value);
else
write_null_pointer(this->specs.type != presentation_type::pointer);
}
void operator()(basic_string_view<Char> value) { base::operator()(value); }
/** Formats a pointer. */
void operator()(const void* value) {
if (value)
base::operator()(value);
else
write_null_pointer();
}
/** Formats an argument of a custom (user-defined) type. */
void operator()(typename basic_format_arg<context_type>::handle handle) {
auto parse_ctx = basic_format_parse_context<Char>({});
handle.format(parse_ctx, context_);
}
};
template <typename Char>
void parse_flags(format_specs<Char>& specs, const Char*& it, const Char* end) {
for (; it != end; ++it) {
switch (*it) {
case '-':
specs.align = align::left;
break;
case '+':
specs.sign = sign::plus;
break;
case '0':
specs.fill[0] = '0';
break;
case ' ':
if (specs.sign != sign::plus) specs.sign = sign::space;
break;
case '#':
specs.alt = true;
break;
default:
return;
}
}
}
template <typename Char, typename GetArg>
auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
GetArg get_arg) -> int {
int arg_index = -1;
Char c = *it;
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
int value = parse_nonnegative_int(it, end, -1);
if (it != end && *it == '$') { // value is an argument index
++it;
arg_index = value != -1 ? value : max_value<int>();
} else {
if (c == '0') specs.fill[0] = '0';
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
if (value == -1) throw_format_error("number is too big");
specs.width = value;
return arg_index;
}
}
}
parse_flags(specs, it, end);
// Parse width.
if (it != end) {
if (*it >= '0' && *it <= '9') {
specs.width = parse_nonnegative_int(it, end, -1);
if (specs.width == -1) throw_format_error("number is too big");
} else if (*it == '*') {
++it;
specs.width = static_cast<int>(visit_format_arg(
detail::printf_width_handler<Char>(specs), get_arg(-1)));
}
}
return arg_index;
}
inline auto parse_printf_presentation_type(char c, type t)
-> presentation_type {
using pt = presentation_type;
constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
switch (c) {
case 'd':
return in(t, integral_set) ? pt::dec : pt::none;
case 'o':
return in(t, integral_set) ? pt::oct : pt::none;
case 'x':
return in(t, integral_set) ? pt::hex_lower : pt::none;
case 'X':
return in(t, integral_set) ? pt::hex_upper : pt::none;
case 'a':
return in(t, float_set) ? pt::hexfloat_lower : pt::none;
case 'A':
return in(t, float_set) ? pt::hexfloat_upper : pt::none;
case 'e':
return in(t, float_set) ? pt::exp_lower : pt::none;
case 'E':
return in(t, float_set) ? pt::exp_upper : pt::none;
case 'f':
return in(t, float_set) ? pt::fixed_lower : pt::none;
case 'F':
return in(t, float_set) ? pt::fixed_upper : pt::none;
case 'g':
return in(t, float_set) ? pt::general_lower : pt::none;
case 'G':
return in(t, float_set) ? pt::general_upper : pt::none;
case 'c':
return in(t, integral_set) ? pt::chr : pt::none;
case 's':
return in(t, string_set | cstring_set) ? pt::string : pt::none;
case 'p':
return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;
default:
return pt::none;
}
}
template <typename Char, typename Context>
void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
basic_format_args<Context> args) {
using iterator = buffer_appender<Char>;
auto out = iterator(buf);
auto context = basic_printf_context<Char>(out, args);
auto parse_ctx = basic_format_parse_context<Char>(format);
// Returns the argument with specified index or, if arg_index is -1, the next
// argument.
auto get_arg = [&](int arg_index) {
if (arg_index < 0)
arg_index = parse_ctx.next_arg_id();
else
parse_ctx.check_arg_id(--arg_index);
return detail::get_arg(context, arg_index);
};
const Char* start = parse_ctx.begin();
const Char* end = parse_ctx.end();
auto it = start;
while (it != end) {
if (!find<false, Char>(it, end, '%', it)) {
it = end; // find leaves it == nullptr if it doesn't find '%'.
break;
}
Char c = *it++;
if (it != end && *it == c) {
write(out, basic_string_view<Char>(start, to_unsigned(it - start)));
start = ++it;
continue;
}
write(out, basic_string_view<Char>(start, to_unsigned(it - 1 - start)));
auto specs = format_specs<Char>();
specs.align = align::right;
// Parse argument index, flags and width.
int arg_index = parse_header(it, end, specs, get_arg);
if (arg_index == 0) throw_format_error("argument not found");
// Parse precision.
if (it != end && *it == '.') {
++it;
c = it != end ? *it : 0;
if ('0' <= c && c <= '9') {
specs.precision = parse_nonnegative_int(it, end, 0);
} else if (c == '*') {
++it;
specs.precision = static_cast<int>(
visit_format_arg(printf_precision_handler(), get_arg(-1)));
} else {
specs.precision = 0;
}
}
auto arg = get_arg(arg_index);
// For d, i, o, u, x, and X conversion specifiers, if a precision is
// specified, the '0' flag is ignored
if (specs.precision >= 0 && arg.is_integral()) {
// Ignore '0' for non-numeric types or if '-' present.
specs.fill[0] = ' ';
}
if (specs.precision >= 0 && arg.type() == type::cstring_type) {
auto str = visit_format_arg(get_cstring<Char>(), arg);
auto str_end = str + specs.precision;
auto nul = std::find(str, str_end, Char());
auto sv = basic_string_view<Char>(
str, to_unsigned(nul != str_end ? nul - str : specs.precision));
arg = make_arg<basic_printf_context<Char>>(sv);
}
if (specs.alt && visit_format_arg(is_zero_int(), arg)) specs.alt = false;
if (specs.fill[0] == '0') {
if (arg.is_arithmetic() && specs.align != align::left)
specs.align = align::numeric;
else
specs.fill[0] = ' '; // Ignore '0' flag for non-numeric types or if '-'
// flag is also present.
}
// Parse length and convert the argument to the required type.
c = it != end ? *it++ : 0;
Char t = it != end ? *it : 0;
switch (c) {
case 'h':
if (t == 'h') {
++it;
t = it != end ? *it : 0;
convert_arg<signed char>(arg, t);
} else {
convert_arg<short>(arg, t);
}
break;
case 'l':
if (t == 'l') {
++it;
t = it != end ? *it : 0;
convert_arg<long long>(arg, t);
} else {
convert_arg<long>(arg, t);
}
break;
case 'j':
convert_arg<intmax_t>(arg, t);
break;
case 'z':
convert_arg<size_t>(arg, t);
break;
case 't':
convert_arg<std::ptrdiff_t>(arg, t);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--it;
convert_arg<void>(arg, c);
}
// Parse type.
if (it == end) throw_format_error("invalid format string");
char type = static_cast<char>(*it++);
if (arg.is_integral()) {
// Normalize type.
switch (type) {
case 'i':
case 'u':
type = 'd';
break;
case 'c':
visit_format_arg(char_converter<basic_printf_context<Char>>(arg), arg);
break;
}
}
specs.type = parse_printf_presentation_type(type, arg.type());
if (specs.type == presentation_type::none)
throw_format_error("invalid format specifier");
start = it;
// Format argument.
visit_format_arg(printf_arg_formatter<Char>(out, specs, context), arg);
}
write(out, basic_string_view<Char>(start, to_unsigned(it - start)));
}
} // namespace detail
using printf_context = basic_printf_context<char>;
using wprintf_context = basic_printf_context<wchar_t>;
using printf_args = basic_format_args<printf_context>;
using wprintf_args = basic_format_args<wprintf_context>;
/**
\rst
Constructs an `~fmt::format_arg_store` object that contains references to
arguments and can be implicitly converted to `~fmt::printf_args`.
\endrst
*/
template <typename... T>
inline auto make_printf_args(const T&... args)
-> format_arg_store<printf_context, T...> {
return {args...};
}
// DEPRECATED!
template <typename... T>
inline auto make_wprintf_args(const T&... args)
-> format_arg_store<wprintf_context, T...> {
return {args...};
}
template <typename Char>
inline auto vsprintf(
basic_string_view<Char> fmt,
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
auto buf = basic_memory_buffer<Char>();
detail::vprintf(buf, fmt, args);
return to_string(buf);
}
/**
\rst
Formats arguments and returns the result as a string.
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
*/
template <typename S, typename... T,
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string<Char> {
return vsprintf(detail::to_string_view(fmt),
fmt::make_format_args<basic_printf_context<Char>>(args...));
}
template <typename Char>
inline auto vfprintf(
std::FILE* f, basic_string_view<Char> fmt,
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
-> int {
auto buf = basic_memory_buffer<Char>();
detail::vprintf(buf, fmt, args);
size_t size = buf.size();
return std::fwrite(buf.data(), sizeof(Char), size, f) < size
? -1
: static_cast<int>(size);
}
/**
\rst
Prints formatted data to the file *f*.
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
*/
template <typename S, typename... T, typename Char = char_t<S>>
inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int {
return vfprintf(f, detail::to_string_view(fmt),
fmt::make_format_args<basic_printf_context<Char>>(args...));
}
template <typename Char>
FMT_DEPRECATED inline auto vprintf(
basic_string_view<Char> fmt,
basic_format_args<basic_printf_context<type_identity_t<Char>>> args)
-> int {
return vfprintf(stdout, fmt, args);
}
/**
\rst
Prints formatted data to ``stdout``.
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
*/
template <typename... T>
inline auto printf(string_view fmt, const T&... args) -> int {
return vfprintf(stdout, fmt, make_printf_args(args...));
}
template <typename... T>
FMT_DEPRECATED inline auto printf(basic_string_view<wchar_t> fmt,
const T&... args) -> int {
return vfprintf(stdout, fmt, make_wprintf_args(args...));
}
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_PRINTF_H_

735
include/fmt/ranges.h Normal file
View File

@ -0,0 +1,735 @@
// Formatting library for C++ - experimental range support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
//
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
// All Rights Reserved
// {fmt} support for ranges, containers and types tuple interface.
#ifndef FMT_RANGES_H_
#define FMT_RANGES_H_
#include <initializer_list>
#include <tuple>
#include <type_traits>
#include "format.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Range, typename OutputIt>
auto copy(const Range& range, OutputIt out) -> OutputIt {
for (auto it = range.begin(), end = range.end(); it != end; ++it)
*out++ = *it;
return out;
}
template <typename OutputIt>
auto copy(const char* str, OutputIt out) -> OutputIt {
while (*str) *out++ = *str++;
return out;
}
template <typename OutputIt> auto copy(char ch, OutputIt out) -> OutputIt {
*out++ = ch;
return out;
}
template <typename OutputIt> auto copy(wchar_t ch, OutputIt out) -> OutputIt {
*out++ = ch;
return out;
}
// Returns true if T has a std::string-like interface, like std::string_view.
template <typename T> class is_std_string_like {
template <typename U>
static auto check(U* p)
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
template <typename> static void check(...);
public:
static constexpr const bool value =
is_string<T>::value ||
std::is_convertible<T, std_string_view<char>>::value ||
!std::is_void<decltype(check<T>(nullptr))>::value;
};
template <typename Char>
struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {};
template <typename T> class is_map {
template <typename U> static auto check(U*) -> typename U::mapped_type;
template <typename> static void check(...);
public:
#ifdef FMT_FORMAT_MAP_AS_LIST // DEPRECATED!
static constexpr const bool value = false;
#else
static constexpr const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
#endif
};
template <typename T> class is_set {
template <typename U> static auto check(U*) -> typename U::key_type;
template <typename> static void check(...);
public:
#ifdef FMT_FORMAT_SET_AS_LIST // DEPRECATED!
static constexpr const bool value = false;
#else
static constexpr const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
#endif
};
template <typename... Ts> struct conditional_helper {};
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
# define FMT_DECLTYPE_RETURN(val) \
->decltype(val) { return val; } \
static_assert( \
true, "") // This makes it so that a semicolon is required after the
// macro, which helps clang-format handle the formatting.
// C array overload
template <typename T, std::size_t N>
auto range_begin(const T (&arr)[N]) -> const T* {
return arr;
}
template <typename T, std::size_t N>
auto range_end(const T (&arr)[N]) -> const T* {
return arr + N;
}
template <typename T, typename Enable = void>
struct has_member_fn_begin_end_t : std::false_type {};
template <typename T>
struct has_member_fn_begin_end_t<T, void_t<decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>>
: std::true_type {};
// Member function overload
template <typename T>
auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin());
template <typename T>
auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end());
// ADL overload. Only participates in overload resolution if member functions
// are not found.
template <typename T>
auto range_begin(T&& rng)
-> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
decltype(begin(static_cast<T&&>(rng)))> {
return begin(static_cast<T&&>(rng));
}
template <typename T>
auto range_end(T&& rng) -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
decltype(end(static_cast<T&&>(rng)))> {
return end(static_cast<T&&>(rng));
}
template <typename T, typename Enable = void>
struct has_const_begin_end : std::false_type {};
template <typename T, typename Enable = void>
struct has_mutable_begin_end : std::false_type {};
template <typename T>
struct has_const_begin_end<
T,
void_t<
decltype(detail::range_begin(std::declval<const remove_cvref_t<T>&>())),
decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>>
: std::true_type {};
template <typename T>
struct has_mutable_begin_end<
T, void_t<decltype(detail::range_begin(std::declval<T>())),
decltype(detail::range_end(std::declval<T>())),
// the extra int here is because older versions of MSVC don't
// SFINAE properly unless there are distinct types
int>> : std::true_type {};
template <typename T>
struct is_range_<T, void>
: std::integral_constant<bool, (has_const_begin_end<T>::value ||
has_mutable_begin_end<T>::value)> {};
# undef FMT_DECLTYPE_RETURN
#endif
// tuple_size and tuple_element check.
template <typename T> class is_tuple_like_ {
template <typename U>
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
template <typename> static void check(...);
public:
static constexpr const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
};
// Check for integer_sequence
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
template <typename T, T... N>
using integer_sequence = std::integer_sequence<T, N...>;
template <size_t... N> using index_sequence = std::index_sequence<N...>;
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
#else
template <typename T, T... N> struct integer_sequence {
using value_type = T;
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
};
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
template <typename T, size_t N, T... Ns>
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
template <typename T, T... Ns>
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
template <size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
#endif
template <typename T>
using tuple_index_sequence = make_index_sequence<std::tuple_size<T>::value>;
template <typename T, typename C, bool = is_tuple_like_<T>::value>
class is_tuple_formattable_ {
public:
static constexpr const bool value = false;
};
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
template <std::size_t... Is>
static std::true_type check2(index_sequence<Is...>,
integer_sequence<bool, (Is == Is)...>);
static std::false_type check2(...);
template <std::size_t... Is>
static decltype(check2(
index_sequence<Is...>{},
integer_sequence<
bool, (is_formattable<typename std::tuple_element<Is, T>::type,
C>::value)...>{})) check(index_sequence<Is...>);
public:
static constexpr const bool value =
decltype(check(tuple_index_sequence<T>{}))::value;
};
template <typename Tuple, typename F, size_t... Is>
FMT_CONSTEXPR void for_each(index_sequence<Is...>, Tuple&& t, F&& f) {
using std::get;
// Using a free function get<Is>(Tuple) now.
const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};
ignore_unused(unused);
}
template <typename Tuple, typename F>
FMT_CONSTEXPR void for_each(Tuple&& t, F&& f) {
for_each(tuple_index_sequence<remove_cvref_t<Tuple>>(),
std::forward<Tuple>(t), std::forward<F>(f));
}
template <typename Tuple1, typename Tuple2, typename F, size_t... Is>
void for_each2(index_sequence<Is...>, Tuple1&& t1, Tuple2&& t2, F&& f) {
using std::get;
const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};
ignore_unused(unused);
}
template <typename Tuple1, typename Tuple2, typename F>
void for_each2(Tuple1&& t1, Tuple2&& t2, F&& f) {
for_each2(tuple_index_sequence<remove_cvref_t<Tuple1>>(),
std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
std::forward<F>(f));
}
namespace tuple {
// Workaround a bug in MSVC 2019 (v140).
template <typename Char, typename... T>
using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
using std::get;
template <typename Tuple, typename Char, std::size_t... Is>
auto get_formatters(index_sequence<Is...>)
-> result_t<Char, decltype(get<Is>(std::declval<Tuple>()))...>;
} // namespace tuple
#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
// Older MSVC doesn't get the reference type correctly for arrays.
template <typename R> struct range_reference_type_impl {
using type = decltype(*detail::range_begin(std::declval<R&>()));
};
template <typename T, std::size_t N> struct range_reference_type_impl<T[N]> {
using type = T&;
};
template <typename T>
using range_reference_type = typename range_reference_type_impl<T>::type;
#else
template <typename Range>
using range_reference_type =
decltype(*detail::range_begin(std::declval<Range&>()));
#endif
// We don't use the Range's value_type for anything, but we do need the Range's
// reference type, with cv-ref stripped.
template <typename Range>
using uncvref_type = remove_cvref_t<range_reference_type<Range>>;
template <typename Formatter>
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set)
-> decltype(f.set_debug_format(set)) {
f.set_debug_format(set);
}
template <typename Formatter>
FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {}
// These are not generic lambdas for compatibility with C++11.
template <typename ParseContext> struct parse_empty_specs {
template <typename Formatter> FMT_CONSTEXPR void operator()(Formatter& f) {
f.parse(ctx);
detail::maybe_set_debug_format(f, true);
}
ParseContext& ctx;
};
template <typename FormatContext> struct format_tuple_element {
using char_type = typename FormatContext::char_type;
template <typename T>
void operator()(const formatter<T, char_type>& f, const T& v) {
if (i > 0)
ctx.advance_to(detail::copy_str<char_type>(separator, ctx.out()));
ctx.advance_to(f.format(v, ctx));
++i;
}
int i;
FormatContext& ctx;
basic_string_view<char_type> separator;
};
} // namespace detail
template <typename T> struct is_tuple_like {
static constexpr const bool value =
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
};
template <typename T, typename C> struct is_tuple_formattable {
static constexpr const bool value =
detail::is_tuple_formattable_<T, C>::value;
};
template <typename Tuple, typename Char>
struct formatter<Tuple, Char,
enable_if_t<fmt::is_tuple_like<Tuple>::value &&
fmt::is_tuple_formattable<Tuple, Char>::value>> {
private:
decltype(detail::tuple::get_formatters<Tuple, Char>(
detail::tuple_index_sequence<Tuple>())) formatters_;
basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
basic_string_view<Char> opening_bracket_ =
detail::string_literal<Char, '('>{};
basic_string_view<Char> closing_bracket_ =
detail::string_literal<Char, ')'>{};
public:
FMT_CONSTEXPR formatter() {}
FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {
separator_ = sep;
}
FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,
basic_string_view<Char> close) {
opening_bracket_ = open;
closing_bracket_ = close;
}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin();
if (it != ctx.end() && *it != '}')
FMT_THROW(format_error("invalid format specifier"));
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
return it;
}
template <typename FormatContext>
auto format(const Tuple& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
ctx.advance_to(detail::copy_str<Char>(opening_bracket_, ctx.out()));
detail::for_each2(
formatters_, value,
detail::format_tuple_element<FormatContext>{0, ctx, separator_});
return detail::copy_str<Char>(closing_bracket_, ctx.out());
}
};
template <typename T, typename Char> struct is_range {
static constexpr const bool value =
detail::is_range_<T>::value && !detail::is_std_string_like<T>::value &&
!std::is_convertible<T, std::basic_string<Char>>::value &&
!std::is_convertible<T, detail::std_string_view<Char>>::value;
};
namespace detail {
template <typename Context> struct range_mapper {
using mapper = arg_mapper<Context>;
template <typename T,
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, Context>::value)>
static auto map(T&& value) -> T&& {
return static_cast<T&&>(value);
}
template <typename T,
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, Context>::value)>
static auto map(T&& value)
-> decltype(mapper().map(static_cast<T&&>(value))) {
return mapper().map(static_cast<T&&>(value));
}
};
template <typename Char, typename Element>
using range_formatter_type =
formatter<remove_cvref_t<decltype(range_mapper<buffer_context<Char>>{}.map(
std::declval<Element>()))>,
Char>;
template <typename R>
using maybe_const_range =
conditional_t<has_const_begin_end<R>::value, const R, R>;
// Workaround a bug in MSVC 2015 and earlier.
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
template <typename R, typename Char>
struct is_formattable_delayed
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
#endif
} // namespace detail
template <typename T, typename Char, typename Enable = void>
struct range_formatter;
template <typename T, typename Char>
struct range_formatter<
T, Char,
enable_if_t<conjunction<std::is_same<T, remove_cvref_t<T>>,
is_formattable<T, Char>>::value>> {
private:
detail::range_formatter_type<Char, T> underlying_;
basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
basic_string_view<Char> opening_bracket_ =
detail::string_literal<Char, '['>{};
basic_string_view<Char> closing_bracket_ =
detail::string_literal<Char, ']'>{};
public:
FMT_CONSTEXPR range_formatter() {}
FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type<Char, T>& {
return underlying_;
}
FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {
separator_ = sep;
}
FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,
basic_string_view<Char> close) {
opening_bracket_ = open;
closing_bracket_ = close;
}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin();
auto end = ctx.end();
if (it != end && *it == 'n') {
set_brackets({}, {});
++it;
}
if (it != end && *it != '}') {
if (*it != ':') FMT_THROW(format_error("invalid format specifier"));
++it;
} else {
detail::maybe_set_debug_format(underlying_, true);
}
ctx.advance_to(it);
return underlying_.parse(ctx);
}
template <typename R, typename FormatContext>
auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {
detail::range_mapper<buffer_context<Char>> mapper;
auto out = ctx.out();
out = detail::copy_str<Char>(opening_bracket_, out);
int i = 0;
auto it = detail::range_begin(range);
auto end = detail::range_end(range);
for (; it != end; ++it) {
if (i > 0) out = detail::copy_str<Char>(separator_, out);
ctx.advance_to(out);
out = underlying_.format(mapper.map(*it), ctx);
++i;
}
out = detail::copy_str<Char>(closing_bracket_, out);
return out;
}
};
enum class range_format { disabled, map, set, sequence, string, debug_string };
namespace detail {
template <typename T>
struct range_format_kind_
: std::integral_constant<range_format,
std::is_same<uncvref_type<T>, T>::value
? range_format::disabled
: is_map<T>::value ? range_format::map
: is_set<T>::value ? range_format::set
: range_format::sequence> {};
template <range_format K, typename R, typename Char, typename Enable = void>
struct range_default_formatter;
template <range_format K>
using range_format_constant = std::integral_constant<range_format, K>;
template <range_format K, typename R, typename Char>
struct range_default_formatter<
K, R, Char,
enable_if_t<(K == range_format::sequence || K == range_format::map ||
K == range_format::set)>> {
using range_type = detail::maybe_const_range<R>;
range_formatter<detail::uncvref_type<range_type>, Char> underlying_;
FMT_CONSTEXPR range_default_formatter() { init(range_format_constant<K>()); }
FMT_CONSTEXPR void init(range_format_constant<range_format::set>) {
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
detail::string_literal<Char, '}'>{});
}
FMT_CONSTEXPR void init(range_format_constant<range_format::map>) {
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
detail::string_literal<Char, '}'>{});
underlying_.underlying().set_brackets({}, {});
underlying_.underlying().set_separator(
detail::string_literal<Char, ':', ' '>{});
}
FMT_CONSTEXPR void init(range_format_constant<range_format::sequence>) {}
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return underlying_.parse(ctx);
}
template <typename FormatContext>
auto format(range_type& range, FormatContext& ctx) const
-> decltype(ctx.out()) {
return underlying_.format(range, ctx);
}
};
} // namespace detail
template <typename T, typename Char, typename Enable = void>
struct range_format_kind
: conditional_t<
is_range<T, Char>::value, detail::range_format_kind_<T>,
std::integral_constant<range_format, range_format::disabled>> {};
template <typename R, typename Char>
struct formatter<
R, Char,
enable_if_t<conjunction<bool_constant<range_format_kind<R, Char>::value !=
range_format::disabled>
// Workaround a bug in MSVC 2015 and earlier.
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
,
detail::is_formattable_delayed<R, Char>
#endif
>::value>>
: detail::range_default_formatter<range_format_kind<R, Char>::value, R,
Char> {
};
template <typename Char, typename... T> struct tuple_join_view : detail::view {
const std::tuple<T...>& tuple;
basic_string_view<Char> sep;
tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
: tuple(t), sep{s} {}
};
// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers
// support in tuple_join. It is disabled by default because of issues with
// the dynamic width and precision.
#ifndef FMT_TUPLE_JOIN_SPECIFIERS
# define FMT_TUPLE_JOIN_SPECIFIERS 0
#endif
template <typename Char, typename... T>
struct formatter<tuple_join_view<Char, T...>, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
}
template <typename FormatContext>
auto format(const tuple_join_view<Char, T...>& value,
FormatContext& ctx) const -> typename FormatContext::iterator {
return do_format(value, ctx,
std::integral_constant<size_t, sizeof...(T)>());
}
private:
std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
template <typename ParseContext>
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
std::integral_constant<size_t, 0>)
-> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename ParseContext, size_t N>
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
std::integral_constant<size_t, N>)
-> decltype(ctx.begin()) {
auto end = ctx.begin();
#if FMT_TUPLE_JOIN_SPECIFIERS
end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
if (N > 1) {
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
if (end != end1)
FMT_THROW(format_error("incompatible format specs for tuple elements"));
}
#endif
return end;
}
template <typename FormatContext>
auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx,
std::integral_constant<size_t, 0>) const ->
typename FormatContext::iterator {
return ctx.out();
}
template <typename FormatContext, size_t N>
auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx,
std::integral_constant<size_t, N>) const ->
typename FormatContext::iterator {
auto out = std::get<sizeof...(T) - N>(formatters_)
.format(std::get<sizeof...(T) - N>(value.tuple), ctx);
if (N > 1) {
out = std::copy(value.sep.begin(), value.sep.end(), out);
ctx.advance_to(out);
return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
}
return out;
}
};
namespace detail {
// Check if T has an interface like a container adaptor (e.g. std::stack,
// std::queue, std::priority_queue).
template <typename T> class is_container_adaptor_like {
template <typename U> static auto check(U* p) -> typename U::container_type;
template <typename> static void check(...);
public:
static constexpr const bool value =
!std::is_void<decltype(check<T>(nullptr))>::value;
};
template <typename Container> struct all {
const Container& c;
auto begin() const -> typename Container::const_iterator { return c.begin(); }
auto end() const -> typename Container::const_iterator { return c.end(); }
};
} // namespace detail
template <typename T, typename Char>
struct formatter<
T, Char,
enable_if_t<conjunction<detail::is_container_adaptor_like<T>,
bool_constant<range_format_kind<T, Char>::value ==
range_format::disabled>>::value>>
: formatter<detail::all<typename T::container_type>, Char> {
using all = detail::all<typename T::container_type>;
template <typename FormatContext>
auto format(const T& t, FormatContext& ctx) const -> decltype(ctx.out()) {
struct getter : T {
static auto get(const T& t) -> all {
return {t.*(&getter::c)}; // Access c through the derived class.
}
};
return formatter<all>::format(getter::get(t), ctx);
}
};
FMT_BEGIN_EXPORT
/**
\rst
Returns an object that formats `tuple` with elements separated by `sep`.
**Example**::
std::tuple<int, char> t = {1, 'a'};
fmt::print("{}", fmt::join(t, ", "));
// Output: "1, a"
\endrst
*/
template <typename... T>
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
-> tuple_join_view<char, T...> {
return {tuple, sep};
}
template <typename... T>
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple,
basic_string_view<wchar_t> sep)
-> tuple_join_view<wchar_t, T...> {
return {tuple, sep};
}
/**
\rst
Returns an object that formats `initializer_list` with elements separated by
`sep`.
**Example**::
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
// Output: "1, 2, 3"
\endrst
*/
template <typename T>
auto join(std::initializer_list<T> list, string_view sep)
-> join_view<const T*, const T*> {
return join(std::begin(list), std::end(list), sep);
}
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_RANGES_H_

465
include/fmt/std.h Normal file
View File

@ -0,0 +1,465 @@
// Formatting library for C++ - formatters for standard library types
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_STD_H_
#define FMT_STD_H_
#include <atomic>
#include <bitset>
#include <cstdlib>
#include <exception>
#include <memory>
#include <thread>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <vector>
#include "format.h"
#include "ostream.h"
#if FMT_HAS_INCLUDE(<version>)
# include <version>
#endif
// Checking FMT_CPLUSPLUS for warning suppression in MSVC.
#if FMT_CPLUSPLUS >= 201703L
# if FMT_HAS_INCLUDE(<filesystem>)
# include <filesystem>
# endif
# if FMT_HAS_INCLUDE(<variant>)
# include <variant>
# endif
# if FMT_HAS_INCLUDE(<optional>)
# include <optional>
# endif
#endif
// GCC 4 does not support FMT_HAS_INCLUDE.
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
# include <cxxabi.h>
// Android NDK with gabi++ library on some architectures does not implement
// abi::__cxa_demangle().
# ifndef __GABIXX_CXXABI_H__
# define FMT_HAS_ABI_CXA_DEMANGLE
# endif
#endif
// Check if typeid is available.
#ifndef FMT_USE_TYPEID
// __RTTI is for EDG compilers. In MSVC typeid is available without RTTI.
# if defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || FMT_MSC_VERSION || \
defined(__INTEL_RTTI__) || defined(__RTTI)
# define FMT_USE_TYPEID 1
# else
# define FMT_USE_TYPEID 0
# endif
#endif
#ifdef __cpp_lib_filesystem
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename Char> auto get_path_string(const std::filesystem::path& p) {
return p.string<Char>();
}
template <typename Char>
void write_escaped_path(basic_memory_buffer<Char>& quoted,
const std::filesystem::path& p) {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}
# ifdef _WIN32
template <>
inline auto get_path_string<char>(const std::filesystem::path& p) {
return to_utf8<wchar_t>(p.native(), to_utf8_error_policy::replace);
}
template <>
inline void write_escaped_path<char>(memory_buffer& quoted,
const std::filesystem::path& p) {
auto buf = basic_memory_buffer<wchar_t>();
write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
FMT_ASSERT(valid, "invalid utf16");
}
# endif // _WIN32
template <>
inline void write_escaped_path<std::filesystem::path::value_type>(
basic_memory_buffer<std::filesystem::path::value_type>& quoted,
const std::filesystem::path& p) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), p.native());
}
} // namespace detail
FMT_EXPORT
template <typename Char> struct formatter<std::filesystem::path, Char> {
private:
format_specs<Char> specs_;
detail::arg_ref<Char> width_ref_;
bool debug_ = false;
public:
FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it == end) return it;
it = detail::parse_align(it, end, specs_);
if (it == end) return it;
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
if (it != end && *it == '?') {
debug_ = true;
++it;
}
return it;
}
template <typename FormatContext>
auto format(const std::filesystem::path& p, FormatContext& ctx) const {
auto specs = specs_;
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
if (!debug_) {
auto s = detail::get_path_string<Char>(p);
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
}
auto quoted = basic_memory_buffer<Char>();
detail::write_escaped_path(quoted, p);
return detail::write(ctx.out(),
basic_string_view<Char>(quoted.data(), quoted.size()),
specs);
}
};
FMT_END_NAMESPACE
#endif
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename Char>
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
FMT_END_NAMESPACE
#ifdef __cpp_lib_optional
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename T, typename Char>
struct formatter<std::optional<T>, Char,
std::enable_if_t<is_formattable<T, Char>::value>> {
private:
formatter<T, Char> underlying_;
static constexpr basic_string_view<Char> optional =
detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
'('>{};
static constexpr basic_string_view<Char> none =
detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};
template <class U>
FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
-> decltype(u.set_debug_format(set)) {
u.set_debug_format(set);
}
template <class U>
FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
public:
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
maybe_set_debug_format(underlying_, true);
return underlying_.parse(ctx);
}
template <typename FormatContext>
auto format(std::optional<T> const& opt, FormatContext& ctx) const
-> decltype(ctx.out()) {
if (!opt) return detail::write<Char>(ctx.out(), none);
auto out = ctx.out();
out = detail::write<Char>(out, optional);
ctx.advance_to(out);
out = underlying_.format(*opt, ctx);
return detail::write(out, ')');
}
};
FMT_END_NAMESPACE
#endif // __cpp_lib_optional
#ifdef __cpp_lib_variant
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T>
using variant_index_sequence =
std::make_index_sequence<std::variant_size<T>::value>;
template <typename> struct is_variant_like_ : std::false_type {};
template <typename... Types>
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
// formattable element check.
template <typename T, typename C> class is_variant_formattable_ {
template <std::size_t... Is>
static std::conjunction<
is_formattable<std::variant_alternative_t<Is, T>, C>...>
check(std::index_sequence<Is...>);
public:
static constexpr const bool value =
decltype(check(variant_index_sequence<T>{}))::value;
};
template <typename Char, typename OutputIt, typename T>
auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
if constexpr (is_string<T>::value)
return write_escaped_string<Char>(out, detail::to_string_view(v));
else if constexpr (std::is_same_v<T, Char>)
return write_escaped_char(out, v);
else
return write<Char>(out, v);
}
} // namespace detail
template <typename T> struct is_variant_like {
static constexpr const bool value = detail::is_variant_like_<T>::value;
};
template <typename T, typename C> struct is_variant_formattable {
static constexpr const bool value =
detail::is_variant_formattable_<T, C>::value;
};
FMT_EXPORT
template <typename Char> struct formatter<std::monostate, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const std::monostate&, FormatContext& ctx) const
-> decltype(ctx.out()) {
return detail::write<Char>(ctx.out(), "monostate");
}
};
FMT_EXPORT
template <typename Variant, typename Char>
struct formatter<
Variant, Char,
std::enable_if_t<std::conjunction_v<
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const Variant& value, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write<Char>(out, "variant(");
FMT_TRY {
std::visit(
[&](const auto& v) {
out = detail::write_variant_alternative<Char>(out, v);
},
value);
}
FMT_CATCH(const std::bad_variant_access&) {
detail::write<Char>(out, "valueless by exception");
}
*out++ = ')';
return out;
}
};
FMT_END_NAMESPACE
#endif // __cpp_lib_variant
FMT_BEGIN_NAMESPACE
FMT_EXPORT
template <typename Char> struct formatter<std::error_code, Char> {
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
-> decltype(ctx.out()) {
auto out = ctx.out();
out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
out = detail::write<Char>(out, Char(':'));
out = detail::write<Char>(out, ec.value());
return out;
}
};
FMT_EXPORT
template <typename T, typename Char>
struct formatter<
T, Char,
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
private:
bool with_typename_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
auto it = ctx.begin();
auto end = ctx.end();
if (it == end || *it == '}') return it;
if (*it == 't') {
++it;
with_typename_ = FMT_USE_TYPEID != 0;
}
return it;
}
template <typename OutputIt>
auto format(const std::exception& ex,
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
format_specs<Char> spec;
auto out = ctx.out();
if (!with_typename_)
return detail::write_bytes(out, string_view(ex.what()), spec);
#if FMT_USE_TYPEID
const std::type_info& ti = typeid(ex);
# ifdef FMT_HAS_ABI_CXA_DEMANGLE
int status = 0;
std::size_t size = 0;
std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
string_view demangled_name_view;
if (demangled_name_ptr) {
demangled_name_view = demangled_name_ptr.get();
// Normalization of stdlib inline namespace names.
// libc++ inline namespaces.
// std::__1::* -> std::*
// std::__1::__fs::* -> std::*
// libstdc++ inline namespaces.
// std::__cxx11::* -> std::*
// std::filesystem::__cxx11::* -> std::filesystem::*
if (demangled_name_view.starts_with("std::")) {
char* begin = demangled_name_ptr.get();
char* to = begin + 5; // std::
for (char *from = to, *end = begin + demangled_name_view.size();
from < end;) {
// This is safe, because demangled_name is NUL-terminated.
if (from[0] == '_' && from[1] == '_') {
char* next = from + 1;
while (next < end && *next != ':') next++;
if (next[0] == ':' && next[1] == ':') {
from = next + 2;
continue;
}
}
*to++ = *from++;
}
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
}
} else {
demangled_name_view = string_view(ti.name());
}
out = detail::write_bytes(out, demangled_name_view, spec);
# elif FMT_MSC_VERSION
string_view demangled_name_view(ti.name());
if (demangled_name_view.starts_with("class "))
demangled_name_view.remove_prefix(6);
else if (demangled_name_view.starts_with("struct "))
demangled_name_view.remove_prefix(7);
out = detail::write_bytes(out, demangled_name_view, spec);
# else
out = detail::write_bytes(out, string_view(ti.name()), spec);
# endif
*out++ = ':';
*out++ = ' ';
return detail::write_bytes(out, string_view(ex.what()), spec);
#endif
}
};
namespace detail {
template <typename T, typename Enable = void>
struct has_flip : std::false_type {};
template <typename T>
struct has_flip<T, void_t<decltype(std::declval<T>().flip())>>
: std::true_type {};
template <typename T> struct is_bit_reference_like {
static constexpr const bool value =
std::is_convertible<T, bool>::value &&
std::is_nothrow_assignable<T, bool>::value && has_flip<T>::value;
};
#ifdef _LIBCPP_VERSION
// Workaround for libc++ incompatibility with C++ standard.
// According to the Standard, `bitset::operator[] const` returns bool.
template <typename C>
struct is_bit_reference_like<std::__bit_const_reference<C>> {
static constexpr const bool value = true;
};
#endif
} // namespace detail
// We can't use std::vector<bool, Allocator>::reference and
// std::bitset<N>::reference because the compiler can't deduce Allocator and N
// in partial specialization.
FMT_EXPORT
template <typename BitRef, typename Char>
struct formatter<BitRef, Char,
enable_if_t<detail::is_bit_reference_like<BitRef>::value>>
: formatter<bool, Char> {
template <typename FormatContext>
FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<bool, Char>::format(v, ctx);
}
};
FMT_EXPORT
template <typename T, typename Char>
struct formatter<std::atomic<T>, Char,
enable_if_t<is_formattable<T, Char>::value>>
: formatter<T, Char> {
template <typename FormatContext>
auto format(const std::atomic<T>& v, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<T, Char>::format(v.load(), ctx);
}
};
#ifdef __cpp_lib_atomic_flag_test
FMT_EXPORT
template <typename Char>
struct formatter<std::atomic_flag, Char>
: formatter<bool, Char> {
template <typename FormatContext>
auto format(const std::atomic_flag& v, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<bool, Char>::format(v.test(), ctx);
}
};
#endif // __cpp_lib_atomic_flag_test
FMT_END_NAMESPACE
#endif // FMT_STD_H_

258
include/fmt/xchar.h Normal file
View File

@ -0,0 +1,258 @@
// Formatting library for C++ - optional wchar_t and exotic character support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_XCHAR_H_
#define FMT_XCHAR_H_
#include <cwchar>
#include "format.h"
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
# include <locale>
#endif
FMT_BEGIN_NAMESPACE
namespace detail {
template <typename T>
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
inline auto write_loc(std::back_insert_iterator<detail::buffer<wchar_t>> out,
loc_value value, const format_specs<wchar_t>& specs,
locale_ref loc) -> bool {
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
auto& numpunct =
std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());
auto separator = std::wstring();
auto grouping = numpunct.grouping();
if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
#endif
return false;
}
} // namespace detail
FMT_BEGIN_EXPORT
using wstring_view = basic_string_view<wchar_t>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
using wformat_context = buffer_context<wchar_t>;
using wformat_args = basic_format_args<wformat_context>;
using wmemory_buffer = basic_memory_buffer<wchar_t>;
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
// Workaround broken conversion on older gcc.
template <typename... Args> using wformat_string = wstring_view;
inline auto runtime(wstring_view s) -> wstring_view { return s; }
#else
template <typename... Args>
using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;
inline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {
return {{s}};
}
#endif
template <> struct is_char<wchar_t> : std::true_type {};
template <> struct is_char<detail::char8_type> : std::true_type {};
template <> struct is_char<char16_t> : std::true_type {};
template <> struct is_char<char32_t> : std::true_type {};
template <typename... T>
constexpr format_arg_store<wformat_context, T...> make_wformat_args(
const T&... args) {
return {args...};
}
inline namespace literals {
#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS
constexpr detail::udl_arg<wchar_t> operator"" _a(const wchar_t* s, size_t) {
return {s};
}
#endif
} // namespace literals
template <typename It, typename Sentinel>
auto join(It begin, Sentinel end, wstring_view sep)
-> join_view<It, Sentinel, wchar_t> {
return {begin, end, sep};
}
template <typename Range>
auto join(Range&& range, wstring_view sep)
-> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>,
wchar_t> {
return join(std::begin(range), std::end(range), sep);
}
template <typename T>
auto join(std::initializer_list<T> list, wstring_view sep)
-> join_view<const T*, const T*, wchar_t> {
return join(std::begin(list), std::end(list), sep);
}
template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
auto vformat(basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
auto buf = basic_memory_buffer<Char>();
detail::vformat_to(buf, format_str, args);
return to_string(buf);
}
template <typename... T>
auto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {
return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));
}
// Pass char_t as a default template parameter instead of using
// std::basic_string<char_t<S>> to reduce the symbol size.
template <typename S, typename... T, typename Char = char_t<S>,
FMT_ENABLE_IF(!std::is_same<Char, char>::value &&
!std::is_same<Char, wchar_t>::value)>
auto format(const S& format_str, T&&... args) -> std::basic_string<Char> {
return vformat(detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}
template <typename Locale, typename S, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat(
const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> std::basic_string<Char> {
return detail::vformat(loc, detail::to_string_view(format_str), args);
}
template <typename Locale, typename S, typename... T, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format(const Locale& loc, const S& format_str, T&&... args)
-> std::basic_string<Char> {
return detail::vformat(loc, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}
template <typename OutputIt, typename S, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
auto vformat_to(OutputIt out, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, detail::to_string_view(format_str), args);
return detail::get_iterator(buf, out);
}
template <typename OutputIt, typename S, typename... T,
typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
return vformat_to(out, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
}
template <typename Locale, typename S, typename OutputIt, typename... Args,
typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to(
OutputIt out, const Locale& loc, const S& format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args) -> OutputIt {
auto&& buf = detail::get_buffer<Char>(out);
vformat_to(buf, detail::to_string_view(format_str), args,
detail::locale_ref(loc));
return detail::get_iterator(buf, out);
}
template <
typename OutputIt, typename Locale, typename S, typename... T,
typename Char = char_t<S>,
bool enable = detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_locale<Locale>::value&& detail::is_exotic_char<Char>::value>
inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
T&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
return vformat_to(out, loc, detail::to_string_view(format_str),
fmt::make_format_args<buffer_context<Char>>(args...));
}
template <typename OutputIt, typename Char, typename... Args,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to_n(
OutputIt out, size_t n, basic_string_view<Char> format_str,
basic_format_args<buffer_context<type_identity_t<Char>>> args)
-> format_to_n_result<OutputIt> {
using traits = detail::fixed_buffer_traits;
auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);
detail::vformat_to(buf, format_str, args);
return {buf.out(), buf.count()};
}
template <typename OutputIt, typename S, typename... T,
typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
-> format_to_n_result<OutputIt> {
return vformat_to_n(out, n, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
}
template <typename S, typename... T, typename Char = char_t<S>,
FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>
inline auto formatted_size(const S& fmt, T&&... args) -> size_t {
auto buf = detail::counting_buffer<Char>();
detail::vformat_to(buf, detail::to_string_view(fmt),
fmt::make_format_args<buffer_context<Char>>(args...));
return buf.count();
}
inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
auto buf = wmemory_buffer();
detail::vformat_to(buf, fmt, args);
buf.push_back(L'\0');
if (std::fputws(buf.data(), f) == -1)
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
}
inline void vprint(wstring_view fmt, wformat_args args) {
vprint(stdout, fmt, args);
}
template <typename... T>
void print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));
}
template <typename... T> void print(wformat_string<T...> fmt, T&&... args) {
return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));
}
template <typename... T>
void println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {
return print(f, L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
}
template <typename... T> void println(wformat_string<T...> fmt, T&&... args) {
return print(L"{}\n", fmt::format(fmt, std::forward<T>(args)...));
}
/**
Converts *value* to ``std::wstring`` using the default format for type *T*.
*/
template <typename T> inline auto to_wstring(const T& value) -> std::wstring {
return format(FMT_STRING(L"{}"), value);
}
FMT_END_EXPORT
FMT_END_NAMESPACE
#endif // FMT_XCHAR_H_

110
src/fmt.cc Normal file
View File

@ -0,0 +1,110 @@
module;
// Put all implementation-provided headers into the global module fragment
// to prevent attachment to this module.
#include <algorithm>
#include <cerrno>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <exception>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iterator>
#include <limits>
#include <locale>
#include <memory>
#include <optional>
#include <ostream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include <thread>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <variant>
#include <vector>
#include <version>
#if __has_include(<cxxabi.h>)
# include <cxxabi.h>
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
# include <intrin.h>
#endif
#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h>
#endif
#if __has_include(<winapifamily.h>)
# include <winapifamily.h>
#endif
#if (__has_include(<fcntl.h>) || defined(__APPLE__) || \
defined(__linux__)) && \
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/types.h>
# ifndef _WIN32
# include <unistd.h>
# else
# include <io.h>
# endif
#endif
#ifdef _WIN32
# if defined(__GLIBCXX__)
# include <ext/stdio_filebuf.h>
# include <ext/stdio_sync_filebuf.h>
# elif defined(_LIBCPP_VERSION)
# include <__std_stream>
# endif
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
export module fmt;
#define FMT_EXPORT export
#define FMT_BEGIN_EXPORT export {
#define FMT_END_EXPORT }
// If you define FMT_ATTACH_TO_GLOBAL_MODULE
// - all declarations are detached from module 'fmt'
// - the module behaves like a traditional static library, too
// - all library symbols are mangled traditionally
// - you can mix TUs with either importing or #including the {fmt} API
#ifdef FMT_ATTACH_TO_GLOBAL_MODULE
extern "C++" {
#endif
// All library-provided declarations and definitions must be in the module
// purview to be exported.
#include "fmt/args.h"
#include "fmt/chrono.h"
#include "fmt/color.h"
#include "fmt/compile.h"
#include "fmt/format.h"
#include "fmt/os.h"
#include "fmt/printf.h"
#include "fmt/std.h"
#include "fmt/xchar.h"
#ifdef FMT_ATTACH_TO_GLOBAL_MODULE
}
#endif
// gcc doesn't yet implement private module fragments
#if !FMT_GCC_VERSION
module : private;
#endif
#include "format.cc"
#include "os.cc"

43
src/format.cc Normal file
View File

@ -0,0 +1,43 @@
// Formatting library for C++
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/format-inl.h"
FMT_BEGIN_NAMESPACE
namespace detail {
template FMT_API auto dragonbox::to_decimal(float x) noexcept
-> dragonbox::decimal_fp<float>;
template FMT_API auto dragonbox::to_decimal(double x) noexcept
-> dragonbox::decimal_fp<double>;
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template FMT_API locale_ref::locale_ref(const std::locale& loc);
template FMT_API auto locale_ref::get<std::locale>() const -> std::locale;
#endif
// Explicit instantiations for char.
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<char>;
template FMT_API auto decimal_point_impl(locale_ref) -> char;
template FMT_API void buffer<char>::append(const char*, const char*);
template FMT_API void vformat_to(buffer<char>&, string_view,
typename vformat_args<>::type, locale_ref);
// Explicit instantiations for wchar_t.
template FMT_API auto thousands_sep_impl(locale_ref)
-> thousands_sep_result<wchar_t>;
template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
template FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);
} // namespace detail
FMT_END_NAMESPACE

398
src/os.cc Normal file
View File

@ -0,0 +1,398 @@
// Formatting library for C++ - optional OS-specific functionality
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
// Disable bogus MSVC warnings.
#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "fmt/os.h"
#include <climits>
#if FMT_USE_FCNTL
# include <sys/stat.h>
# include <sys/types.h>
# ifdef _WRS_KERNEL // VxWorks7 kernel
# include <ioLib.h> // getpagesize
# endif
# ifndef _WIN32
# include <unistd.h>
# else
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <io.h>
# ifndef S_IRUSR
# define S_IRUSR _S_IREAD
# endif
# ifndef S_IWUSR
# define S_IWUSR _S_IWRITE
# endif
# ifndef S_IRGRP
# define S_IRGRP 0
# endif
# ifndef S_IWGRP
# define S_IWGRP 0
# endif
# ifndef S_IROTH
# define S_IROTH 0
# endif
# ifndef S_IWOTH
# define S_IWOTH 0
# endif
# endif // _WIN32
#endif // FMT_USE_FCNTL
#ifdef _WIN32
# include <windows.h>
#endif
namespace {
#ifdef _WIN32
// Return type of read and write functions.
using rwresult = int;
// On Windows the count argument to read and write is unsigned, so convert
// it from size_t preventing integer overflow.
inline unsigned convert_rwcount(std::size_t count) {
return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;
}
#elif FMT_USE_FCNTL
// Return type of read and write functions.
using rwresult = ssize_t;
inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif
} // namespace
FMT_BEGIN_NAMESPACE
#ifdef _WIN32
namespace detail {
class system_message {
system_message(const system_message&) = delete;
void operator=(const system_message&) = delete;
unsigned long result_;
wchar_t* message_;
static bool is_whitespace(wchar_t c) noexcept {
return c == L' ' || c == L'\n' || c == L'\r' || c == L'\t' || c == L'\0';
}
public:
explicit system_message(unsigned long error_code)
: result_(0), message_(nullptr) {
result_ = FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<wchar_t*>(&message_), 0, nullptr);
if (result_ != 0) {
while (result_ != 0 && is_whitespace(message_[result_ - 1])) {
--result_;
}
}
}
~system_message() { LocalFree(message_); }
explicit operator bool() const noexcept { return result_ != 0; }
operator basic_string_view<wchar_t>() const noexcept {
return basic_string_view<wchar_t>(message_, result_);
}
};
class utf8_system_category final : public std::error_category {
public:
const char* name() const noexcept override { return "system"; }
std::string message(int error_code) const override {
auto&& msg = system_message(error_code);
if (msg) {
auto utf8_message = to_utf8<wchar_t>();
if (utf8_message.convert(msg)) {
return utf8_message.str();
}
}
return "unknown error";
}
};
} // namespace detail
FMT_API const std::error_category& system_category() noexcept {
static const detail::utf8_system_category category;
return category;
}
std::system_error vwindows_error(int err_code, string_view format_str,
format_args args) {
auto ec = std::error_code(err_code, system_category());
return std::system_error(ec, vformat(format_str, args));
}
void detail::format_windows_error(detail::buffer<char>& out, int error_code,
const char* message) noexcept {
FMT_TRY {
auto&& msg = system_message(error_code);
if (msg) {
auto utf8_message = to_utf8<wchar_t>();
if (utf8_message.convert(msg)) {
fmt::format_to(appender(out), FMT_STRING("{}: {}"), message,
string_view(utf8_message));
return;
}
}
}
FMT_CATCH(...) {}
format_error_code(out, error_code, message);
}
void report_windows_error(int error_code, const char* message) noexcept {
report_error(detail::format_windows_error, error_code, message);
}
#endif // _WIN32
buffered_file::~buffered_file() noexcept {
if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
report_system_error(errno, "cannot close file");
}
buffered_file::buffered_file(cstring_view filename, cstring_view mode) {
FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),
nullptr);
if (!file_)
FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"),
filename.c_str()));
}
void buffered_file::close() {
if (!file_) return;
int result = FMT_SYSTEM(fclose(file_));
file_ = nullptr;
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
}
int buffered_file::descriptor() const {
#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
int fd = fileno(file_);
#else
int fd = FMT_POSIX_CALL(fileno(file_));
#endif
if (fd == -1)
FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
return fd;
}
#if FMT_USE_FCNTL
# ifdef _WIN32
using mode_t = int;
# endif
constexpr mode_t default_open_mode =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
file::file(cstring_view path, int oflag) {
# if defined(_WIN32) && !defined(__MINGW32__)
fd_ = -1;
auto converted = detail::utf8_to_utf16(string_view(path.c_str()));
*this = file::open_windows_file(converted.c_str(), oflag);
# else
FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode)));
if (fd_ == -1)
FMT_THROW(
system_error(errno, FMT_STRING("cannot open file {}"), path.c_str()));
# endif
}
file::~file() noexcept {
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
report_system_error(errno, "cannot close file");
}
void file::close() {
if (fd_ == -1) return;
// Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
int result = FMT_POSIX_CALL(close(fd_));
fd_ = -1;
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot close file")));
}
long long file::size() const {
# ifdef _WIN32
// Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT
// is less than 0x0500 as is the case with some default MinGW builds.
// Both functions support large file sizes.
DWORD size_upper = 0;
HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));
DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));
if (size_lower == INVALID_FILE_SIZE) {
DWORD error = GetLastError();
if (error != NO_ERROR)
FMT_THROW(windows_error(GetLastError(), "cannot get file size"));
}
unsigned long long long_size = size_upper;
return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;
# else
using Stat = struct stat;
Stat file_stat = Stat();
if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)
FMT_THROW(system_error(errno, FMT_STRING("cannot get file attributes")));
static_assert(sizeof(long long) >= sizeof(file_stat.st_size),
"return type of file::size is not large enough");
return file_stat.st_size;
# endif
}
std::size_t file::read(void* buffer, std::size_t count) {
rwresult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));
if (result < 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot read from file")));
return detail::to_unsigned(result);
}
std::size_t file::write(const void* buffer, std::size_t count) {
rwresult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
if (result < 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
return detail::to_unsigned(result);
}
file file::dup(int fd) {
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
int new_fd = FMT_POSIX_CALL(dup(fd));
if (new_fd == -1)
FMT_THROW(system_error(
errno, FMT_STRING("cannot duplicate file descriptor {}"), fd));
return file(new_fd);
}
void file::dup2(int fd) {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) {
FMT_THROW(system_error(
errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_,
fd));
}
}
void file::dup2(int fd, std::error_code& ec) noexcept {
int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) ec = std::error_code(errno, std::generic_category());
}
void file::pipe(file& read_end, file& write_end) {
// Close the descriptors first to make sure that assignments don't throw
// and there are no leaks.
read_end.close();
write_end.close();
int fds[2] = {};
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
int result = FMT_POSIX_CALL(pipe(fds));
# endif
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
// The following assignments don't throw because read_fd and write_fd
// are closed.
read_end = file(fds[0]);
write_end = file(fds[1]);
}
buffered_file file::fdopen(const char* mode) {
// Don't retry as fdopen doesn't return EINTR.
# if defined(__MINGW32__) && defined(_POSIX_)
FILE* f = ::fdopen(fd_, mode);
# else
FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));
# endif
if (!f) {
FMT_THROW(system_error(
errno, FMT_STRING("cannot associate stream with file descriptor")));
}
buffered_file bf(f);
fd_ = -1;
return bf;
}
# if defined(_WIN32) && !defined(__MINGW32__)
file file::open_windows_file(wcstring_view path, int oflag) {
int fd = -1;
auto err = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO, default_open_mode);
if (fd == -1) {
FMT_THROW(system_error(err, FMT_STRING("cannot open file {}"),
detail::to_utf8<wchar_t>(path.c_str()).c_str()));
}
return file(fd);
}
# endif
# if !defined(__MSDOS__)
long getpagesize() {
# ifdef _WIN32
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
# else
# ifdef _WRS_KERNEL
long size = FMT_POSIX_CALL(getpagesize());
# else
long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));
# endif
if (size < 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot get memory page size")));
return size;
# endif
}
# endif
namespace detail {
void file_buffer::grow(size_t) {
if (this->size() == this->capacity()) flush();
}
file_buffer::file_buffer(cstring_view path,
const detail::ostream_params& params)
: file_(path, params.oflag) {
set(new char[params.buffer_size], params.buffer_size);
}
file_buffer::file_buffer(file_buffer&& other)
: detail::buffer<char>(other.data(), other.size(), other.capacity()),
file_(std::move(other.file_)) {
other.clear();
other.set(nullptr, 0);
}
file_buffer::~file_buffer() {
flush();
delete[] data();
}
} // namespace detail
ostream::~ostream() = default;
#endif // FMT_USE_FCNTL
FMT_END_NAMESPACE

View File

@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := fmt_static
LOCAL_MODULE_FILENAME := libfmt
LOCAL_SRC_FILES := fmt/format.cc
LOCAL_SRC_FILES := ../src/format.cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)

View File

@ -0,0 +1 @@
<manifest package="net.fmtlib" />

2061
support/C++.sublime-syntax Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,5 +2,3 @@ This directory contains build support files such as
* CMake modules
* Build scripts
* qmake (static build with dynamic libc only)

20
support/Vagrantfile vendored Normal file
View File

@ -0,0 +1,20 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
# A vagrant config for testing against gcc-4.8.
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.disksize.size = '15GB'
config.vm.provider "virtualbox" do |vb|
vb.memory = "4096"
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y g++ make wget git
wget -q https://github.com/Kitware/CMake/releases/download/v3.26.0/cmake-3.26.0-Linux-x86_64.tar.gz
tar xzf cmake-3.26.0-Linux-x86_64.tar.gz
ln -s `pwd`/cmake-3.26.0-Linux-x86_64/bin/cmake /usr/local/bin
SHELL
end

View File

@ -1,33 +0,0 @@
#!/usr/bin/env python
# Build the project on AppVeyor.
import os
from subprocess import check_call
build = os.environ['BUILD']
config = os.environ['CONFIGURATION']
platform = os.environ.get('PLATFORM')
path = os.environ['PATH']
cmake_command = ['cmake', '-DFMT_PEDANTIC=ON', '-DCMAKE_BUILD_TYPE=' + config]
if build == 'mingw':
cmake_command.append('-GMinGW Makefiles')
build_command = ['mingw32-make', '-j4']
test_command = ['mingw32-make', 'test']
# Remove the path to Git bin directory from $PATH because it breaks
# MinGW config.
path = path.replace(r'C:\Program Files (x86)\Git\bin', '')
os.environ['PATH'] = r'C:\MinGW\bin;' + path
else:
# 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\14.0\Bin;' + path
generator = 'Visual Studio 14 2015'
if platform == 'x64':
generator += ' Win64'
cmake_command.append('-G' + generator)
build_command = ['cmake', '--build', '.', '--config', config, '--', '/m:4']
test_command = ['ctest', '-C', config]
check_call(cmake_command)
check_call(build_command)
check_call(test_command)

View File

@ -1,26 +0,0 @@
configuration:
- Debug
- Release
environment:
CTEST_OUTPUT_ON_FAILURE: 1
matrix:
- BUILD: msvc
- BUILD: msvc
PLATFORM: x64
- BUILD: mingw
before_build:
# Workaround for CMake not wanting sh.exe on PATH for MinGW.
- set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
build_script:
- python support/appveyor-build.py
on_failure:
- appveyor PushArtifact Testing/Temporary/LastTest.log
- appveyor AddTest test
# Uncomment this to debug AppVeyor failures.
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

View File

@ -0,0 +1 @@
6.1.2

28
support/bazel/BUILD.bazel Normal file
View File

@ -0,0 +1,28 @@
cc_library(
name = "fmt",
srcs = [
#"src/fmt.cc", # No C++ module support
"src/format.cc",
"src/os.cc",
],
hdrs = [
"include/fmt/args.h",
"include/fmt/chrono.h",
"include/fmt/color.h",
"include/fmt/compile.h",
"include/fmt/core.h",
"include/fmt/format.h",
"include/fmt/format-inl.h",
"include/fmt/os.h",
"include/fmt/ostream.h",
"include/fmt/printf.h",
"include/fmt/ranges.h",
"include/fmt/std.h",
"include/fmt/xchar.h",
],
includes = [
"include",
],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)

74
support/bazel/README.md Normal file
View File

@ -0,0 +1,74 @@
# Bazel support
To get [Bazel](https://bazel.build/) working with {fmt} you can copy the files `BUILD.bazel`, `WORKSPACE.bazel`, and `.bazelversion` from this folder (`support/bazel`) to the root folder of this project. This way {fmt} gets bazelized and can be used with Bazel (e.g. doing a `bazel build //...` on {fmt}).
## Using {fmt} as a dependency
The following minimal example shows how to use {fmt} as a dependency within a Bazel project.
The following file structure is assumed:
```
example
├── BUILD.bazel
├── main.cpp
└── WORKSPACE.bazel
```
*main.cpp*:
```c++
#include "fmt/core.h"
int main() {
fmt::print("The answer is {}\n", 42);
}
```
The expected output of this example is `The answer is 42`.
*WORKSPACE.bazel*:
```python
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "fmt",
branch = "master",
remote = "https://github.com/fmtlib/fmt",
patch_cmds = [
"mv support/bazel/.bazelversion .bazelversion",
"mv support/bazel/BUILD.bazel BUILD.bazel",
"mv support/bazel/WORKSPACE.bazel WORKSPACE.bazel",
],
# Windows-related patch commands are only needed in the case MSYS2 is not installed.
# More details about the installation process of MSYS2 on Windows systems can be found here:
# https://docs.bazel.build/versions/main/install-windows.html#installing-compilers-and-language-runtimes
# Even if MSYS2 is installed the Windows related patch commands can still be used.
patch_cmds_win = [
"Move-Item -Path support/bazel/.bazelversion -Destination .bazelversion",
"Move-Item -Path support/bazel/BUILD.bazel -Destination BUILD.bazel",
"Move-Item -Path support/bazel/WORKSPACE.bazel -Destination WORKSPACE.bazel",
],
)
```
In the *WORKSPACE* file, the {fmt} GitHub repository is fetched. Using the attribute `patch_cmds` the files `BUILD.bazel`, `WORKSPACE.bazel`, and `.bazelversion` are moved to the root of the {fmt} repository. This way the {fmt} repository is recognized as a bazelized workspace.
*BUILD.bazel*:
```python
cc_binary(
name = "Demo",
srcs = ["main.cpp"],
deps = ["@fmt"],
)
```
The *BUILD* file defines a binary named `Demo` that has a dependency to {fmt}.
To execute the binary you can run `bazel run //:Demo`.
# Using Bzlmod
The [Bazel Central Registry](https://github.com/bazelbuild/bazel-central-registry/tree/main/modules/fmt) also provides support for {fmt}.

View File

@ -0,0 +1 @@
workspace(name = "fmt")

58
support/build-docs.py Executable file
View File

@ -0,0 +1,58 @@
#!/usr/bin/env python
# Build the documentation in CI.
from __future__ import print_function
import errno, os, shutil, subprocess, sys, urllib
from subprocess import call, check_call, Popen, PIPE, STDOUT
def rmtree_if_exists(dir):
try:
shutil.rmtree(dir)
except OSError as e:
if e.errno == errno.ENOENT:
pass
# Build the docs.
fmt_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.insert(0, os.path.join(fmt_dir, 'doc'))
import build
build.create_build_env()
html_dir = build.build_docs()
repo = 'fmtlib.github.io'
branch = os.environ['GITHUB_REF']
is_ci = 'CI' in os.environ
if is_ci and branch != 'refs/heads/master':
print('Branch: ' + branch)
exit(0) # Ignore non-master branches
if is_ci and 'KEY' not in os.environ:
# Don't update the repo if building in CI from an account that doesn't have
# push access.
print('Skipping update of ' + repo)
exit(0)
# Clone the fmtlib.github.io repo.
rmtree_if_exists(repo)
git_url = 'https://github.com/' if is_ci else 'git@github.com:'
check_call(['git', 'clone', git_url + 'fmtlib/{}.git'.format(repo)])
# Copy docs to the repo.
target_dir = os.path.join(repo, 'dev')
rmtree_if_exists(target_dir)
shutil.copytree(html_dir, target_dir, ignore=shutil.ignore_patterns('.*'))
if is_ci:
check_call(['git', 'config', '--global', 'user.name', 'fmtbot'])
check_call(['git', 'config', '--global', 'user.email', 'viz@fmt.dev'])
# Push docs to GitHub pages.
check_call(['git', 'add', '--all'], cwd=repo)
if call(['git', 'diff-index', '--quiet', 'HEAD'], cwd=repo):
check_call(['git', 'commit', '-m', 'Update documentation'], cwd=repo)
cmd = 'git push'
if is_ci:
cmd += ' https://$KEY@github.com/fmtlib/fmtlib.github.io.git master'
p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=repo)
# Print the output without the key.
print(p.communicate()[0].decode('utf-8').replace(os.environ['KEY'], '$KEY'))
if p.returncode != 0:
raise subprocess.CalledProcessError(p.returncode, cmd)

132
support/build.gradle Normal file
View File

@ -0,0 +1,132 @@
import java.nio.file.Paths
// General gradle arguments for root project
buildscript {
repositories {
google()
jcenter()
}
dependencies {
//
// https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
//
// Notice that 4.0.0 here is the version of [Android Gradle Plugin]
// According to URL above you will need Gradle 6.1 or higher
//
classpath "com.android.tools.build:gradle:4.1.1"
}
}
repositories {
google()
jcenter()
}
// Project's root where CMakeLists.txt exists: rootDir/support/.cxx -> rootDir
def rootDir = Paths.get(project.buildDir.getParent()).getParent()
println("rootDir: ${rootDir}")
// Output: Shared library (.so) for Android
apply plugin: "com.android.library"
android {
compileSdkVersion 25 // Android 7.0
// Target ABI
// - This option controls target platform of module
// - The platform might be limited by compiler's support
// some can work with Clang(default), but some can work only with GCC...
// if bad, both toolchains might not support it
splits {
abi {
enable true
// Specify platforms for Application
reset()
include "arm64-v8a", "armeabi-v7a", "x86_64"
}
}
ndkVersion "21.3.6528147" // ANDROID_NDK_HOME is deprecated. Be explicit
defaultConfig {
minSdkVersion 21 // Android 5.0+
targetSdkVersion 25 // Follow Compile SDK
versionCode 34 // Follow release count
versionName "7.1.2" // Follow Official version
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared" // Specify Android STL
arguments "-DBUILD_SHARED_LIBS=true" // Build shared object
arguments "-DFMT_TEST=false" // Skip test
arguments "-DFMT_DOC=false" // Skip document
cppFlags "-std=c++17"
targets "fmt"
}
}
println(externalNativeBuild.cmake.cppFlags)
println(externalNativeBuild.cmake.arguments)
}
// External Native build
// - Use existing CMakeList.txt
// - Give path to CMake. This gradle file should be
// neighbor of the top level cmake
externalNativeBuild {
cmake {
version "3.10.0+"
path "${rootDir}/CMakeLists.txt"
// buildStagingDirectory "./build" // Custom path for cmake output
}
}
sourceSets{
// Android Manifest for Gradle
main {
manifest.srcFile "AndroidManifest.xml"
}
}
// https://developer.android.com/studio/build/native-dependencies#build_system_configuration
buildFeatures {
prefab true
prefabPublishing true
}
prefab {
fmt {
headers "${rootDir}/include"
}
}
}
assemble.doLast
{
// Instead of `ninja install`, Gradle will deploy the files.
// We are doing this since FMT is dependent to the ANDROID_STL after build
copy {
from "build/intermediates/cmake"
into "${rootDir}/libs"
}
// Copy debug binaries
copy {
from "${rootDir}/libs/debug/obj"
into "${rootDir}/libs/debug"
}
// Copy Release binaries
copy {
from "${rootDir}/libs/release/obj"
into "${rootDir}/libs/release"
}
// Remove empty directory
delete "${rootDir}/libs/debug/obj"
delete "${rootDir}/libs/release/obj"
// Copy AAR files. Notice that the aar is named after the folder of this script.
copy {
from "build/outputs/aar/support-release.aar"
into "${rootDir}/libs"
rename "support-release.aar", "fmt-release.aar"
}
copy {
from "build/outputs/aar/support-debug.aar"
into "${rootDir}/libs"
rename "support-debug.aar", "fmt-debug.aar"
}
}

View File

@ -0,0 +1,26 @@
# This module provides function for joining paths
# known from from most languages
#
# Original license:
# SPDX-License-Identifier: (MIT OR CC0-1.0)
# Explicit permission given to distribute this module under
# the terms of the project as described in /LICENSE.rst.
# Copyright 2020 Jan Tojnar
# https://github.com/jtojnar/cmake-snips
#
# Modelled after Pythons os.path.join
# https://docs.python.org/3.7/library/os.path.html#os.path.join
# Windows not supported
function(join_paths joined_path first_path_segment)
set(temp_path "${first_path_segment}")
foreach(current_segment IN LISTS ARGN)
if(NOT ("${current_segment}" STREQUAL ""))
if(IS_ABSOLUTE "${current_segment}")
set(temp_path "${current_segment}")
else()
set(temp_path "${temp_path}/${current_segment}")
endif()
endif()
endforeach()
set(${joined_path} "${temp_path}" PARENT_SCOPE)
endfunction()

View File

@ -1,85 +0,0 @@
# C++11 feature support detection
if (NOT FMT_USE_CPP11)
return()
endif ()
include(CheckCXXCompilerFlag)
if (FMT_USE_CPP11)
check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
# Check if including cmath works with -std=c++11 and -O3.
# It may not in MinGW due to bug http://ehc.ac/p/mingw/bugs/2250/.
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -O3")
check_cxx_source_compiles("
#include <cmath>
int main() {}" FMT_CPP11_CMATH)
# Check if including <unistd.h> works with -std=c++11.
# It may not in MinGW due to bug http://sourceforge.net/p/mingw/bugs/2024/.
check_cxx_source_compiles("
#include <unistd.h>
int main() {}" FMT_CPP11_UNISTD_H)
# Check if snprintf works with -std=c++11. It may not in MinGW.
check_cxx_source_compiles("
#include <stdio.h>
int main() {
char buffer[10];
snprintf(buffer, 10, \"foo\");
}" FMT_CPP11_SNPRINTF)
if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H AND FMT_CPP11_SNPRINTF)
set(CPP11_FLAG -std=c++11)
else ()
check_cxx_compiler_flag(-std=gnu++11 HAVE_STD_GNUPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
set(CPP11_FLAG -std=gnu++11)
endif ()
endif ()
set(CMAKE_REQUIRED_FLAGS )
else ()
check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG)
if (HAVE_STD_CPP0X_FLAG)
set(CPP11_FLAG -std=c++0x)
endif ()
endif ()
endif ()
if (CMAKE_CXX_STANDARD)
# Don't use -std compiler flag if CMAKE_CXX_STANDARD is specified.
set(CPP11_FLAG )
endif ()
set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG})
# Check if variadic templates are working and not affected by GCC bug 39653:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39653
check_cxx_source_compiles("
template <class T, class ...Types>
struct S { typedef typename S<Types...>::type type; };
int main() {}" SUPPORTS_VARIADIC_TEMPLATES)
# Check if initializer lists are supported.
check_cxx_source_compiles("
#include <initializer_list>
int main() {}" SUPPORTS_INITIALIZER_LIST)
# Check if enum bases are available
check_cxx_source_compiles("
enum C : char {A};
int main() {}"
SUPPORTS_ENUM_BASE)
# Check if type traits are available
check_cxx_source_compiles("
#include <type_traits>
class C { void operator=(const C&); };
int main() { static_assert(!std::is_copy_assignable<C>::value, \"\"); }"
SUPPORTS_TYPE_TRAITS)
# Check if user-defined literals are available
check_cxx_source_compiles("
void operator\"\" _udl(long double);
int main() {}"
SUPPORTS_USER_DEFINED_LITERALS)
set(CMAKE_REQUIRED_FLAGS )

View File

@ -1,4 +1,7 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
if (NOT TARGET fmt::fmt)
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
endif ()
check_required_components(fmt)

11
support/cmake/fmt.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@libdir_for_pc_file@
includedir=@includedir_for_pc_file@
Name: fmt
Description: A modern formatting library
Version: @FMT_VERSION@
Libs: -L${libdir} -l@FMT_LIB_NAME@
Cflags: -I${includedir}

View File

@ -1,11 +0,0 @@
@echo on
rem This scripts configures build environment and runs CMake.
rem Use it instead of running CMake directly when building with
rem the Microsoft SDK toolchain rather than Visual Studio.
rem It is used in the same way as cmake, for example:
rem
rem run-cmake -G "Visual Studio 10 Win64" .
for /F "delims=" %%i IN ('cmake "-DPRINT_PATH=1" -P %~dp0/FindSetEnv.cmake') DO set setenv=%%i
if NOT "%setenv%" == "" call "%setenv%"
cmake %*

53
support/compute-powers.py Executable file
View File

@ -0,0 +1,53 @@
#!/usr/bin/env python
# Compute 10 ** exp with exp in the range [min_exponent, max_exponent] and print
# normalized (with most-significant bit equal to 1) significands in hexadecimal.
from __future__ import print_function
min_exponent = -348
max_exponent = 340
step = 8
significand_size = 64
exp_offset = 2000
class fp:
pass
powers = []
for i, exp in enumerate(range(min_exponent, max_exponent + 1, step)):
result = fp()
n = 10 ** exp if exp >= 0 else 2 ** exp_offset / 10 ** -exp
k = significand_size + 1
# Convert to binary and round.
binary = '{:b}'.format(n)
result.f = (int('{:0<{}}'.format(binary[:k], k), 2) + 1) / 2
result.e = len(binary) - (exp_offset if exp < 0 else 0) - significand_size
powers.append(result)
# Sanity check.
exp_offset10 = 400
actual = result.f * 10 ** exp_offset10
if result.e > 0:
actual *= 2 ** result.e
else:
for j in range(-result.e):
actual /= 2
expected = 10 ** (exp_offset10 + exp)
precision = len('{}'.format(expected)) - len('{}'.format(actual - expected))
if precision < 19:
print('low precision:', precision)
exit(1)
print('Significands:', end='')
for i, fp in enumerate(powers):
if i % 3 == 0:
print(end='\n ')
print(' {:0<#16x}'.format(fp.f, ), end=',')
print('\n\nExponents:', end='')
for i, fp in enumerate(powers):
if i % 11 == 0:
print(end='\n ')
print(' {:5}'.format(fp.e), end=',')
print('\n\nMax exponent difference:',
max([x.e - powers[i - 1].e for i, x in enumerate(powers)][1:]))

View File

@ -1,29 +0,0 @@
# Staticlib configuration for qmake builds
# For some reason qmake 3.1 fails to identify source dependencies and excludes format.cc and printf.cc
# from compilation so it _MUST_ be called as qmake -nodepend
# A workaround is implemented below: a custom compiler is defined which does not track dependencies
TEMPLATE = lib
TARGET = fmt
QMAKE_EXT_CPP = .cc
CONFIG = staticlib warn_on c++11
FMT_SOURCES = \
../fmt/format.cc \
../fmt/ostream.cc \
../fmt/posix.cc \
../fmt/printf.cc
fmt.name = libfmt
fmt.input = FMT_SOURCES
fmt.output = ${QMAKE_FILE_BASE}$$QMAKE_EXT_OBJ
fmt.clean = ${QMAKE_FILE_BASE}$$QMAKE_EXT_OBJ
fmt.depends = ${QMAKE_FILE_IN}
# QMAKE_RUN_CXX will not be expanded
fmt.commands = $$QMAKE_CXX -c $$QMAKE_CXXFLAGS $$QMAKE_CXXFLAGS_WARN_ON $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO $$QMAKE_CXXFLAGS_CXX11 ${QMAKE_FILE_IN}
fmt.variable_out = OBJECTS
fmt.CONFIG = no_dependencies no_link
QMAKE_EXTRA_COMPILERS += fmt

View File

@ -1,10 +1,13 @@
#!/usr/bin/env python
#!/usr/bin/env python3
"""Manage site and releases.
Usage:
manage.py release [<branch>]
manage.py site
For the release command $FMT_TOKEN should contain a GitHub personal access token
obtained from https://github.com/settings/tokens.
"""
from __future__ import print_function
@ -134,25 +137,66 @@ def update_site(env):
if not os.path.exists(contents):
os.rename(os.path.join(target_doc_dir, 'index.rst'), contents)
# Fix issues in reference.rst/api.rst.
for filename in ['reference.rst', 'api.rst']:
for filename in ['reference.rst', 'api.rst', 'index.rst']:
pattern = re.compile('doxygenfunction.. (bin|oct|hexu|hex)$', re.M)
with rewrite(os.path.join(target_doc_dir, filename)) as b:
b.data = b.data.replace('std::ostream &', 'std::ostream&')
b.data = re.sub(pattern, r'doxygenfunction:: \1(int)', b.data)
b.data = b.data.replace('std::FILE*', 'std::FILE *')
b.data = b.data.replace('unsigned int', 'unsigned')
b.data = b.data.replace('operator""_', 'operator"" _')
#b.data = b.data.replace('operator""_', 'operator"" _')
b.data = b.data.replace(
'format_to_n(OutputIt, size_t, string_view, Args&&',
'format_to_n(OutputIt, size_t, const S&, const Args&')
b.data = b.data.replace(
'format_to_n(OutputIt, std::size_t, string_view, Args&&',
'format_to_n(OutputIt, std::size_t, const S&, const Args&')
if version == ('3.0.2'):
b.data = b.data.replace(
'fprintf(std::ostream&', 'fprintf(std::ostream &')
if version == ('5.3.0'):
b.data = b.data.replace(
'format_to(OutputIt, const S&, const Args&...)',
'format_to(OutputIt, const S &, const Args &...)')
if version.startswith('5.') or version.startswith('6.'):
b.data = b.data.replace(', size_t', ', std::size_t')
if version.startswith('7.'):
b.data = b.data.replace(', std::size_t', ', size_t')
b.data = b.data.replace('join(It, It', 'join(It, Sentinel')
if version.startswith('7.1.'):
b.data = b.data.replace(', std::size_t', ', size_t')
b.data = b.data.replace('join(It, It', 'join(It, Sentinel')
b.data = b.data.replace(
'fmt::format_to(OutputIt, const S&, Args&&...)',
'fmt::format_to(OutputIt, const S&, Args&&...) -> ' +
'typename std::enable_if<enable, OutputIt>::type')
b.data = b.data.replace('aa long', 'a long')
b.data = b.data.replace('serveral', 'several')
if version.startswith('6.2.'):
b.data = b.data.replace(
'vformat(const S&, basic_format_args<' +
'buffer_context<Char>>)',
'vformat(const S&, basic_format_args<' +
'buffer_context<type_identity_t<Char>>>)')
# Fix a broken link in index.rst.
index = os.path.join(target_doc_dir, 'index.rst')
with rewrite(index) as b:
b.data = b.data.replace(
'doc/latest/index.html#format-string-syntax', 'syntax.html')
# Fix issues in syntax.rst.
index = os.path.join(target_doc_dir, 'syntax.rst')
with rewrite(index) as b:
b.data = b.data.replace(
'..productionlist:: sf\n', '.. productionlist:: sf\n ')
b.data = b.data.replace('Examples:\n', 'Examples::\n')
# Build the docs.
html_dir = os.path.join(env.build_dir, 'html')
if os.path.exists(html_dir):
shutil.rmtree(html_dir)
include_dir = env.fmt_repo.dir
if LooseVersion(version) >= LooseVersion('3.0.0'):
if LooseVersion(version) >= LooseVersion('5.0.0'):
include_dir = os.path.join(include_dir, 'include', 'fmt')
elif LooseVersion(version) >= LooseVersion('3.0.0'):
include_dir = os.path.join(include_dir, 'fmt')
import build
build.build_docs(version, doc_dir=target_doc_dir,
@ -202,7 +246,7 @@ def release(args):
# Update the version in the changelog.
title_len = 0
for line in fileinput.input(changelog_path, inplace=True):
if line.decode('utf-8').startswith(version + ' - TBD'):
if line.startswith(version + ' - TBD'):
line = version + ' - ' + datetime.date.today().isoformat()
title_len = len(line)
line += '\n'
@ -232,9 +276,9 @@ def release(args):
# Create a release on GitHub.
fmt_repo.push('origin', 'release')
params = {'access_token': os.getenv('FMT_TOKEN')}
auth_headers = {'Authorization': 'token ' + os.getenv('FMT_TOKEN')}
r = requests.post('https://api.github.com/repos/fmtlib/fmt/releases',
params=params,
headers=auth_headers,
data=json.dumps({'tag_name': version,
'target_commitish': 'release',
'body': changes, 'draft': True}))
@ -243,12 +287,12 @@ def release(args):
id = r.json()['id']
uploads_url = 'https://uploads.github.com/repos/fmtlib/fmt/releases'
package = 'fmt-{}.zip'.format(version)
with open('build/fmt/' + package, 'rb') as f:
r = requests.post(
'{}/{}/assets?name={}'.format(uploads_url, id, package),
params=params, files={package: f})
if r.status_code != 201:
raise Exception('Failed to upload an asset ' + str(r))
r = requests.post(
'{}/{}/assets?name={}'.format(uploads_url, id, package),
headers={'Content-Type': 'application/zip'} | auth_headers,
data=open('build/fmt/' + package, 'rb'))
if r.status_code != 201:
raise Exception('Failed to upload an asset ' + str(r))
if __name__ == '__main__':

201
support/printable.py Executable file
View File

@ -0,0 +1,201 @@
#!/usr/bin/env python3
# This script is based on
# https://github.com/rust-lang/rust/blob/master/library/core/src/unicode/printable.py
# distributed under https://github.com/rust-lang/rust/blob/master/LICENSE-MIT.
# This script uses the following Unicode tables:
# - UnicodeData.txt
from collections import namedtuple
import csv
import os
import subprocess
NUM_CODEPOINTS=0x110000
def to_ranges(iter):
current = None
for i in iter:
if current is None or i != current[1] or i in (0x10000, 0x20000):
if current is not None:
yield tuple(current)
current = [i, i + 1]
else:
current[1] += 1
if current is not None:
yield tuple(current)
def get_escaped(codepoints):
for c in codepoints:
if (c.class_ or "Cn") in "Cc Cf Cs Co Cn Zl Zp Zs".split() and c.value != ord(' '):
yield c.value
def get_file(f):
try:
return open(os.path.basename(f))
except FileNotFoundError:
subprocess.run(["curl", "-O", f], check=True)
return open(os.path.basename(f))
Codepoint = namedtuple('Codepoint', 'value class_')
def get_codepoints(f):
r = csv.reader(f, delimiter=";")
prev_codepoint = 0
class_first = None
for row in r:
codepoint = int(row[0], 16)
name = row[1]
class_ = row[2]
if class_first is not None:
if not name.endswith("Last>"):
raise ValueError("Missing Last after First")
for c in range(prev_codepoint + 1, codepoint):
yield Codepoint(c, class_first)
class_first = None
if name.endswith("First>"):
class_first = class_
yield Codepoint(codepoint, class_)
prev_codepoint = codepoint
if class_first is not None:
raise ValueError("Missing Last after First")
for c in range(prev_codepoint + 1, NUM_CODEPOINTS):
yield Codepoint(c, None)
def compress_singletons(singletons):
uppers = [] # (upper, # items in lowers)
lowers = []
for i in singletons:
upper = i >> 8
lower = i & 0xff
if len(uppers) == 0 or uppers[-1][0] != upper:
uppers.append((upper, 1))
else:
upper, count = uppers[-1]
uppers[-1] = upper, count + 1
lowers.append(lower)
return uppers, lowers
def compress_normal(normal):
# lengths 0x00..0x7f are encoded as 00, 01, ..., 7e, 7f
# lengths 0x80..0x7fff are encoded as 80 80, 80 81, ..., ff fe, ff ff
compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)]
prev_start = 0
for start, count in normal:
truelen = start - prev_start
falselen = count
prev_start = start + count
assert truelen < 0x8000 and falselen < 0x8000
entry = []
if truelen > 0x7f:
entry.append(0x80 | (truelen >> 8))
entry.append(truelen & 0xff)
else:
entry.append(truelen & 0x7f)
if falselen > 0x7f:
entry.append(0x80 | (falselen >> 8))
entry.append(falselen & 0xff)
else:
entry.append(falselen & 0x7f)
compressed.append(entry)
return compressed
def print_singletons(uppers, lowers, uppersname, lowersname):
print(" static constexpr singleton {}[] = {{".format(uppersname))
for u, c in uppers:
print(" {{{:#04x}, {}}},".format(u, c))
print(" };")
print(" static constexpr unsigned char {}[] = {{".format(lowersname))
for i in range(0, len(lowers), 8):
print(" {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
print(" };")
def print_normal(normal, normalname):
print(" static constexpr unsigned char {}[] = {{".format(normalname))
for v in normal:
print(" {}".format(" ".join("{:#04x},".format(i) for i in v)))
print(" };")
def main():
file = get_file("https://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
codepoints = get_codepoints(file)
CUTOFF=0x10000
singletons0 = []
singletons1 = []
normal0 = []
normal1 = []
extra = []
for a, b in to_ranges(get_escaped(codepoints)):
if a > 2 * CUTOFF:
extra.append((a, b - a))
elif a == b - 1:
if a & CUTOFF:
singletons1.append(a & ~CUTOFF)
else:
singletons0.append(a)
elif a == b - 2:
if a & CUTOFF:
singletons1.append(a & ~CUTOFF)
singletons1.append((a + 1) & ~CUTOFF)
else:
singletons0.append(a)
singletons0.append(a + 1)
else:
if a >= 2 * CUTOFF:
extra.append((a, b - a))
elif a & CUTOFF:
normal1.append((a & ~CUTOFF, b - a))
else:
normal0.append((a, b - a))
singletons0u, singletons0l = compress_singletons(singletons0)
singletons1u, singletons1l = compress_singletons(singletons1)
normal0 = compress_normal(normal0)
normal1 = compress_normal(normal1)
print("""\
FMT_FUNC auto is_printable(uint32_t cp) -> bool {\
""")
print_singletons(singletons0u, singletons0l, 'singletons0', 'singletons0_lower')
print_singletons(singletons1u, singletons1l, 'singletons1', 'singletons1_lower')
print_normal(normal0, 'normal0')
print_normal(normal1, 'normal1')
print("""\
auto lower = static_cast<uint16_t>(cp);
if (cp < 0x10000) {
return is_printable(lower, singletons0,
sizeof(singletons0) / sizeof(*singletons0),
singletons0_lower, normal0, sizeof(normal0));
}
if (cp < 0x20000) {
return is_printable(lower, singletons1,
sizeof(singletons1) / sizeof(*singletons1),
singletons1_lower, normal1, sizeof(normal1));
}\
""")
for a, b in extra:
print(" if (0x{:x} <= cp && cp < 0x{:x}) return false;".format(a, a + b))
print("""\
return cp < 0x{:x};
}}\
""".format(NUM_CODEPOINTS))
if __name__ == '__main__':
main()

43
support/rst2md.py Normal file → Executable file
View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
# reStructuredText (RST) to GitHub-flavored Markdown converter
import re
import re, sys
from docutils import core, nodes, writers
@ -35,6 +36,9 @@ class Translator(nodes.NodeVisitor):
self.version = re.match(r'(\d+\.\d+\.\d+).*', node.children[0]).group(1)
raise nodes.SkipChildren
def visit_title_reference(self, node):
raise Exception(node)
def depart_title(self, node):
pass
@ -61,7 +65,7 @@ class Translator(nodes.NodeVisitor):
self.write('\n\n')
def visit_paragraph(self, node):
pass
self.write('\n\n')
def depart_paragraph(self, node):
pass
@ -109,6 +113,37 @@ class Translator(nodes.NodeVisitor):
def depart_image(self, node):
pass
def write_row(self, row, widths):
for i, entry in enumerate(row):
text = entry[0][0] if len(entry) > 0 else ''
if i != 0:
self.write('|')
self.write('{:{}}'.format(text, widths[i]))
self.write('\n')
def visit_table(self, node):
table = node.children[0]
colspecs = table[:-2]
thead = table[-2]
tbody = table[-1]
widths = [int(cs['colwidth']) for cs in colspecs]
sep = '|'.join(['-' * w for w in widths]) + '\n'
self.write('\n\n')
self.write_row(thead[0], widths)
self.write(sep)
for row in tbody:
self.write_row(row, widths)
raise nodes.SkipChildren
def depart_table(self, node):
pass
def visit_system_message(self, node):
pass
def depart_system_message(self, node):
pass
class MDWriter(writers.Writer):
"""GitHub-flavored markdown writer"""
@ -125,3 +160,7 @@ class MDWriter(writers.Writer):
def convert(rst_path):
"""Converts RST file to Markdown."""
return core.publish_file(source_path=rst_path, writer=MDWriter())
if __name__ == '__main__':
convert(sys.argv[1])

View File

@ -1,2 +1,2 @@
If you are not redirected automatically, follow the
`link to the fmt documentation <http://fmtlib.net/latest/>`_.
`link to the fmt documentation <https://fmt.dev/latest/>`_.

View File

@ -2,15 +2,15 @@
{% block extrahead %}
<meta charset="UTF-8">
<meta http-equiv="refresh" content="1;url=http://fmtlib.net/latest/">
<meta http-equiv="refresh" content="1;url=https://fmt.dev/latest/">
<script type="text/javascript">
window.location.href = "http://fmtlib.net/latest/"
window.location.href = "https://fmt.dev/latest/"
</script>
<title>Page Redirection</title>
{% endblock %}
{% block document %}
If you are not redirected automatically, follow the <a href='http://fmtlib.net/latest/'>link to the fmt documentation</a>.
If you are not redirected automatically, follow the <a href='https://fmt.dev/latest/'>link to the fmt documentation</a>.
{% endblock %}
{% block footer %}

View File

@ -1,118 +0,0 @@
#!/usr/bin/env python
# Build the project on Travis CI.
from __future__ import print_function
import errno, os, re, shutil, sys, tempfile, urllib
from subprocess import call, check_call, check_output, Popen, PIPE, STDOUT
def rmtree_if_exists(dir):
try:
shutil.rmtree(dir)
except OSError as e:
if e.errno == errno.ENOENT:
pass
def makedirs_if_not_exist(dir):
try:
os.makedirs(dir)
except OSError as e:
if e.errno != errno.EEXIST:
raise
def install_dependencies():
branch = os.environ['TRAVIS_BRANCH']
if branch != 'master':
print('Branch: ' + branch)
exit(0) # Ignore non-master branches
check_call('curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key ' +
'| sudo apt-key add -', shell=True)
check_call('echo "deb https://deb.nodesource.com/node_0.10 precise main" ' +
'| sudo tee /etc/apt/sources.list.d/nodesource.list', shell=True)
check_call(['sudo', 'apt-get', 'update'])
check_call(['sudo', 'apt-get', 'install', 'python-virtualenv', 'nodejs'])
check_call(['sudo', 'npm', 'install', '-g', 'less@2.6.1', 'less-plugin-clean-css'])
deb_file = 'doxygen_1.8.6-2_amd64.deb'
urllib.urlretrieve('http://mirrors.kernel.org/ubuntu/pool/main/d/doxygen/' +
deb_file, deb_file)
check_call(['sudo', 'dpkg', '-i', deb_file])
fmt_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
build = os.environ['BUILD']
if build == 'Doc':
travis = 'TRAVIS' in os.environ
if travis:
install_dependencies()
sys.path.insert(0, os.path.join(fmt_dir, 'doc'))
import build
build.create_build_env()
html_dir = build.build_docs()
repo = 'fmtlib.github.io'
if travis and 'KEY' not in os.environ:
# Don't update the repo if building on Travis from an account that
# doesn't have push access.
print('Skipping update of ' + repo)
exit(0)
# Clone the fmtlib.github.io repo.
rmtree_if_exists(repo)
git_url = 'https://github.com/' if travis else 'git@github.com:'
check_call(['git', 'clone', git_url + 'fmtlib/{}.git'.format(repo)])
# Copy docs to the repo.
target_dir = os.path.join(repo, 'dev')
rmtree_if_exists(target_dir)
shutil.copytree(html_dir, target_dir, ignore=shutil.ignore_patterns('.*'))
if travis:
check_call(['git', 'config', '--global', 'user.name', 'amplbot'])
check_call(['git', 'config', '--global', 'user.email', 'viz@ampl.com'])
# Push docs to GitHub pages.
check_call(['git', 'add', '--all'], cwd=repo)
if call(['git', 'diff-index', '--quiet', 'HEAD'], cwd=repo):
check_call(['git', 'commit', '-m', 'Update documentation'], cwd=repo)
cmd = 'git push'
if travis:
cmd += ' https://$KEY@github.com/fmtlib/fmtlib.github.io.git master'
p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=repo)
# Print the output without the key.
print(p.communicate()[0].replace(os.environ['KEY'], '$KEY'))
if p.returncode != 0:
raise CalledProcessError(p.returncode, cmd)
exit(0)
standard = os.environ['STANDARD']
install_dir = os.path.join(fmt_dir, "_install")
build_dir = os.path.join(fmt_dir, "_build")
test_build_dir = os.path.join(fmt_dir, "_build_test")
# Configure library.
makedirs_if_not_exist(build_dir)
common_cmake_flags = [
'-DCMAKE_INSTALL_PREFIX=' + install_dir, '-DCMAKE_BUILD_TYPE=' + build
]
extra_cmake_flags = []
if standard != '0x':
extra_cmake_flags = [
'-DCMAKE_CXX_FLAGS=-std=c++' + standard, '-DFMT_USE_CPP11=OFF'
]
check_call(['cmake', '-DFMT_DOC=OFF', '-DFMT_PEDANTIC=ON', fmt_dir] +
common_cmake_flags + extra_cmake_flags, cwd=build_dir)
# Build library.
check_call(['make', '-j4'], cwd=build_dir)
# Test library.
env = os.environ.copy()
env['CTEST_OUTPUT_ON_FAILURE'] = '1'
if call(['make', 'test'], env=env, cwd=build_dir):
with open('Testing/Temporary/LastTest.log', 'r') as f:
print(f.read())
sys.exit(-1)
# Install library.
check_call(['make', 'install'], cwd=build_dir)
# Test installation.
makedirs_if_not_exist(test_build_dir)
check_call(['cmake', '-DCMAKE_CXX_FLAGS=-std=c++' + standard,
os.path.join(fmt_dir, "test", "find-package-test")] +
common_cmake_flags, cwd=test_build_dir)
check_call(['make', '-j4'], cwd=test_build_dir)

View File

@ -1,30 +0,0 @@
#!/usr/bin/env python
# Update the coverity branch from the master branch.
# It is not done automatically because Coverity Scan limits
# the number of submissions per day.
from __future__ import print_function
import shutil, tempfile
from subprocess import check_output, STDOUT
class Git:
def __init__(self, dir):
self.dir = dir
def __call__(self, *args):
output = check_output(['git'] + list(args), cwd=self.dir, stderr=STDOUT)
print(output)
return output
dir = tempfile.mkdtemp()
try:
git = Git(dir)
git('clone', '-b', 'coverity', 'git@github.com:fmtlib/fmt.git', dir)
output = git('merge', '-X', 'theirs', '--no-commit', 'origin/master')
if 'Fast-forward' not in output:
git('reset', 'HEAD', '.travis.yml')
git('checkout', '--', '.travis.yml')
git('commit', '-m', 'Update coverity branch')
git('push')
finally:
shutil.rmtree(dir)

View File

@ -1,157 +1,196 @@
#------------------------------------------------------------------------------
# Build the google test library
add_subdirectory(gtest)
# We compile Google Test ourselves instead of using pre-compiled libraries.
# See the Google Test FAQ "Why is it not recommended to install a
# pre-compiled copy of Google Test (for example, into /usr/local)?"
# at http://code.google.com/p/googletest/wiki/FAQ for more details.
add_library(gmock STATIC
gmock-gtest-all.cc gmock/gmock.h gtest/gtest.h gtest/gtest-spi.h)
target_compile_options(gmock PUBLIC ${CPP11_FLAG})
target_compile_definitions(gmock PUBLIC GTEST_HAS_STD_WSTRING=1)
target_include_directories(gmock PUBLIC .)
# Workaround for Cygwin to make google-tests compile and run because the macro
# _POSIX_C_SOURCE must be defined to allow fileno(), strdup(), fdopen() calls.
if (CYGWIN)
target_compile_definitions(gmock PUBLIC _POSIX_C_SOURCE=200809)
endif ()
find_package(Threads)
if (Threads_FOUND)
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
else ()
target_compile_definitions(gmock PUBLIC GTEST_HAS_PTHREAD=0)
endif ()
if (NOT SUPPORTS_VARIADIC_TEMPLATES OR NOT SUPPORTS_INITIALIZER_LIST)
target_compile_definitions(gmock PUBLIC GTEST_LANG_CXX11=0)
endif ()
# Workaround a bug in implementation of variadic templates in MSVC11.
if (MSVC)
target_compile_definitions(gmock PUBLIC _VARIADIC_MAX=10)
endif ()
# GTest doesn't detect <tuple> with clang.
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_definitions(gmock PUBLIC GTEST_USE_OWN_TR1_TUPLE=1)
endif ()
#------------------------------------------------------------------------------
# Build the actual library tests
include(CheckSymbolExists)
set(TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc)
add_library(test-main STATIC ${TEST_MAIN_SRC})
target_compile_definitions(test-main PUBLIC
FMT_USE_FILE_DESCRIPTORS=$<BOOL:${HAVE_OPEN}>)
target_link_libraries(test-main gmock fmt)
include(CheckCXXCompilerFlag)
# Workaround GTest bug https://github.com/google/googletest/issues/705.
check_cxx_compiler_flag(
-fno-delete-null-pointer-checks HAVE_FNO_DELETE_NULL_POINTER_CHECKS)
if (HAVE_FNO_DELETE_NULL_POINTER_CHECKS)
target_compile_options(test-main PUBLIC -fno-delete-null-pointer-checks)
endif ()
# Use less strict pedantic flags for the tests because GMock doesn't compile
# cleanly with -pedantic and -std=c++98.
if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wno-long-long -Wno-variadic-macros)
endif ()
target_include_directories(test-main PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
target_link_libraries(test-main gtest fmt)
function(add_fmt_executable name)
add_executable(${name} ${ARGN})
if (MINGW)
target_link_libraries(${name} -static-libgcc -static-libstdc++)
# (Wstringop-overflow) - [meta-bug] bogus/missing -Wstringop-overflow warnings
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
# Bogus -Wstringop-overflow warning
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100395
# [10 Regression] spurious -Wstringop-overflow writing to a trailing array plus offset
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95353
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND
NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
target_compile_options(${name} PRIVATE -Wno-stringop-overflow)
# The linker flag is needed for LTO.
target_link_libraries(${name} -Wno-stringop-overflow)
endif ()
endfunction()
# Adds a test.
# Usage: add_fmt_test(name srcs...)
function(add_fmt_test name)
add_fmt_executable(${name} ${name}.cc ${ARGN})
target_link_libraries(${name} test-main)
cmake_parse_arguments(ADD_FMT_TEST "HEADER_ONLY;MODULE" "" "" ${ARGN})
# define if certain c++ features can be used
target_compile_definitions(${name} PRIVATE
FMT_USE_TYPE_TRAITS=$<BOOL:${SUPPORTS_TYPE_TRAITS}>
FMT_USE_ENUM_BASE=$<BOOL:${SUPPORTS_ENUM_BASE}>)
set(sources ${name}.cc ${ADD_FMT_TEST_UNPARSED_ARGUMENTS})
if (ADD_FMT_TEST_HEADER_ONLY)
set(sources ${sources} ${TEST_MAIN_SRC} ../src/os.cc)
set(libs gtest fmt-header-only)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-weak-vtables)
endif ()
elseif (ADD_FMT_TEST_MODULE)
set(libs test-main test-module)
set_source_files_properties(${name}.cc PROPERTIES OBJECT_DEPENDS test-module)
else ()
set(libs test-main fmt)
endif ()
add_fmt_executable(${name} ${sources})
target_link_libraries(${name} ${libs})
# Define if certain C++ features can be used.
if (FMT_PEDANTIC)
target_compile_options(${name} PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
if (FMT_WERROR)
target_compile_options(${name} PRIVATE ${WERROR_FLAG})
endif ()
add_test(NAME ${name} COMMAND ${name})
endfunction()
if (FMT_MODULE)
return ()
endif ()
add_fmt_test(args-test)
add_fmt_test(assert-test)
add_fmt_test(container-test)
add_fmt_test(chrono-test)
add_fmt_test(color-test)
add_fmt_test(core-test)
add_fmt_test(gtest-extra-test)
add_fmt_test(format-test)
add_fmt_test(format-impl-test)
add_fmt_test(format-test mock-allocator.h)
if (MSVC)
target_compile_options(format-test PRIVATE /bigobj)
endif ()
if (NOT (MSVC AND BUILD_SHARED_LIBS))
add_fmt_test(format-impl-test HEADER_ONLY header-only-test.cc)
endif ()
add_fmt_test(ostream-test)
add_fmt_test(compile-test)
add_fmt_test(compile-fp-test HEADER_ONLY)
if (MSVC)
# Without this option, MSVC returns 199711L for the __cplusplus macro.
target_compile_options(compile-fp-test PRIVATE /Zc:__cplusplus)
endif()
add_fmt_test(printf-test)
add_fmt_test(string-test)
add_fmt_test(time-test)
add_fmt_test(util-test mock-allocator.h)
add_fmt_test(macro-test)
add_fmt_test(custom-formatter-test)
add_fmt_test(ranges-test ranges-odr-test.cc)
# Enable stricter options for one test to make sure that the header is free of
# warnings.
if (FMT_PEDANTIC AND MSVC)
target_compile_options(format-test PRIVATE /W4)
add_fmt_test(scan-test)
check_symbol_exists(strptime "time.h" HAVE_STRPTIME)
if (HAVE_STRPTIME)
target_compile_definitions(scan-test PRIVATE FMT_HAVE_STRPTIME)
endif ()
if (HAVE_OPEN)
add_fmt_test(std-test)
try_compile(compile_result_unused
${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_LIST_DIR}/detect-stdfs.cc
OUTPUT_VARIABLE RAWOUTPUT)
string(REGEX REPLACE ".*libfound \"([^\"]*)\".*" "\\1" STDLIBFS "${RAWOUTPUT}")
if (STDLIBFS)
target_link_libraries(std-test ${STDLIBFS})
endif ()
add_fmt_test(unicode-test HEADER_ONLY)
if (MSVC)
target_compile_options(unicode-test PRIVATE /utf-8)
endif ()
add_fmt_test(xchar-test)
add_fmt_test(enforce-checks-test)
target_compile_definitions(enforce-checks-test PRIVATE
-DFMT_ENFORCE_COMPILE_STRING)
if (FMT_MODULE)
# The tests need {fmt} to be compiled as traditional library
# because of visibility of implementation details.
# If module support is present the module tests require a
# test-only module to be built from {fmt}
add_library(test-module OBJECT ${CMAKE_SOURCE_DIR}/src/fmt.cc)
target_compile_features(test-module PUBLIC cxx_std_11)
target_include_directories(test-module PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
enable_module(test-module)
add_fmt_test(module-test MODULE test-main.cc)
if (MSVC)
target_compile_options(test-module PRIVATE /utf-8 /Zc:__cplusplus
/Zc:externConstexpr /Zc:inline)
target_compile_options(module-test PRIVATE /utf-8 /Zc:__cplusplus
/Zc:externConstexpr /Zc:inline)
endif ()
endif ()
if (NOT DEFINED MSVC_STATIC_RUNTIME AND MSVC)
foreach (flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (${flag_var} MATCHES "^(/|-)(MT|MTd)")
set(MSVC_STATIC_RUNTIME ON)
break()
endif()
endforeach()
endif()
if (NOT MSVC_STATIC_RUNTIME)
add_fmt_executable(posix-mock-test
posix-mock-test.cc ../fmt/format.cc ../fmt/printf.cc ${TEST_MAIN_SRC})
target_include_directories(posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_definitions(posix-mock-test PRIVATE FMT_USE_FILE_DESCRIPTORS=1)
target_link_libraries(posix-mock-test gmock)
posix-mock-test.cc ../src/format.cc ${TEST_MAIN_SRC})
target_include_directories(
posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(posix-mock-test gtest)
if (FMT_PEDANTIC)
target_compile_options(posix-mock-test PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
add_test(NAME posix-mock-test COMMAND posix-mock-test)
add_fmt_test(posix-test)
add_fmt_test(os-test)
endif ()
add_fmt_executable(header-only-test
header-only-test.cc header-only-test2.cc test-main.cc)
target_link_libraries(header-only-test gmock)
if (TARGET fmt-header-only)
target_link_libraries(header-only-test fmt-header-only)
else ()
target_include_directories(header-only-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_definitions(header-only-test PRIVATE FMT_HEADER_ONLY=1)
endif ()
# Test that the library can be compiled with exceptions disabled.
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
if (HAVE_FNO_EXCEPTIONS_FLAG)
add_library(noexception-test ../fmt/format.cc)
target_include_directories(noexception-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_options(noexception-test PRIVATE -fno-exceptions)
endif ()
message(STATUS "FMT_PEDANTIC: ${FMT_PEDANTIC}")
if (FMT_PEDANTIC)
# Test that the library compiles without windows.h.
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_library(no-windows-h-test ../fmt/format.cc)
target_include_directories(no-windows-h-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0)
# Test that the library can be compiled with exceptions disabled.
# -fno-exception is broken in icc: https://github.com/fmtlib/fmt/issues/822.
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
endif ()
if (HAVE_FNO_EXCEPTIONS_FLAG)
add_library(noexception-test ../src/format.cc noexception-test.cc)
target_include_directories(
noexception-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_options(noexception-test PRIVATE -fno-exceptions)
target_compile_options(noexception-test PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
add_test(compile-test ${CMAKE_CTEST_COMMAND}
# Test that the library compiles without locale.
add_library(nolocale-test ../src/format.cc)
target_include_directories(
nolocale-test PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_compile_definitions(
nolocale-test PRIVATE FMT_STATIC_THOUSANDS_SEPARATOR=1)
endif ()
# These tests are disabled on Windows because they take too long.
if (FMT_PEDANTIC AND NOT WIN32)
# Test if incorrect API usages produce compilation error.
add_test(compile-error-test ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/compile-test"
"${CMAKE_CURRENT_BINARY_DIR}/compile-test"
"${CMAKE_CURRENT_SOURCE_DIR}/compile-error-test"
"${CMAKE_CURRENT_BINARY_DIR}/compile-error-test"
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCPP11_FLAG=${CPP11_FLAG}"
"-DSUPPORTS_USER_DEFINED_LITERALS=${SUPPORTS_USER_DEFINED_LITERALS}")
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DCXX_STANDARD_FLAG=${CXX_STANDARD_FLAG}"
"-DFMT_DIR=${CMAKE_SOURCE_DIR}")
# test if the targets are findable from the build directory
# Test if the targets are found from the build directory.
add_test(find-package-test ${CMAKE_CTEST_COMMAND}
-C ${CMAKE_BUILD_TYPE}
--build-and-test
@ -161,10 +200,13 @@ if (FMT_PEDANTIC)
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DFMT_DIR=${PROJECT_BINARY_DIR}"
"-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
# test if the targets are findable when add_subdirectory is used
# Test if the targets are found when add_subdirectory is used.
add_test(add-subdirectory-test ${CMAKE_CTEST_COMMAND}
-C ${CMAKE_BUILD_TYPE}
--build-and-test
@ -174,5 +216,42 @@ if (FMT_PEDANTIC)
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
endif ()
# This test are disabled on Windows because it is only *NIX issue.
if (FMT_PEDANTIC AND NOT WIN32)
add_test(static-export-test ${CMAKE_CTEST_COMMAND}
-C ${CMAKE_BUILD_TYPE}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/static-export-test"
"${CMAKE_CURRENT_BINARY_DIR}/static-export-test"
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
endif ()
# Activate optional CUDA tests if CUDA is found. For version selection see
# https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cpp14-language-features
if (FMT_CUDA_TEST)
if (${CMAKE_VERSION} VERSION_LESS 3.15)
find_package(CUDA 9.0)
else ()
include(CheckLanguage)
check_language(CUDA)
if (CMAKE_CUDA_COMPILER)
enable_language(CUDA OPTIONAL)
set(CUDA_FOUND TRUE)
endif ()
endif ()
if (CUDA_FOUND)
add_subdirectory(cuda-test)
add_test(NAME cuda-test COMMAND fmt-in-cuda-test)
endif ()
endif ()

View File

@ -1,13 +1,17 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.8...3.25)
project(fmt-test)
project(fmt-test CXX)
add_subdirectory(../.. fmt)
add_executable(library-test "main.cc")
add_executable(library-test main.cc)
target_include_directories(library-test PUBLIC SYSTEM .)
target_compile_options(library-test PRIVATE ${PEDANTIC_COMPILE_FLAGS})
target_link_libraries(library-test fmt::fmt)
if (TARGET fmt::fmt-header-only)
add_executable(header-only-test "main.cc")
add_executable(header-only-test main.cc)
target_include_directories(header-only-test PUBLIC SYSTEM .)
target_compile_options(header-only-test PRIVATE ${PEDANTIC_COMPILE_FLAGS})
target_link_libraries(header-only-test fmt::fmt-header-only)
endif ()

View File

@ -1,6 +1,5 @@
#include "fmt/format.h"
#include "fmt/core.h"
int main(int argc, char** argv) {
for(int i = 0; i < argc; ++i)
fmt::print("{}: {}\n", i, argv[i]);
for (int i = 0; i < argc; ++i) fmt::print("{}: {}\n", i, argv[i]);
}

186
test/args-test.cc Normal file
View File

@ -0,0 +1,186 @@
// Formatting library for C++ - dynamic argument store tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/args.h"
#include <memory>
#include "gtest/gtest.h"
TEST(args_test, basic) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(42);
store.push_back("abc1");
store.push_back(1.5f);
EXPECT_EQ("42 and abc1 and 1.5", fmt::vformat("{} and {} and {}", store));
}
TEST(args_test, strings_and_refs) {
// Unfortunately the tests are compiled with old ABI so strings use COW.
fmt::dynamic_format_arg_store<fmt::format_context> store;
char str[] = "1234567890";
store.push_back(str);
store.push_back(std::cref(str));
store.push_back(fmt::string_view{str});
str[0] = 'X';
auto result = fmt::vformat("{} and {} and {}", store);
EXPECT_EQ("1234567890 and X234567890 and X234567890", result);
}
struct custom_type {
int i = 0;
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<custom_type> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const custom_type& p, FormatContext& ctx) -> decltype(ctx.out()) {
return fmt::format_to(ctx.out(), "cust={}", p.i);
}
};
FMT_END_NAMESPACE
TEST(args_test, custom_format) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
auto c = custom_type();
store.push_back(c);
++c.i;
store.push_back(c);
++c.i;
store.push_back(std::cref(c));
++c.i;
auto result = fmt::vformat("{} and {} and {}", store);
EXPECT_EQ("cust=0 and cust=1 and cust=3", result);
}
struct to_stringable {
friend fmt::string_view to_string_view(to_stringable) { return {}; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<to_stringable> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(to_stringable, format_context& ctx) -> decltype(ctx.out()) {
return ctx.out();
}
};
FMT_END_NAMESPACE
TEST(args_test, to_string_and_formatter) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
auto s = to_stringable();
store.push_back(s);
store.push_back(std::cref(s));
fmt::vformat("", store);
}
TEST(args_test, named_int) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(fmt::arg("a1", 42));
EXPECT_EQ("42", fmt::vformat("{a1}", store));
}
TEST(args_test, named_strings) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
char str[] = "1234567890";
store.push_back(fmt::arg("a1", str));
store.push_back(fmt::arg("a2", std::cref(str)));
str[0] = 'X';
EXPECT_EQ("1234567890 and X234567890", fmt::vformat("{a1} and {a2}", store));
}
TEST(args_test, named_arg_by_ref) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
char band[] = "Rolling Stones";
store.push_back(fmt::arg("band", std::cref(band)));
band[9] = 'c'; // Changing band affects the output.
EXPECT_EQ(fmt::vformat("{band}", store), "Rolling Scones");
}
TEST(args_test, named_custom_format) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
auto c = custom_type();
store.push_back(fmt::arg("c1", c));
++c.i;
store.push_back(fmt::arg("c2", c));
++c.i;
store.push_back(fmt::arg("c_ref", std::cref(c)));
++c.i;
auto result = fmt::vformat("{c1} and {c2} and {c_ref}", store);
EXPECT_EQ("cust=0 and cust=1 and cust=3", result);
}
TEST(args_test, clear) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(42);
auto result = fmt::vformat("{}", store);
EXPECT_EQ("42", result);
store.push_back(43);
result = fmt::vformat("{} and {}", store);
EXPECT_EQ("42 and 43", result);
store.clear();
store.push_back(44);
result = fmt::vformat("{}", store);
EXPECT_EQ("44", result);
}
TEST(args_test, reserve) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.reserve(2, 1);
store.push_back(1.5f);
store.push_back(fmt::arg("a1", 42));
auto result = fmt::vformat("{a1} and {}", store);
EXPECT_EQ("42 and 1.5", result);
}
struct copy_throwable {
copy_throwable() {}
copy_throwable(const copy_throwable&) { throw "deal with it"; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<copy_throwable> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(copy_throwable, format_context& ctx) -> decltype(ctx.out()) {
return ctx.out();
}
};
FMT_END_NAMESPACE
TEST(args_test, throw_on_copy) {
fmt::dynamic_format_arg_store<fmt::format_context> store;
store.push_back(std::string("foo"));
try {
store.push_back(copy_throwable());
} catch (...) {
}
EXPECT_EQ(fmt::vformat("{}", store), "foo");
}
TEST(args_test, move_constructor) {
using store_type = fmt::dynamic_format_arg_store<fmt::format_context>;
auto store = std::unique_ptr<store_type>(new store_type());
store->push_back(42);
store->push_back(std::string("foo"));
store->push_back(fmt::arg("a1", "foo"));
auto moved_store = std::move(*store);
store.reset();
EXPECT_EQ(fmt::vformat("{} {} {a1}", moved_store), "42 foo foo");
}

View File

@ -1,41 +1,31 @@
/*
Assertion tests
// Formatting library for C++ - FMT_ASSERT test
//
// It is a separate test to minimize the number of EXPECT_DEBUG_DEATH checks
// which are slow on some platforms. In other tests FMT_ASSERT is made to throw
// an exception which is much faster and easier to check.
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
Copyright (c) 2015, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fmt/format.h"
#include "fmt/core.h"
#include "gtest/gtest.h"
TEST(assert_test, fail) {
#if GTEST_HAS_DEATH_TEST
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEBUG_DEATH(statement, regex)
EXPECT_DEBUG_DEATH(FMT_ASSERT(false, "don't panic!"), "don't panic!");
#else
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
fmt::print("warning: death tests are not supported\n");
#endif
TEST(AssertTest, Fail) {
EXPECT_DEBUG_DEATH_IF_SUPPORTED(FMT_ASSERT(false, "don't panic!"), "don't panic!");
}
TEST(assert_test, dangling_else) {
bool test_condition = false;
bool executed_else = false;
if (test_condition)
FMT_ASSERT(true, "");
else
executed_else = true;
EXPECT_TRUE(executed_else);
}

1003
test/chrono-test.cc Normal file

File diff suppressed because it is too large Load Diff

72
test/color-test.cc Normal file
View File

@ -0,0 +1,72 @@
// Formatting library for C++ - color tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/color.h"
#include <iterator> // std::back_inserter
#include "gtest-extra.h" // EXPECT_WRITE
TEST(color_test, format) {
EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"),
"\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m");
EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue"),
"\x1b[38;2;000;000;255mblue\x1b[0m");
EXPECT_EQ(
fmt::format(fg(fmt::color::blue) | bg(fmt::color::red), "two color"),
"\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold"), "\x1b[1mbold\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::faint, "faint"), "\x1b[2mfaint\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::italic, "italic"),
"\x1b[3mitalic\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::underline, "underline"),
"\x1b[4munderline\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::blink, "blink"), "\x1b[5mblink\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::reverse, "reverse"),
"\x1b[7mreverse\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::conceal, "conceal"),
"\x1b[8mconceal\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::strikethrough, "strikethrough"),
"\x1b[9mstrikethrough\x1b[0m");
EXPECT_EQ(
fmt::format(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"),
"\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m");
EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"),
"\x1b[1mbold error\x1b[0m");
EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue log"),
"\x1b[38;2;000;000;255mblue log\x1b[0m");
EXPECT_EQ(fmt::format(fmt::text_style(), "hi"), "hi");
EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "tred"),
"\x1b[31mtred\x1b[0m");
EXPECT_EQ(fmt::format(bg(fmt::terminal_color::cyan), "tcyan"),
"\x1b[46mtcyan\x1b[0m");
EXPECT_EQ(fmt::format(fg(fmt::terminal_color::bright_green), "tbgreen"),
"\x1b[92mtbgreen\x1b[0m");
EXPECT_EQ(fmt::format(bg(fmt::terminal_color::bright_magenta), "tbmagenta"),
"\x1b[105mtbmagenta\x1b[0m");
EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "{}", "foo"),
"\x1b[31mfoo\x1b[0m");
EXPECT_EQ(fmt::format("{}{}", fmt::styled("red", fg(fmt::color::red)),
fmt::styled("bold", fmt::emphasis::bold)),
"\x1b[38;2;255;000;000mred\x1b[0m\x1b[1mbold\x1b[0m");
EXPECT_EQ(fmt::format("{}", fmt::styled("bar", fg(fmt::color::blue) |
fmt::emphasis::underline)),
"\x1b[4m\x1b[38;2;000;000;255mbar\x1b[0m");
}
TEST(color_test, format_to) {
auto out = std::string();
fmt::format_to(std::back_inserter(out), fg(fmt::rgb(255, 20, 30)),
"rgb(255,20,30){}{}{}", 1, 2, 3);
EXPECT_EQ(fmt::to_string(out),
"\x1b[38;2;255;020;030mrgb(255,20,30)123\x1b[0m");
}
TEST(color_test, print) {
EXPECT_WRITE(stdout, fmt::print(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"),
"\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m");
}

View File

@ -0,0 +1,241 @@
# Test if compile errors are produced where necessary.
cmake_minimum_required(VERSION 3.8...3.25)
project(compile-error-test CXX)
set(fmt_headers "
#include <fmt/format.h>
#include <fmt/xchar.h>
#include <fmt/ostream.h>
#include <iostream>
")
set(error_test_names "")
set(non_error_test_content "")
# For error tests (we expect them to produce compilation error):
# * adds a name of test into `error_test_names` list
# * generates a single source file (with the same name) for each test
# For non-error tests (we expect them to compile successfully):
# * adds a code segment as separate function to `non_error_test_content`
function (expect_compile name code_fragment)
cmake_parse_arguments(EXPECT_COMPILE "ERROR" "" "" ${ARGN})
string(MAKE_C_IDENTIFIER "${name}" test_name)
if (EXPECT_COMPILE_ERROR)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/${test_name}.cc" "
${fmt_headers}
void ${test_name}() {
${code_fragment}
}
")
set(error_test_names_copy "${error_test_names}")
list(APPEND error_test_names_copy "${test_name}")
set(error_test_names "${error_test_names_copy}" PARENT_SCOPE)
else()
set(non_error_test_content "
${non_error_test_content}
void ${test_name}() {
${code_fragment}
}" PARENT_SCOPE)
endif()
endfunction ()
# Generates a source file for non-error test with `non_error_test_content` and
# CMake project file with all error and single non-error test targets.
function (run_tests)
set(cmake_targets "")
foreach(test_name IN LISTS error_test_names)
set(cmake_targets "
${cmake_targets}
add_library(test-${test_name} ${test_name}.cc)
target_link_libraries(test-${test_name} PRIVATE fmt::fmt)
")
endforeach()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/non_error_test.cc" "
${fmt_headers}
${non_error_test_content}
")
set(cmake_targets "
${cmake_targets}
add_library(non-error-test non_error_test.cc)
target_link_libraries(non-error-test PRIVATE fmt::fmt)
")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/CMakeLists.txt" "
cmake_minimum_required(VERSION 3.8...3.25)
project(tests CXX)
add_subdirectory(${FMT_DIR} fmt)
${cmake_targets}
")
set(build_directory "${CMAKE_CURRENT_BINARY_DIR}/test/build")
file(MAKE_DIRECTORY "${build_directory}")
execute_process(
COMMAND
"${CMAKE_COMMAND}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
"-DCMAKE_GENERATOR=${CMAKE_GENERATOR}"
"-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
"-DFMT_DIR=${FMT_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/test"
WORKING_DIRECTORY "${build_directory}"
RESULT_VARIABLE result_var
OUTPUT_VARIABLE output_var
ERROR_VARIABLE output_var)
if (NOT result_var EQUAL 0)
message(FATAL_ERROR "Unable to configure:\n${output_var}")
endif()
foreach(test_name IN LISTS error_test_names)
execute_process(
COMMAND
"${CMAKE_COMMAND}" --build "${build_directory}" --target "test-${test_name}"
WORKING_DIRECTORY "${build_directory}"
RESULT_VARIABLE result_var
OUTPUT_VARIABLE output_var
ERROR_QUIET)
if (result_var EQUAL 0)
message(SEND_ERROR "No compile error for \"${test_name}\":\n${output_var}")
endif ()
endforeach()
execute_process(
COMMAND
"${CMAKE_COMMAND}" --build "${build_directory}" --target "non-error-test"
WORKING_DIRECTORY "${build_directory}"
RESULT_VARIABLE result_var
OUTPUT_VARIABLE output_var
ERROR_VARIABLE output_var)
if (NOT result_var EQUAL 0)
message(SEND_ERROR "Compile error for combined non-error test:\n${output_var}")
endif ()
endfunction ()
# check if the source file skeleton compiles
expect_compile(check "")
expect_compile(check-error "compilation_error" ERROR)
# Formatting a wide character with a narrow format string is forbidden.
expect_compile(wide-character-narrow-format-string "fmt::format(L\"{}\", L'a');")
expect_compile(wide-character-narrow-format-string-error "fmt::format(\"{}\", L'a');" ERROR)
# Formatting a wide string with a narrow format string is forbidden.
expect_compile(wide-string-narrow-format-string "fmt::format(L\"{}\", L\"foo\");")
expect_compile(wide-string-narrow-format-string-error "fmt::format(\"{}\", L\"foo\");" ERROR)
# Formatting a narrow string with a wide format string is forbidden because
# mixing UTF-8 with UTF-16/32 can result in an invalid output.
expect_compile(narrow-string-wide-format-string "fmt::format(L\"{}\", L\"foo\");")
expect_compile(narrow-string-wide-format-string-error "fmt::format(L\"{}\", \"foo\");" ERROR)
expect_compile(cast-to-string "
struct S {
operator std::string() const { return std::string(); }
};
fmt::format(\"{}\", std::string(S()));
")
expect_compile(cast-to-string-error "
struct S {
operator std::string() const { return std::string(); }
};
fmt::format(\"{}\", S());
" ERROR)
# Formatting a function
expect_compile(format-function "
void (*f)();
fmt::format(\"{}\", fmt::ptr(f));
")
expect_compile(format-function-error "
void (*f)();
fmt::format(\"{}\", f);
" ERROR)
# Formatting an unformattable argument should always be a compile time error
expect_compile(format-lots-of-arguments-with-unformattable "
struct E {};
fmt::format(\"\", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, E());
" ERROR)
expect_compile(format-lots-of-arguments-with-function "
void (*f)();
fmt::format(\"\", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, f);
" ERROR)
# Check if user-defined literals are available
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_FLAGS ${CXX_STANDARD_FLAG})
check_cxx_source_compiles("
void operator\"\" _udl(long double);
int main() {}"
SUPPORTS_USER_DEFINED_LITERALS)
set(CMAKE_REQUIRED_FLAGS )
if (NOT SUPPORTS_USER_DEFINED_LITERALS)
set (SUPPORTS_USER_DEFINED_LITERALS OFF)
endif ()
# Make sure that compiler features detected in the header
# match the features detected in CMake.
if (SUPPORTS_USER_DEFINED_LITERALS)
set(supports_udl 1)
else ()
set(supports_udl 0)
endif ()
expect_compile(udl-check "
#if FMT_USE_USER_DEFINED_LITERALS != ${supports_udl}
# error
#endif
")
if (CMAKE_CXX_STANDARD GREATER_EQUAL 20)
# Compile-time argument type check
expect_compile(format-string-number-spec "
#ifdef FMT_HAS_CONSTEVAL
fmt::format(\"{:d}\", 42);
#endif
")
expect_compile(format-string-number-spec-error "
#ifdef FMT_HAS_CONSTEVAL
fmt::format(\"{:d}\", \"I am not a number\");
#else
#error
#endif
" ERROR)
expect_compile(print-string-number-spec-error "
#ifdef FMT_HAS_CONSTEVAL
fmt::print(\"{:d}\", \"I am not a number\");
#else
#error
#endif
" ERROR)
expect_compile(print-stream-string-number-spec-error "
#ifdef FMT_HAS_CONSTEVAL
fmt::print(std::cout, \"{:d}\", \"I am not a number\");
#else
#error
#endif
" ERROR)
# Compile-time argument name check
expect_compile(format-string-name "
#if defined(FMT_HAS_CONSTEVAL) && FMT_USE_NONTYPE_TEMPLATE_ARGS
using namespace fmt::literals;
fmt::print(\"{foo}\", \"foo\"_a=42);
#endif
")
expect_compile(format-string-name-error "
#if defined(FMT_HAS_CONSTEVAL) && FMT_USE_NONTYPE_TEMPLATE_ARGS
using namespace fmt::literals;
fmt::print(\"{foo}\", \"bar\"_a=42);
#else
#error
#endif
" ERROR)
endif ()
# Run all tests
run_tests()

63
test/compile-fp-test.cc Normal file
View File

@ -0,0 +1,63 @@
// Formatting library for C++ - formatting library tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/compile.h"
#include "gmock/gmock.h"
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806 && \
defined(__cpp_constexpr) && __cpp_constexpr >= 201907 && \
defined(__cpp_constexpr_dynamic_alloc) && \
__cpp_constexpr_dynamic_alloc >= 201907 && FMT_CPLUSPLUS >= 202002L
template <size_t max_string_length, typename Char = char> struct test_string {
template <typename T> constexpr bool operator==(const T& rhs) const noexcept {
return fmt::basic_string_view<Char>(rhs).compare(buffer) == 0;
}
Char buffer[max_string_length]{};
};
template <size_t max_string_length, typename Char = char, typename... Args>
consteval auto test_format(auto format, const Args&... args) {
test_string<max_string_length, Char> string{};
fmt::format_to(string.buffer, format, args...);
return string;
}
TEST(compile_time_formatting_test, floating_point) {
EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{}"), 0.0f));
EXPECT_EQ("392.500000", test_format<11>(FMT_COMPILE("{0:f}"), 392.5f));
EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{:}"), 0.0));
EXPECT_EQ("0.000000", test_format<9>(FMT_COMPILE("{:f}"), 0.0));
EXPECT_EQ("0", test_format<2>(FMT_COMPILE("{:g}"), 0.0));
EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:}"), 392.65));
EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:g}"), 392.65));
EXPECT_EQ("392.65", test_format<7>(FMT_COMPILE("{:G}"), 392.65));
EXPECT_EQ("4.9014e+06", test_format<11>(FMT_COMPILE("{:g}"), 4.9014e6));
EXPECT_EQ("-392.650000", test_format<12>(FMT_COMPILE("{:f}"), -392.65));
EXPECT_EQ("-392.650000", test_format<12>(FMT_COMPILE("{:F}"), -392.65));
EXPECT_EQ("3.926500e+02", test_format<13>(FMT_COMPILE("{0:e}"), 392.65));
EXPECT_EQ("3.926500E+02", test_format<13>(FMT_COMPILE("{0:E}"), 392.65));
EXPECT_EQ("+0000392.6", test_format<11>(FMT_COMPILE("{0:+010.4g}"), 392.65));
EXPECT_EQ("9223372036854775808.000000",
test_format<27>(FMT_COMPILE("{:f}"), 9223372036854775807.0));
constexpr double nan = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ("nan", test_format<4>(FMT_COMPILE("{}"), nan));
EXPECT_EQ("+nan", test_format<5>(FMT_COMPILE("{:+}"), nan));
if (std::signbit(-nan))
EXPECT_EQ("-nan", test_format<5>(FMT_COMPILE("{}"), -nan));
else
fmt::print("Warning: compiler doesn't handle negative NaN correctly");
constexpr double inf = std::numeric_limits<double>::infinity();
EXPECT_EQ("inf", test_format<4>(FMT_COMPILE("{}"), inf));
EXPECT_EQ("+inf", test_format<5>(FMT_COMPILE("{:+}"), inf));
EXPECT_EQ("-inf", test_format<5>(FMT_COMPILE("{}"), -inf));
}
#endif

374
test/compile-test.cc Normal file
View File

@ -0,0 +1,374 @@
// Formatting library for C++ - formatting library tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/compile.h"
#include <type_traits>
#include "fmt/chrono.h"
#include "gmock/gmock.h"
#include "gtest-extra.h"
TEST(iterator_test, counting_iterator) {
auto it = fmt::detail::counting_iterator();
auto prev = it++;
EXPECT_EQ(prev.count(), 0);
EXPECT_EQ(it.count(), 1);
EXPECT_EQ((it + 41).count(), 42);
}
TEST(compile_test, compile_fallback) {
// FMT_COMPILE should fallback on runtime formatting when `if constexpr` is
// not available.
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42));
}
struct type_with_get {
template <int> friend void get(type_with_get);
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<type_with_get> : formatter<int> {
template <typename FormatContext>
auto format(type_with_get, FormatContext& ctx) -> decltype(ctx.out()) {
return formatter<int>::format(42, ctx);
}
};
FMT_END_NAMESPACE
TEST(compile_test, compile_type_with_get) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), type_with_get()));
}
#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
struct test_formattable {};
FMT_BEGIN_NAMESPACE
template <> struct formatter<test_formattable> : formatter<const char*> {
char word_spec = 'f';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it;
if (it != end && (*it == 'f' || *it == 'b')) word_spec = *it++;
if (it != end && *it != '}') throw format_error("invalid format");
return it;
}
template <typename FormatContext>
constexpr auto format(test_formattable, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<const char*>::format(word_spec == 'f' ? "foo" : "bar",
ctx);
}
};
FMT_END_NAMESPACE
TEST(compile_test, format_default) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42));
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42u));
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42ll));
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42ull));
EXPECT_EQ("true", fmt::format(FMT_COMPILE("{}"), true));
EXPECT_EQ("x", fmt::format(FMT_COMPILE("{}"), 'x'));
EXPECT_EQ("4.2", fmt::format(FMT_COMPILE("{}"), 4.2));
EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), "foo"));
EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), std::string("foo")));
EXPECT_EQ("foo", fmt::format(FMT_COMPILE("{}"), test_formattable()));
auto t = std::chrono::system_clock::now();
EXPECT_EQ(fmt::format("{}", t), fmt::format(FMT_COMPILE("{}"), t));
# ifdef __cpp_lib_byte
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), std::byte{42}));
# endif
}
TEST(compile_test, format_wide_string) {
EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{}"), 42));
}
TEST(compile_test, format_specs) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
EXPECT_EQ("1.2 ms ",
fmt::format(FMT_COMPILE("{:7.1%Q %q}"),
std::chrono::duration<double, std::milli>(1.234)));
}
TEST(compile_test, dynamic_format_specs) {
EXPECT_EQ("foo ", fmt::format(FMT_COMPILE("{:{}}"), "foo", 5));
EXPECT_EQ(" 3.14", fmt::format(FMT_COMPILE("{:{}.{}f}"), 3.141592, 6, 2));
EXPECT_EQ(
"=1.234ms=",
fmt::format(FMT_COMPILE("{:=^{}.{}}"),
std::chrono::duration<double, std::milli>(1.234), 9, 3));
}
TEST(compile_test, manual_ordering) {
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{0}"), 42));
EXPECT_EQ(" -42", fmt::format(FMT_COMPILE("{0:4}"), -42));
EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{0} {1}"), 41, 43));
EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{1} {0}"), 43, 41));
EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{0} {2}"), 41, 42, 43));
EXPECT_EQ(" 41 43", fmt::format(FMT_COMPILE("{1:{2}} {0:4}"), 43, 41, 4));
EXPECT_EQ("42 1.2 ms ",
fmt::format(FMT_COMPILE("{0} {1:7.1%Q %q}"), 42,
std::chrono::duration<double, std::milli>(1.234)));
EXPECT_EQ(
"true 42 42 foo 0x1234 foo",
fmt::format(FMT_COMPILE("{0} {1} {2} {3} {4} {5}"), true, 42, 42.0f,
"foo", reinterpret_cast<void*>(0x1234), test_formattable()));
EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{0}"), 42));
}
TEST(compile_test, named) {
auto runtime_named_field_compiled =
fmt::detail::compile<decltype(fmt::arg("arg", 42))>(FMT_COMPILE("{arg}"));
static_assert(std::is_same_v<decltype(runtime_named_field_compiled),
fmt::detail::runtime_named_field<char>>);
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), fmt::arg("arg", 42)));
EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{} {}"), fmt::arg("arg", 41),
fmt::arg("arg", 43)));
EXPECT_EQ("foobar",
fmt::format(FMT_COMPILE("{a0}{a1}"), fmt::arg("a0", "foo"),
fmt::arg("a1", "bar")));
EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{}{a1}"), fmt::arg("a0", "foo"),
fmt::arg("a1", "bar")));
EXPECT_EQ("foofoo", fmt::format(FMT_COMPILE("{a0}{}"), fmt::arg("a0", "foo"),
fmt::arg("a1", "bar")));
EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{0}{a1}"), fmt::arg("a0", "foo"),
fmt::arg("a1", "bar")));
EXPECT_EQ("foobar", fmt::format(FMT_COMPILE("{a0}{1}"), fmt::arg("a0", "foo"),
fmt::arg("a1", "bar")));
EXPECT_EQ("foobar",
fmt::format(FMT_COMPILE("{}{a1}"), "foo", fmt::arg("a1", "bar")));
EXPECT_EQ("foobar",
fmt::format(FMT_COMPILE("{a0}{a1}"), fmt::arg("a1", "bar"),
fmt::arg("a2", "baz"), fmt::arg("a0", "foo")));
EXPECT_EQ(" bar foo ",
fmt::format(FMT_COMPILE(" {foo} {bar} "), fmt::arg("foo", "bar"),
fmt::arg("bar", "foo")));
EXPECT_THROW(fmt::format(FMT_COMPILE("{invalid}"), fmt::arg("valid", 42)),
fmt::format_error);
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
using namespace fmt::literals;
auto statically_named_field_compiled =
fmt::detail::compile<decltype("arg"_a = 42)>(FMT_COMPILE("{arg}"));
static_assert(std::is_same_v<decltype(statically_named_field_compiled),
fmt::detail::field<char, int, 0>>);
EXPECT_EQ("41 43",
fmt::format(FMT_COMPILE("{a0} {a1}"), "a0"_a = 41, "a1"_a = 43));
EXPECT_EQ("41 43",
fmt::format(FMT_COMPILE("{a1} {a0}"), "a0"_a = 43, "a1"_a = 41));
# endif
}
TEST(compile_test, join) {
unsigned char data[] = {0x1, 0x2, 0xaf};
EXPECT_EQ("0102af", fmt::format(FMT_COMPILE("{:02x}"), fmt::join(data, "")));
}
TEST(compile_test, format_to) {
char buf[8];
auto end = fmt::format_to(buf, FMT_COMPILE("{}"), 42);
*end = '\0';
EXPECT_STREQ("42", buf);
end = fmt::format_to(buf, FMT_COMPILE("{:x}"), 42);
*end = '\0';
EXPECT_STREQ("2a", buf);
}
TEST(compile_test, format_to_n) {
constexpr auto buffer_size = 8;
char buffer[buffer_size];
auto res = fmt::format_to_n(buffer, buffer_size, FMT_COMPILE("{}"), 42);
*res.out = '\0';
EXPECT_STREQ("42", buffer);
res = fmt::format_to_n(buffer, buffer_size, FMT_COMPILE("{:x}"), 42);
*res.out = '\0';
EXPECT_STREQ("2a", buffer);
}
# ifdef __cpp_lib_bit_cast
TEST(compile_test, constexpr_formatted_size) {
FMT_CONSTEXPR20 size_t size = fmt::formatted_size(FMT_COMPILE("{}"), 42);
EXPECT_EQ(size, 2);
FMT_CONSTEXPR20 size_t hex_size =
fmt::formatted_size(FMT_COMPILE("{:x}"), 15);
EXPECT_EQ(hex_size, 1);
FMT_CONSTEXPR20 size_t binary_size =
fmt::formatted_size(FMT_COMPILE("{:b}"), 15);
EXPECT_EQ(binary_size, 4);
FMT_CONSTEXPR20 size_t padded_size =
fmt::formatted_size(FMT_COMPILE("{:*^6}"), 42);
EXPECT_EQ(padded_size, 6);
FMT_CONSTEXPR20 size_t float_size =
fmt::formatted_size(FMT_COMPILE("{:.3}"), 12.345);
EXPECT_EQ(float_size, 4);
FMT_CONSTEXPR20 size_t str_size =
fmt::formatted_size(FMT_COMPILE("{:s}"), "abc");
EXPECT_EQ(str_size, 3);
}
# endif
TEST(compile_test, text_and_arg) {
EXPECT_EQ(">>>42<<<", fmt::format(FMT_COMPILE(">>>{}<<<"), 42));
EXPECT_EQ("42!", fmt::format(FMT_COMPILE("{}!"), 42));
}
TEST(compile_test, unknown_format_fallback) {
EXPECT_EQ(" 42 ",
fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42)));
std::vector<char> v;
fmt::format_to(std::back_inserter(v), FMT_COMPILE("{name:^4}"),
fmt::arg("name", 42));
EXPECT_EQ(" 42 ", fmt::string_view(v.data(), v.size()));
char buffer[4];
auto result = fmt::format_to_n(buffer, 4, FMT_COMPILE("{name:^5}"),
fmt::arg("name", 42));
EXPECT_EQ(5u, result.size);
EXPECT_EQ(buffer + 4, result.out);
EXPECT_EQ(" 42 ", fmt::string_view(buffer, 4));
}
TEST(compile_test, empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); }
struct to_stringable {
friend fmt::string_view to_string_view(to_stringable) { return {}; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<to_stringable> {
auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const to_stringable&, FormatContext& ctx) -> decltype(ctx.out()) {
return ctx.out();
}
};
FMT_END_NAMESPACE
TEST(compile_test, to_string_and_formatter) {
fmt::format(FMT_COMPILE("{}"), to_stringable());
}
TEST(compile_test, print) {
EXPECT_WRITE(stdout, fmt::print(FMT_COMPILE("Don't {}!"), "panic"),
"Don't panic!");
EXPECT_WRITE(stderr, fmt::print(stderr, FMT_COMPILE("Don't {}!"), "panic"),
"Don't panic!");
}
#endif
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
TEST(compile_test, compile_format_string_literal) {
using namespace fmt::literals;
EXPECT_EQ("", fmt::format(""_cf));
EXPECT_EQ("42", fmt::format("{}"_cf, 42));
EXPECT_EQ(L"42", fmt::format(L"{}"_cf, 42));
}
#endif
// MSVS 2019 19.29.30145.0 - Support C++20 and OK.
// MSVS 2022 19.32.31332.0 - compile-test.cc(362,3): fatal error C1001: Internal
// compiler error.
// (compiler file
// 'D:\a\_work\1\s\src\vctools\Compiler\CxxFE\sl\p1\c\constexpr\constexpr.cpp',
// line 8635)
#if ((FMT_CPLUSPLUS >= 202002L) && \
(!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9) && \
(!FMT_MSC_VERSION || FMT_MSC_VERSION < 1930)) || \
(FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002)
template <size_t max_string_length, typename Char = char> struct test_string {
template <typename T> constexpr bool operator==(const T& rhs) const noexcept {
return fmt::basic_string_view<Char>(rhs).compare(buffer) == 0;
}
Char buffer[max_string_length]{};
};
template <size_t max_string_length, typename Char = char, typename... Args>
consteval auto test_format(auto format, const Args&... args) {
test_string<max_string_length, Char> string{};
fmt::format_to(string.buffer, format, args...);
return string;
}
TEST(compile_time_formatting_test, bool) {
EXPECT_EQ("true", test_format<5>(FMT_COMPILE("{}"), true));
EXPECT_EQ("false", test_format<6>(FMT_COMPILE("{}"), false));
EXPECT_EQ("true ", test_format<6>(FMT_COMPILE("{:5}"), true));
EXPECT_EQ("1", test_format<2>(FMT_COMPILE("{:d}"), true));
}
TEST(compile_time_formatting_test, integer) {
EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), 42));
EXPECT_EQ("420", test_format<4>(FMT_COMPILE("{}"), 420));
EXPECT_EQ("42 42", test_format<6>(FMT_COMPILE("{} {}"), 42, 42));
EXPECT_EQ("42 42",
test_format<6>(FMT_COMPILE("{} {}"), uint32_t{42}, uint64_t{42}));
EXPECT_EQ("+42", test_format<4>(FMT_COMPILE("{:+}"), 42));
EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{:-}"), 42));
EXPECT_EQ(" 42", test_format<4>(FMT_COMPILE("{: }"), 42));
EXPECT_EQ("-0042", test_format<6>(FMT_COMPILE("{:05}"), -42));
EXPECT_EQ("101010", test_format<7>(FMT_COMPILE("{:b}"), 42));
EXPECT_EQ("0b101010", test_format<9>(FMT_COMPILE("{:#b}"), 42));
EXPECT_EQ("0B101010", test_format<9>(FMT_COMPILE("{:#B}"), 42));
EXPECT_EQ("042", test_format<4>(FMT_COMPILE("{:#o}"), 042));
EXPECT_EQ("0x4a", test_format<5>(FMT_COMPILE("{:#x}"), 0x4a));
EXPECT_EQ("0X4A", test_format<5>(FMT_COMPILE("{:#X}"), 0x4a));
EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42));
EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42ll));
EXPECT_EQ(" 42", test_format<6>(FMT_COMPILE("{:5}"), 42ull));
EXPECT_EQ("42 ", test_format<5>(FMT_COMPILE("{:<4}"), 42));
EXPECT_EQ(" 42", test_format<5>(FMT_COMPILE("{:>4}"), 42));
EXPECT_EQ(" 42 ", test_format<5>(FMT_COMPILE("{:^4}"), 42));
EXPECT_EQ("**-42", test_format<6>(FMT_COMPILE("{:*>5}"), -42));
}
TEST(compile_time_formatting_test, char) {
EXPECT_EQ("c", test_format<2>(FMT_COMPILE("{}"), 'c'));
EXPECT_EQ("c ", test_format<4>(FMT_COMPILE("{:3}"), 'c'));
EXPECT_EQ("99", test_format<3>(FMT_COMPILE("{:d}"), 'c'));
}
TEST(compile_time_formatting_test, string) {
EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), "42"));
EXPECT_EQ("The answer is 42",
test_format<17>(FMT_COMPILE("{} is {}"), "The answer", "42"));
EXPECT_EQ("abc**", test_format<6>(FMT_COMPILE("{:*<5}"), "abc"));
EXPECT_EQ("**🤡**", test_format<9>(FMT_COMPILE("{:*^6}"), "🤡"));
}
TEST(compile_time_formatting_test, combination) {
EXPECT_EQ("420, true, answer",
test_format<18>(FMT_COMPILE("{}, {}, {}"), 420, true, "answer"));
EXPECT_EQ(" -42", test_format<5>(FMT_COMPILE("{:{}}"), -42, 4));
}
TEST(compile_time_formatting_test, custom_type) {
EXPECT_EQ("foo", test_format<4>(FMT_COMPILE("{}"), test_formattable()));
EXPECT_EQ("bar", test_format<4>(FMT_COMPILE("{:b}"), test_formattable()));
}
TEST(compile_time_formatting_test, multibyte_fill) {
EXPECT_EQ("жж42", test_format<8>(FMT_COMPILE("{:ж>4}"), 42));
}
#endif

View File

@ -1,78 +0,0 @@
# Test if compile errors are produced where necessary.
cmake_minimum_required(VERSION 2.8)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../..)
set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG})
function (generate_source result fragment)
set(${result} "
#define FMT_HEADER_ONLY 1
#include \"fmt/posix.h\"
int main() {
${fragment}
}
" PARENT_SCOPE)
endfunction ()
function (expect_compile code)
generate_source(source "${code}")
check_cxx_source_compiles("${source}" compiles)
if (NOT compiles)
set(error_msg "Compile error for: ${code}")
endif ()
# Unset the CMake cache variable compiles. Otherwise the compile test will
# just use cached information next time it runs.
unset(compiles CACHE)
if (error_msg)
message(FATAL_ERROR ${error_msg})
endif ()
endfunction ()
function (expect_compile_error code)
generate_source(source "${code}")
check_cxx_source_compiles("${source}" compiles)
if (compiles)
set(error_msg "No compile error for: ${code}")
endif ()
# Unset the CMake cache variable compiles. Otherwise the compile test will
# just use cached information next time it runs.
unset(compiles CACHE)
if (error_msg)
message(FATAL_ERROR ${error_msg})
endif ()
endfunction ()
# check if the source file skeleton compiles
expect_compile("")
# MakeArg doesn't accept [const] volatile char *.
expect_compile_error("volatile char s[] = \"test\"; (fmt::internal::MakeArg<char>)(s);")
expect_compile_error("const volatile char s[] = \"test\"; (fmt::internal::MakeArg<char>)(s);")
# MakeArg<char> doesn't accept wchar_t.
expect_compile_error("fmt::internal::MakeValue<char>(L'a');")
expect_compile_error("fmt::internal::MakeValue<char>(L\"test\");")
# Writing a wide character to a character stream Writer is forbidden.
expect_compile_error("fmt::MemoryWriter() << L'a';")
expect_compile_error("fmt::MemoryWriter() << fmt::pad(\"abc\", 5, L' ');")
expect_compile_error("fmt::MemoryWriter() << fmt::pad(42, 5, L' ');")
# Formatting a wide character with a narrow format string is forbidden.
expect_compile_error("fmt::format(\"{}\", L'a';")
expect_compile("FMT_STATIC_ASSERT(true, \"this should never happen\");")
expect_compile_error("FMT_STATIC_ASSERT(0 > 1, \"oops\");")
# Make sure that compiler features detected in the header
# match the features detected in CMake.
if (SUPPORTS_USER_DEFINED_LITERALS)
set(supports_udl 1)
else ()
set(supports_udl 0)
endif ()
expect_compile("#if FMT_USE_USER_DEFINED_LITERALS != ${supports_udl}
# error
#endif")

View File

@ -1,94 +0,0 @@
/*
Tests of container utilities
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#include "fmt/container.h"
#include "gtest/gtest.h"
using fmt::internal::ContainerBuffer;
TEST(ContainerBufferTest, Empty) {
std::string data;
ContainerBuffer<std::string> buffer(data);
EXPECT_EQ(0u, buffer.size());
EXPECT_EQ(0u, buffer.capacity());
}
TEST(ContainerBufferTest, Reserve) {
std::string data;
ContainerBuffer<std::string> buffer(data);
std::size_t capacity = std::string().capacity() + 10;
buffer.reserve(capacity);
EXPECT_EQ(0u, buffer.size());
EXPECT_EQ(capacity, buffer.capacity());
}
TEST(ContainerBufferTest, Resize) {
std::string data;
ContainerBuffer<std::string> buffer(data);
std::size_t size = std::string().capacity() + 10;
buffer.resize(size);
EXPECT_EQ(size, buffer.size());
EXPECT_EQ(size, buffer.capacity());
}
TEST(ContainerBufferTest, Append) {
std::string data("Why so");
const std::string serious(" serious");
ContainerBuffer<std::string> buffer(data);
buffer.append(serious.c_str(), serious.c_str() + serious.length());
EXPECT_EQ("Why so serious", data);
EXPECT_EQ(data.length(), buffer.size());
}
TEST(BasicContainerWriterTest, String) {
std::string data;
fmt::BasicContainerWriter<std::string> out(data);
out << "The answer is " << 42 << "\n";
EXPECT_EQ("The answer is 42\n", data);
EXPECT_EQ(17u, out.size());
}
TEST(BasicContainerWriterTest, WString) {
std::wstring data;
fmt::BasicContainerWriter<std::wstring> out(data);
out << "The answer is " << 42 << "\n";
EXPECT_EQ(L"The answer is 42\n", data);
EXPECT_EQ(17u, out.size());
}
TEST(BasicContainerWriterTest, Vector) {
std::vector<char> data;
fmt::BasicContainerWriter<std::vector<char> > out(data);
out << "The answer is " << 42 << "\n";
EXPECT_EQ(17u, data.size());
EXPECT_EQ(out.size(), data.size());
}
TEST(BasicContainerWriterTest, StringAppend) {
std::string data("The");
fmt::BasicContainerWriter<std::string> out(data);
EXPECT_EQ(3u, data.size());
EXPECT_EQ(3u, out.size());
out << " answer is " << 42 << "\n";
EXPECT_EQ("The answer is 42\n", data);
EXPECT_EQ(17u, out.size());
}
TEST(BasicContainerWriterTest, VectorAppend) {
std::vector<char> data;
data.push_back('T');
data.push_back('h');
data.push_back('e');
fmt::BasicContainerWriter<std::vector<char> > out(data);
EXPECT_EQ(3u, data.size());
EXPECT_EQ(3u, out.size());
out << " answer is " << 42 << "\n";
EXPECT_EQ(17u, data.size());
EXPECT_EQ(17u, out.size());
}

858
test/core-test.cc Normal file
View File

@ -0,0 +1,858 @@
// Formatting library for C++ - core tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
// clang-format off
#include "test-assert.h"
// clang-format on
#include "fmt/core.h"
#include <algorithm> // std::copy_n
#include <climits> // INT_MAX
#include <cstring> // std::strlen
#include <functional> // std::equal_to
#include <iterator> // std::back_insert_iterator
#include <limits> // std::numeric_limits
#include <string> // std::string
#include <type_traits> // std::is_same
#include "gmock/gmock.h"
using fmt::string_view;
using fmt::detail::buffer;
using testing::_;
using testing::Invoke;
using testing::Return;
#ifdef FMT_FORMAT_H_
# error core-test includes format.h
#endif
TEST(string_view_test, value_type) {
static_assert(std::is_same<string_view::value_type, char>::value, "");
}
TEST(string_view_test, ctor) {
EXPECT_STREQ("abc", fmt::string_view("abc").data());
EXPECT_EQ(3u, fmt::string_view("abc").size());
EXPECT_STREQ("defg", fmt::string_view(std::string("defg")).data());
EXPECT_EQ(4u, fmt::string_view(std::string("defg")).size());
}
TEST(string_view_test, length) {
// Test that string_view::size() returns string length, not buffer size.
char str[100] = "some string";
EXPECT_EQ(std::strlen(str), string_view(str).size());
EXPECT_LT(std::strlen(str), sizeof(str));
}
// Check string_view's comparison operator.
template <template <typename> class Op> void check_op() {
const char* inputs[] = {"foo", "fop", "fo"};
size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
for (size_t i = 0; i < num_inputs; ++i) {
for (size_t j = 0; j < num_inputs; ++j) {
string_view lhs(inputs[i]), rhs(inputs[j]);
EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs));
}
}
}
TEST(string_view_test, compare) {
EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0);
EXPECT_GT(string_view("fop").compare(string_view("foo")), 0);
EXPECT_LT(string_view("foo").compare(string_view("fop")), 0);
EXPECT_GT(string_view("foo").compare(string_view("fo")), 0);
EXPECT_LT(string_view("fo").compare(string_view("foo")), 0);
EXPECT_TRUE(string_view("foo").starts_with('f'));
EXPECT_FALSE(string_view("foo").starts_with('o'));
EXPECT_FALSE(string_view().starts_with('o'));
EXPECT_TRUE(string_view("foo").starts_with("fo"));
EXPECT_TRUE(string_view("foo").starts_with("foo"));
EXPECT_FALSE(string_view("foo").starts_with("fooo"));
EXPECT_FALSE(string_view().starts_with("fooo"));
check_op<std::equal_to>();
check_op<std::not_equal_to>();
check_op<std::less>();
check_op<std::less_equal>();
check_op<std::greater>();
check_op<std::greater_equal>();
}
TEST(core_test, is_output_iterator) {
EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value));
EXPECT_TRUE(
(fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>,
char>::value));
EXPECT_TRUE(
(fmt::detail::is_output_iterator<std::string::iterator, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator,
char>::value));
}
TEST(core_test, buffer_appender) {
// back_insert_iterator is not default-constructible before C++20, so
// buffer_appender can only be default-constructible when back_insert_iterator
// is.
static_assert(
std::is_default_constructible<
std::back_insert_iterator<fmt::detail::buffer<char>>>::value ==
std::is_default_constructible<
fmt::detail::buffer_appender<char>>::value,
"");
#ifdef __cpp_lib_ranges
static_assert(std::output_iterator<fmt::detail::buffer_appender<char>, char>);
#endif
}
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
TEST(buffer_test, noncopyable) {
EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value);
# if !FMT_MSC_VERSION
// std::is_copy_assignable is broken in MSVC2013.
EXPECT_FALSE(std::is_copy_assignable<buffer<char>>::value);
# endif
}
TEST(buffer_test, nonmoveable) {
EXPECT_FALSE(std::is_move_constructible<buffer<char>>::value);
# if !FMT_MSC_VERSION
// std::is_move_assignable is broken in MSVC2013.
EXPECT_FALSE(std::is_move_assignable<buffer<char>>::value);
# endif
}
#endif
TEST(buffer_test, indestructible) {
static_assert(!std::is_destructible<fmt::detail::buffer<int>>(),
"buffer's destructor is protected");
}
template <typename T> struct mock_buffer final : buffer<T> {
MOCK_METHOD(size_t, do_grow, (size_t));
void grow(size_t capacity) override {
this->set(this->data(), do_grow(capacity));
}
mock_buffer(T* data = nullptr, size_t buf_capacity = 0) {
this->set(data, buf_capacity);
ON_CALL(*this, do_grow(_)).WillByDefault(Invoke([](size_t capacity) {
return capacity;
}));
}
};
TEST(buffer_test, ctor) {
{
mock_buffer<int> buffer;
EXPECT_EQ(nullptr, buffer.data());
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
}
{
int dummy;
mock_buffer<int> buffer(&dummy);
EXPECT_EQ(&dummy, &buffer[0]);
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
}
{
int dummy;
size_t capacity = std::numeric_limits<size_t>::max();
mock_buffer<int> buffer(&dummy, capacity);
EXPECT_EQ(&dummy, &buffer[0]);
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
EXPECT_EQ(capacity, buffer.capacity());
}
}
TEST(buffer_test, access) {
char data[10];
mock_buffer<char> buffer(data, sizeof(data));
buffer[0] = 11;
EXPECT_EQ(11, buffer[0]);
buffer[3] = 42;
EXPECT_EQ(42, *(&buffer[0] + 3));
const fmt::detail::buffer<char>& const_buffer = buffer;
EXPECT_EQ(42, const_buffer[3]);
}
TEST(buffer_test, try_resize) {
char data[123];
mock_buffer<char> buffer(data, sizeof(data));
buffer[10] = 42;
EXPECT_EQ(42, buffer[10]);
buffer.try_resize(20);
EXPECT_EQ(20u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
buffer.try_resize(5);
EXPECT_EQ(5u, buffer.size());
EXPECT_EQ(123u, buffer.capacity());
EXPECT_EQ(42, buffer[10]);
// Check if try_resize calls grow.
EXPECT_CALL(buffer, do_grow(124));
buffer.try_resize(124);
EXPECT_CALL(buffer, do_grow(200));
buffer.try_resize(200);
}
TEST(buffer_test, try_resize_partial) {
char data[10];
mock_buffer<char> buffer(data, sizeof(data));
EXPECT_CALL(buffer, do_grow(20)).WillOnce(Return(15));
buffer.try_resize(20);
EXPECT_EQ(buffer.capacity(), 15);
EXPECT_EQ(buffer.size(), 15);
}
TEST(buffer_test, clear) {
mock_buffer<char> buffer;
EXPECT_CALL(buffer, do_grow(20));
buffer.try_resize(20);
buffer.try_resize(0);
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
EXPECT_EQ(20u, buffer.capacity());
}
TEST(buffer_test, append) {
char data[15];
mock_buffer<char> buffer(data, 10);
auto test = "test";
buffer.append(test, test + 5);
EXPECT_STREQ(test, &buffer[0]);
EXPECT_EQ(5u, buffer.size());
buffer.try_resize(10);
EXPECT_CALL(buffer, do_grow(12));
buffer.append(test, test + 2);
EXPECT_EQ('t', buffer[10]);
EXPECT_EQ('e', buffer[11]);
EXPECT_EQ(12u, buffer.size());
}
TEST(buffer_test, append_partial) {
char data[10];
mock_buffer<char> buffer(data, sizeof(data));
testing::InSequence seq;
EXPECT_CALL(buffer, do_grow(15)).WillOnce(Return(10));
EXPECT_CALL(buffer, do_grow(15)).WillOnce(Invoke([&buffer](size_t) {
EXPECT_EQ(fmt::string_view(buffer.data(), buffer.size()), "0123456789");
buffer.clear();
return 10;
}));
auto test = "0123456789abcde";
buffer.append(test, test + 15);
}
TEST(buffer_test, append_allocates_enough_storage) {
char data[19];
mock_buffer<char> buffer(data, 10);
auto test = "abcdefgh";
buffer.try_resize(10);
EXPECT_CALL(buffer, do_grow(19));
buffer.append(test, test + 9);
}
struct custom_context {
using char_type = char;
using parse_context_type = fmt::format_parse_context;
bool called = false;
template <typename T> struct formatter_type {
FMT_CONSTEXPR auto parse(fmt::format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
const char* format(const T&, custom_context& ctx) {
ctx.called = true;
return nullptr;
}
};
void advance_to(const char*) {}
};
struct test_struct {};
FMT_BEGIN_NAMESPACE
template <typename Char> struct formatter<test_struct, Char> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(test_struct, format_context& ctx) const -> decltype(ctx.out()) {
auto test = string_view("test");
return std::copy_n(test.data(), test.size(), ctx.out());
}
};
FMT_END_NAMESPACE
TEST(arg_test, format_args) {
auto args = fmt::format_args();
EXPECT_FALSE(args.get(1));
}
TEST(arg_test, make_value_with_custom_context) {
auto t = test_struct();
auto arg = fmt::detail::value<custom_context>(
fmt::detail::arg_mapper<custom_context>().map(t));
auto ctx = custom_context();
auto parse_ctx = fmt::format_parse_context("");
arg.custom.format(&t, parse_ctx, ctx);
EXPECT_TRUE(ctx.called);
}
// Use a unique result type to make sure that there are no undesirable
// conversions.
struct test_result {};
template <typename T> struct mock_visitor {
template <typename U> struct result { using type = test_result; };
mock_visitor() {
ON_CALL(*this, visit(_)).WillByDefault(Return(test_result()));
}
MOCK_METHOD(test_result, visit, (T));
MOCK_METHOD(void, unexpected, ());
auto operator()(T value) -> test_result { return visit(value); }
template <typename U> auto operator()(U) -> test_result {
unexpected();
return test_result();
}
};
template <typename T> struct visit_type { using type = T; };
#define VISIT_TYPE(type_, visit_type_) \
template <> struct visit_type<type_> { using type = visit_type_; }
VISIT_TYPE(signed char, int);
VISIT_TYPE(unsigned char, unsigned);
VISIT_TYPE(short, int);
VISIT_TYPE(unsigned short, unsigned);
#if LONG_MAX == INT_MAX
VISIT_TYPE(long, int);
VISIT_TYPE(unsigned long, unsigned);
#else
VISIT_TYPE(long, long long);
VISIT_TYPE(unsigned long, unsigned long long);
#endif
#define CHECK_ARG(Char, expected, value) \
{ \
testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \
EXPECT_CALL(visitor, visit(expected)); \
using iterator = std::back_insert_iterator<buffer<Char>>; \
auto var = value; \
fmt::visit_format_arg( \
visitor, \
fmt::detail::make_arg<fmt::basic_format_context<iterator, Char>>( \
var)); \
}
#define CHECK_ARG_SIMPLE(value) \
{ \
using value_type = decltype(value); \
typename visit_type<value_type>::type expected = value; \
CHECK_ARG(char, expected, value) \
CHECK_ARG(wchar_t, expected, value) \
}
template <typename T> class numeric_arg_test : public testing::Test {};
using test_types =
testing::Types<bool, signed char, unsigned char, short, unsigned short, int,
unsigned, long, unsigned long, long long, unsigned long long,
float, double, long double>;
TYPED_TEST_SUITE(numeric_arg_test, test_types);
template <typename T, fmt::enable_if_t<std::is_integral<T>::value, int> = 0>
auto test_value() -> T {
return static_cast<T>(42);
}
template <typename T,
fmt::enable_if_t<std::is_floating_point<T>::value, int> = 0>
auto test_value() -> T {
return static_cast<T>(4.2);
}
TYPED_TEST(numeric_arg_test, make_and_visit) {
CHECK_ARG_SIMPLE(test_value<TypeParam>());
CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::min());
CHECK_ARG_SIMPLE(std::numeric_limits<TypeParam>::max());
}
TEST(arg_test, char_arg) { CHECK_ARG(char, 'a', 'a'); }
TEST(arg_test, string_arg) {
char str_data[] = "test";
char* str = str_data;
const char* cstr = str;
CHECK_ARG(char, cstr, str);
auto sv = fmt::string_view(str);
CHECK_ARG(char, sv, std::string(str));
}
TEST(arg_test, wstring_arg) {
wchar_t str_data[] = L"test";
wchar_t* str = str_data;
const wchar_t* cstr = str;
auto sv = fmt::basic_string_view<wchar_t>(str);
CHECK_ARG(wchar_t, cstr, str);
CHECK_ARG(wchar_t, cstr, cstr);
CHECK_ARG(wchar_t, sv, std::wstring(str));
CHECK_ARG(wchar_t, sv, fmt::basic_string_view<wchar_t>(str));
}
TEST(arg_test, pointer_arg) {
void* p = nullptr;
const void* cp = nullptr;
CHECK_ARG(char, cp, p);
CHECK_ARG(wchar_t, cp, p);
CHECK_ARG_SIMPLE(cp);
}
struct check_custom {
auto operator()(fmt::basic_format_arg<fmt::format_context>::handle h) const
-> test_result {
struct test_buffer final : fmt::detail::buffer<char> {
char data[10];
test_buffer() : fmt::detail::buffer<char>(data, 0, 10) {}
void grow(size_t) override {}
} buffer;
auto parse_ctx = fmt::format_parse_context("");
auto ctx = fmt::format_context(fmt::detail::buffer_appender<char>(buffer),
fmt::format_args());
h.format(parse_ctx, ctx);
EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
return test_result();
}
};
TEST(arg_test, custom_arg) {
auto test = test_struct();
using visitor =
mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>;
auto&& v = testing::StrictMock<visitor>();
EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom()));
fmt::visit_format_arg(v, fmt::detail::make_arg<fmt::format_context>(test));
}
TEST(arg_test, visit_invalid_arg) {
auto&& visitor = testing::StrictMock<mock_visitor<fmt::monostate>>();
EXPECT_CALL(visitor, visit(_));
auto arg = fmt::basic_format_arg<fmt::format_context>();
fmt::visit_format_arg(visitor, arg);
}
#if FMT_USE_CONSTEXPR
enum class arg_id_result { none, empty, index, name };
struct test_arg_id_handler {
arg_id_result res = arg_id_result::none;
int index = 0;
string_view name;
constexpr void on_auto() { res = arg_id_result::empty; }
constexpr void on_index(int i) {
res = arg_id_result::index;
index = i;
}
constexpr void on_name(string_view n) {
res = arg_id_result::name;
name = n;
}
};
template <size_t N>
constexpr test_arg_id_handler parse_arg_id(const char (&s)[N]) {
auto h = test_arg_id_handler();
fmt::detail::parse_arg_id(s, s + N, h);
return h;
}
TEST(core_test, constexpr_parse_arg_id) {
static_assert(parse_arg_id(":").res == arg_id_result::empty, "");
static_assert(parse_arg_id("}").res == arg_id_result::empty, "");
static_assert(parse_arg_id("42:").res == arg_id_result::index, "");
static_assert(parse_arg_id("42:").index == 42, "");
static_assert(parse_arg_id("foo:").res == arg_id_result::name, "");
static_assert(parse_arg_id("foo:").name.size() == 3, "");
}
template <size_t N> constexpr auto parse_test_specs(const char (&s)[N]) {
auto ctx = fmt::detail::compile_parse_context<char>(fmt::string_view(s, N),
43, nullptr);
auto specs = fmt::detail::dynamic_format_specs<>();
fmt::detail::parse_format_specs(s, s + N - 1, specs, ctx,
fmt::detail::type::float_type);
return specs;
}
TEST(core_test, constexpr_parse_format_specs) {
static_assert(parse_test_specs("<").align == fmt::align::left, "");
static_assert(parse_test_specs("*^").fill[0] == '*', "");
static_assert(parse_test_specs("+").sign == fmt::sign::plus, "");
static_assert(parse_test_specs("-").sign == fmt::sign::minus, "");
static_assert(parse_test_specs(" ").sign == fmt::sign::space, "");
static_assert(parse_test_specs("#").alt, "");
static_assert(parse_test_specs("0").align == fmt::align::numeric, "");
static_assert(parse_test_specs("L").localized, "");
static_assert(parse_test_specs("42").width == 42, "");
static_assert(parse_test_specs("{42}").width_ref.val.index == 42, "");
static_assert(parse_test_specs(".42").precision == 42, "");
static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, "");
static_assert(
parse_test_specs("f").type == fmt::presentation_type::fixed_lower, "");
}
struct test_format_string_handler {
constexpr void on_text(const char*, const char*) {}
constexpr auto on_arg_id() -> int { return 0; }
template <typename T> constexpr auto on_arg_id(T) -> int { return 0; }
constexpr void on_replacement_field(int, const char*) {}
constexpr auto on_format_specs(int, const char* begin, const char*) -> const
char* {
return begin;
}
constexpr void on_error(const char*) { error = true; }
bool error = false;
};
template <size_t N> constexpr bool parse_string(const char (&s)[N]) {
auto h = test_format_string_handler();
fmt::detail::parse_format_string<true>(fmt::string_view(s, N - 1), h);
return !h.error;
}
TEST(core_test, constexpr_parse_format_string) {
static_assert(parse_string("foo"), "");
static_assert(!parse_string("}"), "");
static_assert(parse_string("{}"), "");
static_assert(parse_string("{42}"), "");
static_assert(parse_string("{foo}"), "");
static_assert(parse_string("{:}"), "");
}
#endif // FMT_USE_CONSTEXPR
struct enabled_formatter {};
struct enabled_ptr_formatter {};
struct disabled_formatter {};
struct disabled_formatter_convertible {
operator int() const { return 42; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<enabled_formatter> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(enabled_formatter, format_context& ctx) const
-> decltype(ctx.out()) {
return ctx.out();
}
};
template <> struct formatter<enabled_ptr_formatter*> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(enabled_ptr_formatter*, format_context& ctx) const
-> decltype(ctx.out()) {
return ctx.out();
}
};
FMT_END_NAMESPACE
TEST(core_test, has_formatter) {
using fmt::has_formatter;
using context = fmt::format_context;
static_assert(has_formatter<enabled_formatter, context>::value, "");
static_assert(!has_formatter<disabled_formatter, context>::value, "");
static_assert(!has_formatter<disabled_formatter_convertible, context>::value,
"");
}
struct const_formattable {};
struct nonconst_formattable {};
FMT_BEGIN_NAMESPACE
template <> struct formatter<const_formattable> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(const const_formattable&, format_context& ctx)
-> decltype(ctx.out()) {
auto test = string_view("test");
return std::copy_n(test.data(), test.size(), ctx.out());
}
};
template <> struct formatter<nonconst_formattable> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(nonconst_formattable&, format_context& ctx)
-> decltype(ctx.out()) {
auto test = string_view("test");
return std::copy_n(test.data(), test.size(), ctx.out());
}
};
FMT_END_NAMESPACE
struct convertible_to_pointer {
operator const int*() const { return nullptr; }
};
struct convertible_to_pointer_formattable {
operator const int*() const { return nullptr; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<convertible_to_pointer_formattable> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(convertible_to_pointer_formattable, format_context& ctx) const
-> decltype(ctx.out()) {
auto test = string_view("test");
return std::copy_n(test.data(), test.size(), ctx.out());
}
};
FMT_END_NAMESPACE
enum class unformattable_scoped_enum {};
TEST(core_test, is_formattable) {
static_assert(!fmt::is_formattable<wchar_t>::value, "");
#ifdef __cpp_char8_t
static_assert(!fmt::is_formattable<char8_t>::value, "");
#endif
static_assert(!fmt::is_formattable<char16_t>::value, "");
static_assert(!fmt::is_formattable<char32_t>::value, "");
static_assert(!fmt::is_formattable<signed char*>::value, "");
static_assert(!fmt::is_formattable<unsigned char*>::value, "");
static_assert(!fmt::is_formattable<const signed char*>::value, "");
static_assert(!fmt::is_formattable<const unsigned char*>::value, "");
static_assert(!fmt::is_formattable<const wchar_t*>::value, "");
static_assert(!fmt::is_formattable<const wchar_t[3]>::value, "");
static_assert(!fmt::is_formattable<fmt::basic_string_view<wchar_t>>::value,
"");
static_assert(fmt::is_formattable<enabled_formatter>::value, "");
static_assert(!fmt::is_formattable<enabled_ptr_formatter*>::value, "");
static_assert(!fmt::is_formattable<disabled_formatter>::value, "");
static_assert(!fmt::is_formattable<disabled_formatter_convertible>::value,
"");
static_assert(fmt::is_formattable<const_formattable&>::value, "");
static_assert(fmt::is_formattable<const const_formattable&>::value, "");
static_assert(fmt::is_formattable<nonconst_formattable&>::value, "");
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
static_assert(!fmt::is_formattable<const nonconst_formattable&>::value, "");
#endif
static_assert(!fmt::is_formattable<convertible_to_pointer>::value, "");
const auto f = convertible_to_pointer_formattable();
EXPECT_EQ(fmt::format("{}", f), "test");
static_assert(!fmt::is_formattable<void (*)()>::value, "");
struct s;
static_assert(!fmt::is_formattable<int(s::*)>::value, "");
static_assert(!fmt::is_formattable<int (s::*)()>::value, "");
static_assert(!fmt::is_formattable<unformattable_scoped_enum>::value, "");
static_assert(!fmt::is_formattable<unformattable_scoped_enum>::value, "");
}
TEST(core_test, format) { EXPECT_EQ(fmt::format("{}", 42), "42"); }
TEST(core_test, format_to) {
auto s = std::string();
fmt::format_to(std::back_inserter(s), "{}", 42);
EXPECT_EQ(s, "42");
}
#ifdef __cpp_lib_byte
TEST(core_test, format_byte) {
EXPECT_EQ(fmt::format("{}", std::byte(42)), "42");
}
#endif
struct convertible_to_int {
operator int() const { return 42; }
};
struct convertible_to_cstring {
operator const char*() const { return "foo"; }
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<convertible_to_int> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(convertible_to_int, format_context& ctx) const
-> decltype(ctx.out()) {
return std::copy_n("foo", 3, ctx.out());
}
};
template <> struct formatter<convertible_to_cstring> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(convertible_to_cstring, format_context& ctx) const
-> decltype(ctx.out()) {
return std::copy_n("bar", 3, ctx.out());
}
};
FMT_END_NAMESPACE
TEST(core_test, formatter_overrides_implicit_conversion) {
EXPECT_EQ(fmt::format("{}", convertible_to_int()), "foo");
EXPECT_EQ(fmt::format("{}", convertible_to_cstring()), "bar");
}
// Test that check is not found by ADL.
template <typename T> void check(T);
TEST(core_test, adl_check) {
EXPECT_EQ(fmt::format("{}", test_struct()), "test");
}
struct implicitly_convertible_to_string_view {
operator fmt::string_view() const { return "foo"; }
};
TEST(core_test, no_implicit_conversion_to_string_view) {
EXPECT_FALSE(
fmt::is_formattable<implicitly_convertible_to_string_view>::value);
}
#ifdef FMT_USE_STRING_VIEW
struct implicitly_convertible_to_std_string_view {
operator std::string_view() const { return "foo"; }
};
TEST(core_test, no_implicit_conversion_to_std_string_view) {
EXPECT_FALSE(
fmt::is_formattable<implicitly_convertible_to_std_string_view>::value);
}
#endif
// std::is_constructible is broken in MSVC until version 2015.
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1900
struct explicitly_convertible_to_string_view {
explicit operator fmt::string_view() const { return "foo"; }
};
TEST(core_test, format_explicitly_convertible_to_string_view) {
// Types explicitly convertible to string_view are not formattable by
// default because it may introduce ODR violations.
static_assert(
!fmt::is_formattable<explicitly_convertible_to_string_view>::value, "");
}
# ifdef FMT_USE_STRING_VIEW
struct explicitly_convertible_to_std_string_view {
explicit operator std::string_view() const { return "foo"; }
};
TEST(core_test, format_explicitly_convertible_to_std_string_view) {
// Types explicitly convertible to string_view are not formattable by
// default because it may introduce ODR violations.
static_assert(
!fmt::is_formattable<explicitly_convertible_to_std_string_view>::value,
"");
}
# endif
#endif
namespace adl_test {
template <typename... T> void make_format_args(const T&...) = delete;
struct string : std::string {};
} // namespace adl_test
// Test that formatting functions compile when make_format_args is found by ADL.
TEST(core_test, adl) {
// Only check compilation and don't run the code to avoid polluting the output
// and since the output is tested elsewhere.
if (fmt::detail::const_check(true)) return;
auto s = adl_test::string();
char buf[10];
(void)fmt::format("{}", s);
fmt::format_to(buf, "{}", s);
fmt::format_to_n(buf, 10, "{}", s);
(void)fmt::formatted_size("{}", s);
fmt::print("{}", s);
fmt::print(stdout, "{}", s);
}
TEST(core_test, has_const_formatter) {
EXPECT_TRUE((fmt::detail::has_const_formatter<const_formattable,
fmt::format_context>()));
EXPECT_FALSE((fmt::detail::has_const_formatter<nonconst_formattable,
fmt::format_context>()));
}
TEST(core_test, format_nonconst) {
EXPECT_EQ(fmt::format("{}", nonconst_formattable()), "test");
}
struct its_a_trap {
template <typename T> operator T() const {
auto v = T();
v.x = 42;
return v;
}
};
FMT_BEGIN_NAMESPACE
template <> struct formatter<its_a_trap> {
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
auto format(its_a_trap, format_context& ctx) const -> decltype(ctx.out()) {
auto s = string_view("42");
return std::copy(s.begin(), s.end(), ctx.out());
}
};
FMT_END_NAMESPACE
TEST(core_test, trappy_conversion) {
EXPECT_EQ(fmt::format("{}", its_a_trap()), "42");
}

View File

@ -0,0 +1,73 @@
# We can find some usecases which follow the guide of CMake which uses
# `enable_language(CUDA)` instead of `find_package(CUDA)` and let the CMake
# built-in functions use NVCC.
# See: https://cmake.org/cmake/help/latest/module/FindCUDA.html#replacement
#
# However, this requires CMake version 3.10 or higher and we can't be sure most
# of the CUDA projects are using those.
#
# This test relies on `find_package(CUDA)` in the parent CMake config.
# These can be updated when NVCC becomes ready for C++ 17 features
# https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cpp14-language-features
set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_CUDA_STANDARD_REQUIRED 14)
# In this test, we assume that the user is going to compile CUDA source code
# with some libraries (fmt in this case).
#
# In addition to that, this test invokes both the C++ host compiler and NVCC
# by providing another (non-CUDA) C++ source code.
if (${CMAKE_VERSION} VERSION_LESS 3.15)
# https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html
list(APPEND CUDA_NVCC_FLAGS "-std=c++14")
if (MSVC)
# This is the solution of pytorch:
# https://github.com/pytorch/pytorch/pull/7118
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "/std:c++14")
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "/Zc:__cplusplus")
# for the reason of this -Xcompiler options, see below.
endif ()
cuda_add_executable(fmt-in-cuda-test cuda-cpp14.cu cpp14.cc)
target_compile_features(fmt-in-cuda-test PRIVATE cxx_std_14)
if (MSVC)
# This part is for (non-CUDA) C++ code. MSVC can define incorrect
# `__cplusplus` macro. Fix for the issue is to use additional compiler flag.
#
# See Also:
# https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
# https://github.com/Microsoft/vscode-cpptools/issues/2595
target_compile_options(fmt-in-cuda-test PRIVATE /Zc:__cplusplus /permissive-)
endif ()
else()
# now using a "new" way of handling CUDA
add_executable(fmt-in-cuda-test cuda-cpp14.cu cpp14.cc)
set_target_properties(fmt-in-cuda-test PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_compile_features(fmt-in-cuda-test PRIVATE cxx_std_14)
if (MSVC)
# with MSVC, 'cxx_std_14' will only propagate to the host code (MSVC), but will
# not set __cplusplus correctly anyway, while nvcc will ignore it.
# If specified for nvcc on the command line as '-std=c++14' nvcc will emit this
# message instead:
# nvcc warning : The -std=c++14 flag is not supported with the configured host
# compiler. Flag will be ignored.
set_property(SOURCE cuda-cpp14.cu APPEND PROPERTY
COMPILE_OPTIONS -Xcompiler /std:c++14 -Xcompiler /Zc:__cplusplus)
set_property(SOURCE cpp14.cc APPEND PROPERTY
COMPILE_OPTIONS /std:c++14 /Zc:__cplusplus)
endif()
endif()
get_target_property(IN_USE_CUDA_STANDARD fmt-in-cuda-test CUDA_STANDARD)
message(STATUS "cuda_standard: ${IN_USE_CUDA_STANDARD}")
get_target_property(IN_USE_CUDA_STANDARD_REQUIRED
fmt-in-cuda-test CUDA_STANDARD_REQUIRED)
message(STATUS "cuda_standard_required: ${IN_USE_CUDA_STANDARD_REQUIRED}")
# We don't use PUBLIC or other keyword for reasons explained in the
# CUDA_LINK_LIBRARIES_KEYWORD section in
# https://cmake.org/cmake/help/latest/module/FindCUDA.html
target_link_libraries(fmt-in-cuda-test fmt::fmt)

Some files were not shown because too many files have changed in this diff Show More