diff --git a/CMakeLists.txt b/CMakeLists.txt index eb29eb2a..23de5969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,7 +133,7 @@ endfunction() # Define the fmt library, its includes and the needed defines. add_headers(FMT_HEADERS core.h format.h format-inl.h locale.h ostream.h printf.h - time.h) + time.h ranges.h) set(FMT_SOURCES src/format.cc) if (HAVE_OPEN) add_headers(FMT_HEADERS posix.h) diff --git a/ChangeLog.rst b/ChangeLog.rst index 4e1356a3..8cd24414 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -52,6 +52,27 @@ :12:45: error: expression '' is not a constant expression throw format_error("invalid specifier"); +* Added `iterator support + `_: + + .. code:: c++ + + #include + #include + + std::vector out; + fmt::format_to(std::back_inserter(out), "{}", 42); + +* Added the `formatted_size + `_ function for + computing output size: + + .. code:: c++ + + #include + + auto size = fmt::formatted_size("{}", 12345); // size == 5 + * Improved compile times by reducing dependencies on standard headers and providing a lightweight `core API `_: @@ -94,6 +115,19 @@ in the format API and provided ``fmt::string_view`` which implements a subset of ``std::string_view`` API for pre-C++17 systems. +* Added support for ``std::experimental::string_view`` + (`#607 `_): + + .. code:: c++ + + #include + #include + + fmt::print("{}", std::experimental::string_view("foo")); + + Thanks `@virgiliofornazin (Virgilio Alexandre Fornazin) + `_. + * Allowed mixing named and automatic arguments: .. code:: c++ diff --git a/doc/api.rst b/doc/api.rst index b65a8fc6..0eeab744 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -151,6 +151,8 @@ The following user-defined literals are defined in ``fmt/format.h``. Utilities --------- +.. doxygenfunction:: fmt::formatted_size(string_view, const Args&...) + .. doxygenfunction:: fmt::to_string(const T&) .. doxygenfunction:: fmt::to_wstring(const T&) diff --git a/include/fmt/core.h b/include/fmt/core.h index e8a6f615..7941ece0 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -73,7 +73,8 @@ # endif #endif -#if FMT_HAS_FEATURE(cxx_explicit_conversions) +#if FMT_HAS_FEATURE(cxx_explicit_conversions) || \ + FMT_MSC_VER >= 1800 # define FMT_EXPLICIT explicit #else # define FMT_EXPLICIT @@ -199,13 +200,11 @@ typename std::add_rvalue_reference::type declval() FMT_NOEXCEPT; } /** - \rst An implementation of ``std::basic_string_view`` for pre-C++17. It provides a subset of the API. ``fmt::basic_string_view`` is used for format strings even if ``std::string_view`` is available to prevent issues when a library is compiled with a different ``-std`` option than the client code (which is not recommended). - \endrst */ template class basic_string_view { @@ -244,11 +243,7 @@ class basic_string_view { basic_string_view(const Char *s) : data_(s), size_(std::char_traits::length(s)) {} - /** - \rst - Constructs a string reference from a ``std::basic_string`` object. - \endrst - */ + /** Constructs a string reference from a ``std::basic_string`` object. */ template FMT_CONSTEXPR basic_string_view( const std::basic_string &s) FMT_NOEXCEPT @@ -335,11 +330,7 @@ class basic_buffer { capacity_ = capacity; } - /** - \rst - Increases the buffer capacity to hold at least *capacity* elements. - \endrst - */ + /** Increases the buffer capacity to hold at least *capacity* elements. */ virtual void grow(std::size_t capacity) = 0; public: @@ -371,11 +362,7 @@ class basic_buffer { size_ = new_size; } - /** - \rst - Reserves space to store at least *capacity* elements. - \endrst - */ + /** Reserves space to store at least *capacity* elements. */ void reserve(std::size_t capacity) { if (capacity > capacity_) grow(capacity); @@ -910,10 +897,8 @@ class basic_format_context : using typename base::iterator; /** - \rst Constructs a ``basic_format_context`` object. References to the arguments are stored in the object so make sure they have appropriate lifetimes. - \endrst */ basic_format_context(OutputIt out, basic_string_view format_str, basic_format_args args) @@ -997,8 +982,17 @@ class format_arg_store { friend class basic_format_args; + static FMT_CONSTEXPR uint64_t get_types() { + return IS_PACKED ? internal::get_types() + : -static_cast(NUM_ARGS); + } + public: +#if FMT_USE_CONSTEXPR + static constexpr uint64_t TYPES = get_types(); +#else static const uint64_t TYPES; +#endif #if FMT_GCC_VERSION && FMT_GCC_VERSION <= 405 // Workaround an array initialization bug in gcc 4.5 and earlier. @@ -1011,10 +1005,10 @@ class format_arg_store { #endif }; +#if !FMT_USE_CONSTEXPR template -const uint64_t format_arg_store::TYPES = IS_PACKED ? - internal::get_types() : - -static_cast(NUM_ARGS); +const uint64_t format_arg_store::TYPES = get_types(); +#endif /** \rst diff --git a/include/fmt/format.h b/include/fmt/format.h index 75ca3a17..a058e513 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1395,13 +1395,13 @@ class float_type_checker : private ErrorHandler { } }; -template +template class char_specs_checker : public ErrorHandler { private: - char type_; + CharType type_; public: - FMT_CONSTEXPR char_specs_checker(char type, ErrorHandler eh) + FMT_CONSTEXPR char_specs_checker(CharType type, ErrorHandler eh) : ErrorHandler(eh), type_(type) {} FMT_CONSTEXPR void on_int() { @@ -3138,8 +3138,10 @@ struct formatter< type_spec, internal::int_type_checker(eh)); break; case internal::char_type: - handle_char_specs(specs_, internal::char_specs_checker( - static_cast(type_spec), eh)); + handle_char_specs( + specs_, + internal::char_specs_checker( + type_spec, eh)); break; case internal::double_type: case internal::long_double_type: @@ -3419,9 +3421,7 @@ std::string to_string(const T &value) { } /** - \rst Converts *value* to ``std::wstring`` using the default format for type *T*. - \endrst */ template std::wstring to_wstring(const T &value) { @@ -3478,6 +3478,17 @@ inline OutputIt vformat_to(OutputIt out, string_view format_str, return vformat_to>(range(out), format_str, args); } +/** + \rst + Formats arguments, writes the result to the output iterator ``out`` and returns + the iterator past the end of the output range. + + **Example**:: + + std::vector out; + fmt::format_to(std::back_inserter(out), "{}", 42); + \endrst + */ template inline OutputIt format_to(OutputIt out, string_view format_str, const Args & ... args) { @@ -3552,7 +3563,10 @@ inline typename std::enable_if::value>::type return vprint(format_str.data(), make_format_args(args...)); } -// Counts the number of characters in the output of format(format_str, args...). +/** + Returns the number of characters in the output of + ``format(format_str, args...)``. + */ template inline std::size_t formatted_size(string_view format_str, const Args & ... args) {