Remove dependency on string_view

This commit is contained in:
Victor Zverovich 2024-01-03 15:34:43 -08:00
parent f2e43f967c
commit 800a0bb23f
3 changed files with 68 additions and 61 deletions

View File

@ -12,7 +12,7 @@
#include <memory> // std::unique_ptr
#include <vector>
#include "core.h"
#include "format.h" // std_string_view
FMT_BEGIN_NAMESPACE

View File

@ -8,12 +8,12 @@
#ifndef FMT_CORE_H_
#define FMT_CORE_H_
#include <cstddef> // std::byte
#include <cstdio> // std::FILE
#include <cstring> // std::strlen
#include <limits> // std::numeric_limits
#include <string>
#include <type_traits>
#include <cstddef> // std::byte
#include <cstdio> // std::FILE
#include <cstring> // std::strlen
#include <limits> // std::numeric_limits
#include <string> // std::string
#include <type_traits> // std::enable_if
// The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 100200
@ -209,16 +209,6 @@
# define FMT_API
#endif
// libc++ supports string_view in pre-c++17.
#if FMT_HAS_INCLUDE(<string_view>) && \
(FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
# include <string_view>
# define FMT_USE_STRING_VIEW
#elif FMT_HAS_INCLUDE("experimental/string_view") && FMT_CPLUSPLUS >= 201402L
# include <experimental/string_view>
# define FMT_USE_EXPERIMENTAL_STRING_VIEW
#endif
#ifndef FMT_UNICODE
# define FMT_UNICODE !FMT_MSC_VERSION
#endif
@ -287,10 +277,15 @@ template <typename T> using type_identity_t = typename type_identity<T>::type;
template <typename T>
using underlying_t = typename std::underlying_type<T>::type;
// Checks whether T is a container with contiguous storage.
template <typename T> struct is_contiguous : std::false_type {};
template <typename Char>
struct is_contiguous<std::basic_string<Char>> : std::true_type {};
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
template <typename...> struct void_t_impl {
using type = void;
};
template <typename... T> using void_t = typename void_t_impl<T...>::type;
#else
template <typename...> using void_t = void;
#endif
struct monostate {
constexpr monostate() {}
@ -388,15 +383,6 @@ FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
# endif
#endif
#if defined(FMT_USE_STRING_VIEW)
template <typename Char> using std_string_view = std::basic_string_view<Char>;
#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
template <typename Char>
using std_string_view = std::experimental::basic_string_view<Char>;
#else
template <typename T> struct std_string_view {};
#endif
#ifdef FMT_USE_INT128
// Do nothing.
#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \
@ -425,6 +411,15 @@ FMT_CONSTEXPR auto to_unsigned(Int value) ->
return static_cast<typename std::make_unsigned<Int>::type>(value);
}
template <typename T, typename Enable = void>
struct is_string_like : std::false_type {};
// A heuristic to detect std::string and std::string_view.
template <typename T>
struct is_string_like<T, void_t<decltype(std::declval<T>().find_first_of(
typename T::value_type(), 0))>> : std::true_type {
};
FMT_CONSTEXPR inline auto is_utf8() -> bool {
FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char section[] = "\u00A7";
@ -451,6 +446,15 @@ FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, std::size_t n)
}
} // namespace detail
template <typename Char>
using basic_string =
std::basic_string<Char, std::char_traits<Char>, std::allocator<Char>>;
// Checks whether T is a container with contiguous storage.
template <typename T> struct is_contiguous : std::false_type {};
template <typename Char>
struct is_contiguous<basic_string<Char>> : std::true_type {};
/**
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
@ -486,15 +490,14 @@ template <typename Char> class basic_string_view {
? std::strlen(reinterpret_cast<const char*>(s))
: detail::length(s)) {}
/** Constructs a string reference from a ``std::basic_string`` object. */
template <typename Traits, typename Alloc>
FMT_CONSTEXPR basic_string_view(
const std::basic_string<Char, Traits, Alloc>& s) noexcept
: data_(s.data()), size_(s.size()) {}
template <typename S, FMT_ENABLE_IF(std::is_same<
S, detail::std_string_view<Char>>::value)>
FMT_CONSTEXPR basic_string_view(S s) noexcept
/**
Constructs a string reference from a ``std::basic_string`` or a
``std::basic_string_view`` object.
*/
template <typename S,
FMT_ENABLE_IF(detail::is_string_like<S>::value&& std::is_same<
typename S::value_type, Char>::value)>
FMT_CONSTEXPR basic_string_view(const S& s) noexcept
: data_(s.data()), size_(s.size()) {}
/** Returns a pointer to the string data. */
@ -576,21 +579,16 @@ template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view<Char> {
return s;
}
template <typename Char, typename Traits, typename Alloc>
inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s)
-> basic_string_view<Char> {
return s;
template <typename S, FMT_ENABLE_IF(is_string_like<S>::value)>
inline auto to_string_view(const S& s)
-> basic_string_view<typename S::value_type> {
return s; // std::basic_string[_view]
}
template <typename Char>
constexpr auto to_string_view(basic_string_view<Char> s)
-> basic_string_view<Char> {
return s;
}
template <typename Char,
FMT_ENABLE_IF(!std::is_empty<std_string_view<Char>>::value)>
inline auto to_string_view(std_string_view<Char> s) -> basic_string_view<Char> {
return s;
}
template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
constexpr auto to_string_view(const S& s)
-> basic_string_view<typename S::char_type> {
@ -985,7 +983,7 @@ class iterator_buffer<T*, T, fixed_buffer_traits> final
: fixed_buffer_traits(n), buffer<T>(grow, out, 0, n), out_(out) {}
iterator_buffer(iterator_buffer&& other)
: fixed_buffer_traits(other),
buffer<T>(std::move(other)),
buffer<T>(static_cast<iterator_buffer&&>(other)),
out_(other.out_) {
if (this->data() != out_) {
this->set(data_, buffer_size);
@ -1526,16 +1524,6 @@ enum { max_packed_args = 62 / packed_arg_bits };
enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
template <typename...> struct void_t_impl {
using type = void;
};
template <typename... T> using void_t = typename void_t_impl<T...>::type;
#else
template <typename...> using void_t = void;
#endif
template <typename It, typename T, typename Enable = void>
struct is_output_iterator : std::false_type {};
@ -2813,7 +2801,7 @@ using format_string = basic_format_string<char, type_identity_t<Args>...>;
inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
#endif
FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
FMT_API auto vformat(string_view fmt, format_args args) -> basic_string<char>;
/**
\rst
@ -2828,7 +2816,7 @@ FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
*/
template <typename... T>
FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
-> std::string {
-> basic_string<char> {
return vformat(fmt, fmt::make_format_args(args...));
}

View File

@ -49,6 +49,16 @@
#include "core.h"
// libc++ supports string_view in pre-c++17.
#if FMT_HAS_INCLUDE(<string_view>) && \
(FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))
# include <string_view>
# define FMT_USE_STRING_VIEW
#elif FMT_HAS_INCLUDE("experimental/string_view") && FMT_CPLUSPLUS >= 201402L
# include <experimental/string_view>
# define FMT_USE_EXPERIMENTAL_STRING_VIEW
#endif
#if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L
# define FMT_INLINE_VARIABLE inline
#else
@ -285,6 +295,15 @@ FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {
#endif
}
#if defined(FMT_USE_STRING_VIEW)
template <typename Char> using std_string_view = std::basic_string_view<Char>;
#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
template <typename Char>
using std_string_view = std::experimental::basic_string_view<Char>;
#else
template <typename T> struct std_string_view {};
#endif
template <typename CharT, CharT... C> struct string_literal {
static constexpr CharT value[sizeof...(C)] = {C...};
constexpr operator basic_string_view<CharT>() const {