mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-07-16 05:47:11 +02:00
bin
cmake
module
Base
Core
Entity
Library
Misc
Vendor
AES256
B64
CivetWeb
ConcurrentQueue
Fmt
include
fmt
chrono.h
color.h
compile.h
core.h
format-inl.h
format.h
locale.h
os.h
ostream.h
posix.h
printf.h
ranges.h
CMakeLists.txt
LICENSE.rst
format.cc
os.cc
Hash
MDBC
MaxmindDB
PUGIXML
SQLite
SimpleIni
SimpleSocket
TinyDir
Whirlpool
CMakeLists.txt
CMakeLists.txt
Core.cpp
Core.hpp
Logger.cpp
Logger.hpp
Main.cpp
Register.cpp
SqBase.hpp
sdk
.gitignore
.gitmodules
CMakeLists.txt
LICENSE
README.md
178 lines
5.8 KiB
C++
178 lines
5.8 KiB
C++
// 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 <ostream>
|
|
|
|
#include "format.h"
|
|
|
|
FMT_BEGIN_NAMESPACE
|
|
|
|
template <typename Char> class basic_printf_parse_context;
|
|
template <typename OutputIt, typename Char> class basic_printf_context;
|
|
|
|
namespace detail {
|
|
|
|
template <class Char> class formatbuf : public std::basic_streambuf<Char> {
|
|
private:
|
|
using int_type = typename std::basic_streambuf<Char>::int_type;
|
|
using traits_type = typename std::basic_streambuf<Char>::traits_type;
|
|
|
|
buffer<Char>& buffer_;
|
|
|
|
public:
|
|
formatbuf(buffer<Char>& buf) : buffer_(buf) {}
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
struct converter {
|
|
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)> converter(T);
|
|
};
|
|
|
|
template <typename Char> struct test_stream : std::basic_ostream<Char> {
|
|
private:
|
|
void_t<> operator<<(converter);
|
|
};
|
|
|
|
// Hide insertion operators for built-in types.
|
|
template <typename Char, typename Traits>
|
|
void_t<> operator<<(std::basic_ostream<Char, Traits>&, Char);
|
|
template <typename Char, typename Traits>
|
|
void_t<> operator<<(std::basic_ostream<Char, Traits>&, char);
|
|
template <typename Traits>
|
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, char);
|
|
template <typename Traits>
|
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, signed char);
|
|
template <typename Traits>
|
|
void_t<> operator<<(std::basic_ostream<char, Traits>&, unsigned char);
|
|
|
|
// Checks if T has a user-defined operator<< (e.g. not a member of
|
|
// std::ostream).
|
|
template <typename T, typename Char> class is_streamable {
|
|
private:
|
|
template <typename U>
|
|
static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
|
|
<< std::declval<U>()),
|
|
void_t<>>::value>
|
|
test(int);
|
|
|
|
template <typename> static std::false_type test(...);
|
|
|
|
using result = decltype(test<T>(0));
|
|
|
|
public:
|
|
static const bool value = result::value;
|
|
};
|
|
|
|
// Write the content of buf to os.
|
|
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()) {
|
|
formatbuf<Char> format_buf(buf);
|
|
std::basic_ostream<Char> output(&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);
|
|
buf.try_resize(buf.size());
|
|
}
|
|
|
|
// Formats an object of type T that has an overloaded ostream operator<<.
|
|
template <typename T, typename Char>
|
|
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
|
|
: private formatter<basic_string_view<Char>, Char> {
|
|
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
|
-> decltype(ctx.begin()) {
|
|
return formatter<basic_string_view<Char>, Char>::parse(ctx);
|
|
}
|
|
template <typename ParseCtx,
|
|
FMT_ENABLE_IF(std::is_same<
|
|
ParseCtx, basic_printf_parse_context<Char>>::value)>
|
|
auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) {
|
|
return ctx.begin();
|
|
}
|
|
|
|
template <typename OutputIt>
|
|
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
|
|
-> OutputIt {
|
|
basic_memory_buffer<Char> buffer;
|
|
format_value(buffer, value, ctx.locale());
|
|
basic_string_view<Char> str(buffer.data(), buffer.size());
|
|
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
|
|
}
|
|
template <typename OutputIt>
|
|
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
|
|
-> OutputIt {
|
|
basic_memory_buffer<Char> buffer;
|
|
format_value(buffer, value, ctx.locale());
|
|
return std::copy(buffer.begin(), buffer.end(), ctx.out());
|
|
}
|
|
};
|
|
} // namespace detail
|
|
|
|
template <typename Char>
|
|
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
|
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
|
basic_memory_buffer<Char> buffer;
|
|
detail::vformat_to(buffer, format_str, args);
|
|
detail::write_buffer(os, buffer);
|
|
}
|
|
|
|
/**
|
|
\rst
|
|
Prints formatted data to the stream *os*.
|
|
|
|
**Example**::
|
|
|
|
fmt::print(cerr, "Don't {}!", "panic");
|
|
\endrst
|
|
*/
|
|
template <typename S, typename... Args,
|
|
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
|
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
|
|
vprint(os, to_string_view(format_str),
|
|
fmt::make_args_checked<Args...>(format_str, args...));
|
|
}
|
|
FMT_END_NAMESPACE
|
|
|
|
#endif // FMT_OSTREAM_H_
|