From cdf3fa08dc9123959c5007513fb8e0b9bc20c820 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 4 Oct 2018 18:06:21 -0700 Subject: [PATCH] Put related code together in fmt/core.h --- include/fmt/core.h | 484 ++++++++++++++++++++++----------------------- 1 file changed, 240 insertions(+), 244 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index e3c152cb..11a887f4 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -222,128 +222,9 @@ template struct is_constructible: std::false_type {}; #else template -struct is_constructible: std::is_constructible {}; +struct is_constructible : std::is_constructible {}; #endif -template -struct no_formatter_error : std::false_type {}; -} // namespace internal - -/** - 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). - */ -template -class basic_string_view { - private: - const Char *data_; - size_t size_; - - public: - typedef Char char_type; - typedef const Char *iterator; - - FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(FMT_NULL), size_(0) {} - - /** Constructs a string reference object from a C string and a size. */ - FMT_CONSTEXPR basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT - : data_(s), size_(count) {} - - /** - \rst - Constructs a string reference object from a C string computing - the size with ``std::char_traits::length``. - \endrst - */ - FMT_CONSTEXPR basic_string_view(const Char *s) - : data_(s), size_(internal::length(s)) {} - - /** Constructs a string reference from a ``std::basic_string`` object. */ - template - FMT_CONSTEXPR basic_string_view( - const std::basic_string &s) FMT_NOEXCEPT - : data_(s.data()), size_(s.size()) {} - -#ifdef FMT_STRING_VIEW - FMT_CONSTEXPR basic_string_view(FMT_STRING_VIEW s) FMT_NOEXCEPT - : data_(s.data()), size_(s.size()) {} -#endif - - /** Returns a pointer to the string data. */ - FMT_CONSTEXPR const Char *data() const { return data_; } - - /** Returns the string size. */ - FMT_CONSTEXPR size_t size() const { return size_; } - - FMT_CONSTEXPR iterator begin() const { return data_; } - FMT_CONSTEXPR iterator end() const { return data_ + size_; } - - FMT_CONSTEXPR void remove_prefix(size_t n) { - data_ += n; - size_ -= n; - } - - // Lexicographically compare this string reference to other. - int compare(basic_string_view other) const { - size_t str_size = size_ < other.size_ ? size_ : other.size_; - int result = std::char_traits::compare(data_, other.data_, str_size); - if (result == 0) - result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); - return result; - } - - friend bool operator==(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) == 0; - } - friend bool operator!=(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) != 0; - } - friend bool operator<(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) < 0; - } - friend bool operator<=(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) <= 0; - } - friend bool operator>(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) > 0; - } - friend bool operator>=(basic_string_view lhs, basic_string_view rhs) { - return lhs.compare(rhs) >= 0; - } -}; - -typedef basic_string_view string_view; -typedef basic_string_view wstring_view; - -template -class basic_format_arg; - -template -class basic_format_args; - -// A formatter for objects of type T. -template -struct formatter { - static_assert(internal::no_formatter_error::value, - "don't know how to format the type, include fmt/ostream.h if it provides " - "an operator<< that should be used"); - - // The following functions are not defined intentionally. - template - typename ParseContext::iterator parse(ParseContext &); - template - auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out()); -}; - -template -struct convert_to_int: std::integral_constant< - bool, !std::is_arithmetic::value && std::is_convertible::value> {}; - -namespace internal { - /** A contiguous memory buffer with an optional growing ability. */ template class basic_buffer { @@ -442,6 +323,17 @@ class container_buffer : public basic_buffer { : basic_buffer(c.size()), container_(c) {} }; +// Extracts a reference to the container from back_insert_iterator. +template +inline Container &get_container(std::back_insert_iterator it) { + typedef std::back_insert_iterator bi_iterator; + struct accessor: bi_iterator { + accessor(bi_iterator iter) : bi_iterator(iter) {} + using bi_iterator::container; + }; + return *accessor(it).container; +} + struct error_handler { FMT_CONSTEXPR error_handler() {} FMT_CONSTEXPR error_handler(const error_handler &) {} @@ -450,6 +342,171 @@ struct error_handler { FMT_API void on_error(const char *message); }; +template +struct no_formatter_error : std::false_type {}; +} // namespace internal + +/** + 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). + */ +template +class basic_string_view { + private: + const Char *data_; + size_t size_; + + public: + typedef Char char_type; + typedef const Char *iterator; + + FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(FMT_NULL), size_(0) {} + + /** Constructs a string reference object from a C string and a size. */ + FMT_CONSTEXPR basic_string_view(const Char *s, size_t count) FMT_NOEXCEPT + : data_(s), size_(count) {} + + /** + \rst + Constructs a string reference object from a C string computing + the size with ``std::char_traits::length``. + \endrst + */ + FMT_CONSTEXPR basic_string_view(const Char *s) + : data_(s), size_(internal::length(s)) {} + + /** Constructs a string reference from a ``std::basic_string`` object. */ + template + FMT_CONSTEXPR basic_string_view( + const std::basic_string &s) FMT_NOEXCEPT + : data_(s.data()), size_(s.size()) {} + +#ifdef FMT_STRING_VIEW + FMT_CONSTEXPR basic_string_view(FMT_STRING_VIEW s) FMT_NOEXCEPT + : data_(s.data()), size_(s.size()) {} +#endif + + /** Returns a pointer to the string data. */ + FMT_CONSTEXPR const Char *data() const { return data_; } + + /** Returns the string size. */ + FMT_CONSTEXPR size_t size() const { return size_; } + + FMT_CONSTEXPR iterator begin() const { return data_; } + FMT_CONSTEXPR iterator end() const { return data_ + size_; } + + FMT_CONSTEXPR void remove_prefix(size_t n) { + data_ += n; + size_ -= n; + } + + // Lexicographically compare this string reference to other. + int compare(basic_string_view other) const { + size_t str_size = size_ < other.size_ ? size_ : other.size_; + int result = std::char_traits::compare(data_, other.data_, str_size); + if (result == 0) + result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); + return result; + } + + friend bool operator==(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) == 0; + } + friend bool operator!=(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) != 0; + } + friend bool operator<(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) < 0; + } + friend bool operator<=(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) <= 0; + } + friend bool operator>(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) > 0; + } + friend bool operator>=(basic_string_view lhs, basic_string_view rhs) { + return lhs.compare(rhs) >= 0; + } +}; + +typedef basic_string_view string_view; +typedef basic_string_view wstring_view; + +// A base class for compile-time strings. It is defined in the fmt namespace to +// make formatting functions visible via ADL, e.g. format(fmt("{}"), 42). +struct compile_string {}; + +template +class basic_format_arg; + +template +class basic_format_args; + +// A formatter for objects of type T. +template +struct formatter { + static_assert(internal::no_formatter_error::value, + "don't know how to format the type, include fmt/ostream.h if it provides " + "an operator<< that should be used"); + + // The following functions are not defined intentionally. + template + typename ParseContext::iterator parse(ParseContext &); + template + auto format(const T &val, FormatContext &ctx) -> decltype(ctx.out()); +}; + +template +struct convert_to_int: std::integral_constant< + bool, !std::is_arithmetic::value && std::is_convertible::value> {}; + +namespace internal { + +// If S is a format string type, format_string_traints::char_type gives its +// character type. +template +class format_string_traits { + // Use emptyness as a way to detect if format_string_traits is + // specialized because other methods are broken on MSVC2013 or gcc 4.4. + int dummy; +}; + +template +struct format_string_traits_base { typedef Char char_type; }; + +template +struct format_string_traits : format_string_traits_base {}; + +template +struct format_string_traits : format_string_traits_base {}; + +template +struct format_string_traits : format_string_traits_base {}; + +template +struct format_string_traits : format_string_traits_base {}; + +template +struct format_string_traits> : + format_string_traits_base {}; + +template +struct format_string_traits< + S, typename std::enable_if, S>::value>::type> : + format_string_traits_base {}; + +template +struct is_format_string : std::is_empty> {}; + +template +struct is_compile_string : std::is_base_of {}; + +#define FMT_CHAR(Str) typename internal::format_string_traits::char_type + template struct named_arg_base; @@ -917,15 +974,39 @@ class context_base { void advance_to(iterator it) { out_ = it; } }; -// Extracts a reference to the container from back_insert_iterator. -template -inline Container &get_container(std::back_insert_iterator it) { - typedef std::back_insert_iterator bi_iterator; - struct accessor: bi_iterator { - accessor(bi_iterator iter) : bi_iterator(iter) {} - using bi_iterator::container; - }; - return *accessor(it).container; +template +struct get_type { + typedef decltype(make_value( + declval::type&>())) value_type; + static const type value = value_type::type_tag; +}; + +template +FMT_CONSTEXPR11 unsigned long long get_types() { return 0; } + +template +FMT_CONSTEXPR11 unsigned long long get_types() { + return get_type::value | (get_types() << 4); +} + +template +FMT_CONSTEXPR basic_format_arg make_arg(const T &value) { + basic_format_arg arg; + arg.type_ = get_type::value; + arg.value_ = make_value(value); + return arg; +} + +template +inline typename std::enable_if>::type + make_arg(const T &value) { + return make_value(value); +} + +template +inline typename std::enable_if>::type + make_arg(const T &value) { + return make_arg(value); } } // namespace internal @@ -981,43 +1062,6 @@ struct buffer_context { typedef buffer_context::type format_context; typedef buffer_context::type wformat_context; -namespace internal { -template -struct get_type { - typedef decltype(make_value( - declval::type&>())) value_type; - static const type value = value_type::type_tag; -}; - -template -FMT_CONSTEXPR11 unsigned long long get_types() { return 0; } - -template -FMT_CONSTEXPR11 unsigned long long get_types() { - return get_type::value | (get_types() << 4); -} - -template -FMT_CONSTEXPR basic_format_arg make_arg(const T &value) { - basic_format_arg arg; - arg.type_ = get_type::value; - arg.value_ = make_value(value); - return arg; -} - -template -inline typename std::enable_if>::type - make_arg(const T &value) { - return make_value(value); -} - -template -inline typename std::enable_if>::type - make_arg(const T &value) { - return make_arg(value); -} -} // namespace internal - /** \rst An array of references to arguments. It can be implicitly converted into @@ -1221,6 +1265,36 @@ struct named_arg : named_arg_base { named_arg(basic_string_view name, const T &val) : named_arg_base(name), value(val) {} }; + +template +inline typename std::enable_if::value>::type + check_format_string(const S &) {} +template +typename std::enable_if::value>::type + check_format_string(S); + +template +struct checked_args : format_arg_store< + typename buffer_context::type, Args...> { + typedef typename buffer_context::type context; + + checked_args(const S &format_str, const Args &... args): + format_arg_store(args...) { + internal::check_format_string(format_str); + } + + basic_format_args operator*() const { return *this; } +}; + +template +inline basic_string_view to_string_view(const S &s) { + return basic_string_view(s); +} + +template +std::basic_string vformat( + basic_string_view format_str, + basic_format_args::type> args); } /** @@ -1247,84 +1321,6 @@ inline internal::named_arg arg(wstring_view name, const T &arg) { template void arg(S, internal::named_arg) = delete; -// A base class for compile-time strings. It is defined in the fmt namespace to -// make formatting functions visible via ADL, e.g. format(fmt("{}"), 42). -struct compile_string {}; - -namespace internal { -// If S is a format string type, format_string_traints::char_type gives its -// character type. -template -class format_string_traits { - // Use emptyness as a way to detect if format_string_traits is - // specialized because other methods are broken on MSVC2013 or gcc 4.4. - int dummy; -}; - -template -struct format_string_traits_base { typedef Char char_type; }; - -template -struct format_string_traits : format_string_traits_base {}; - -template -struct format_string_traits : format_string_traits_base {}; - -template -struct format_string_traits : format_string_traits_base {}; - -template -struct format_string_traits : format_string_traits_base {}; - -template -struct format_string_traits> : - format_string_traits_base {}; - -template -struct format_string_traits< - S, typename std::enable_if, S>::value>::type> : - format_string_traits_base {}; - -template -struct is_format_string : std::is_empty> {}; - -template -struct is_compile_string : std::is_base_of {}; - -#define FMT_CHAR(Str) typename internal::format_string_traits::char_type - -template -inline typename std::enable_if::value>::type - check_format_string(const S &) {} -template -typename std::enable_if::value>::type - check_format_string(S); - -template -struct checked_args: format_arg_store< - typename buffer_context::type, Args...> { - typedef typename buffer_context::type context; - - checked_args(const S &format_str, const Args &... args): - format_arg_store(args...) { - internal::check_format_string(format_str); - } - - basic_format_args operator*() const { return *this; } -}; - -template -inline basic_string_view to_string_view(const S &s) { - return basic_string_view(s); -} - -template -std::basic_string vformat( - basic_string_view format_str, - basic_format_args::type> args); -} // namespace internal - template format_context::iterator vformat_to( internal::basic_buffer &buf, const S &format_str,