|
|
|
@ -83,21 +83,28 @@
|
|
|
|
|
|
|
|
|
|
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
|
|
|
|
|
|
|
|
|
|
namespace fmt {
|
|
|
|
|
namespace fmt
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// An error code.
|
|
|
|
|
class ErrorCode {
|
|
|
|
|
class ErrorCode
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
int value_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
|
|
|
|
|
explicit ErrorCode(int value = 0) FMT_NOEXCEPT :
|
|
|
|
|
value_(value) {}
|
|
|
|
|
|
|
|
|
|
int get() const FMT_NOEXCEPT { return value_; }
|
|
|
|
|
int get() const FMT_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return value_;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// A buffered file.
|
|
|
|
|
class BufferedFile {
|
|
|
|
|
class BufferedFile
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
FILE *file_;
|
|
|
|
|
|
|
|
|
@ -107,7 +114,8 @@ class BufferedFile {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// Constructs a BufferedFile object which doesn't represent any file.
|
|
|
|
|
BufferedFile() FMT_NOEXCEPT : file_(0) {}
|
|
|
|
|
BufferedFile() FMT_NOEXCEPT :
|
|
|
|
|
file_(0) {}
|
|
|
|
|
|
|
|
|
|
// Destroys the object closing the file it represents if any.
|
|
|
|
|
~BufferedFile() FMT_NOEXCEPT;
|
|
|
|
@ -119,28 +127,34 @@ class BufferedFile {
|
|
|
|
|
private:
|
|
|
|
|
// A proxy object to emulate a move constructor.
|
|
|
|
|
// It is private to make it impossible call operator Proxy directly.
|
|
|
|
|
struct Proxy {
|
|
|
|
|
struct Proxy
|
|
|
|
|
{
|
|
|
|
|
FILE *file;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// A "move constructor" for moving from a temporary.
|
|
|
|
|
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
|
|
|
|
|
BufferedFile(Proxy p) FMT_NOEXCEPT :
|
|
|
|
|
file_(p.file) {}
|
|
|
|
|
|
|
|
|
|
// A "move constructor" for moving from an lvalue.
|
|
|
|
|
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
|
|
|
|
|
BufferedFile(BufferedFile &f) FMT_NOEXCEPT :
|
|
|
|
|
file_(f.file_)
|
|
|
|
|
{
|
|
|
|
|
f.file_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A "move assignment operator" for moving from a temporary.
|
|
|
|
|
BufferedFile &operator=(Proxy p) {
|
|
|
|
|
BufferedFile &operator=(Proxy p)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
file_ = p.file;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A "move assignment operator" for moving from an lvalue.
|
|
|
|
|
BufferedFile &operator=(BufferedFile &other) {
|
|
|
|
|
BufferedFile &operator=(BufferedFile &other)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
file_ = other.file_;
|
|
|
|
|
other.file_ = 0;
|
|
|
|
@ -149,7 +163,8 @@ public:
|
|
|
|
|
|
|
|
|
|
// Returns a proxy object for moving from a temporary:
|
|
|
|
|
// BufferedFile file = BufferedFile(...);
|
|
|
|
|
operator Proxy() FMT_NOEXCEPT {
|
|
|
|
|
operator Proxy() FMT_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
Proxy p = {file_};
|
|
|
|
|
file_ = 0;
|
|
|
|
|
return p;
|
|
|
|
@ -160,11 +175,14 @@ public:
|
|
|
|
|
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
|
|
|
|
|
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
|
|
|
|
|
file_(other.file_)
|
|
|
|
|
{
|
|
|
|
|
other.file_ = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BufferedFile& operator=(BufferedFile &&other) {
|
|
|
|
|
BufferedFile& operator=(BufferedFile &&other)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
file_ = other.file_;
|
|
|
|
|
other.file_ = 0;
|
|
|
|
@ -179,13 +197,17 @@ public:
|
|
|
|
|
void close();
|
|
|
|
|
|
|
|
|
|
// Returns the pointer to a FILE object representing this file.
|
|
|
|
|
FILE *get() const FMT_NOEXCEPT { return 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.
|
|
|
|
|
int (fileno)() const;
|
|
|
|
|
|
|
|
|
|
void print(CStringRef format_str, const ArgList &args) {
|
|
|
|
|
void print(CStringRef format_str, const ArgList &args)
|
|
|
|
|
{
|
|
|
|
|
fmt::print(file_, format_str, args);
|
|
|
|
|
}
|
|
|
|
|
FMT_VARIADIC(void, print, CStringRef)
|
|
|
|
@ -197,7 +219,8 @@ public:
|
|
|
|
|
// 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 {
|
|
|
|
|
class File
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
int fd_; // File descriptor.
|
|
|
|
|
|
|
|
|
@ -206,14 +229,16 @@ class File {
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// Possible values for the oflag argument to the constructor.
|
|
|
|
|
enum {
|
|
|
|
|
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) {}
|
|
|
|
|
File() FMT_NOEXCEPT :
|
|
|
|
|
fd_(-1) {}
|
|
|
|
|
|
|
|
|
|
// Opens a file and constructs a File object representing this file.
|
|
|
|
|
File(CStringRef path, int oflag);
|
|
|
|
@ -225,28 +250,34 @@ class File {
|
|
|
|
|
private:
|
|
|
|
|
// A proxy object to emulate a move constructor.
|
|
|
|
|
// It is private to make it impossible call operator Proxy directly.
|
|
|
|
|
struct Proxy {
|
|
|
|
|
struct Proxy
|
|
|
|
|
{
|
|
|
|
|
int fd;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// A "move constructor" for moving from a temporary.
|
|
|
|
|
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
|
|
|
|
|
File(Proxy p) FMT_NOEXCEPT :
|
|
|
|
|
fd_(p.fd) {}
|
|
|
|
|
|
|
|
|
|
// A "move constructor" for moving from an lvalue.
|
|
|
|
|
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
|
|
|
|
|
File(File &other) FMT_NOEXCEPT :
|
|
|
|
|
fd_(other.fd_)
|
|
|
|
|
{
|
|
|
|
|
other.fd_ = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A "move assignment operator" for moving from a temporary.
|
|
|
|
|
File &operator=(Proxy p) {
|
|
|
|
|
File &operator=(Proxy p)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
fd_ = p.fd;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A "move assignment operator" for moving from an lvalue.
|
|
|
|
|
File &operator=(File &other) {
|
|
|
|
|
File &operator=(File &other)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
fd_ = other.fd_;
|
|
|
|
|
other.fd_ = -1;
|
|
|
|
@ -255,7 +286,8 @@ class File {
|
|
|
|
|
|
|
|
|
|
// Returns a proxy object for moving from a temporary:
|
|
|
|
|
// File file = File(...);
|
|
|
|
|
operator Proxy() FMT_NOEXCEPT {
|
|
|
|
|
operator Proxy() FMT_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
Proxy p = {fd_};
|
|
|
|
|
fd_ = -1;
|
|
|
|
|
return p;
|
|
|
|
@ -266,11 +298,14 @@ class File {
|
|
|
|
|
FMT_DISALLOW_COPY_AND_ASSIGN(File);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
|
|
|
|
|
File(File &&other) FMT_NOEXCEPT :
|
|
|
|
|
fd_(other.fd_)
|
|
|
|
|
{
|
|
|
|
|
other.fd_ = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File& operator=(File &&other) {
|
|
|
|
|
File& operator=(File &&other)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
fd_ = other.fd_;
|
|
|
|
|
other.fd_ = -1;
|
|
|
|
@ -282,7 +317,10 @@ class File {
|
|
|
|
|
~File() FMT_NOEXCEPT;
|
|
|
|
|
|
|
|
|
|
// Returns the file descriptor.
|
|
|
|
|
int descriptor() const FMT_NOEXCEPT { return fd_; }
|
|
|
|
|
int descriptor() const FMT_NOEXCEPT
|
|
|
|
|
{
|
|
|
|
|
return fd_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Closes the file.
|
|
|
|
|
void close();
|
|
|
|
@ -328,22 +366,26 @@ long getpagesize();
|
|
|
|
|
|
|
|
|
|
#ifdef FMT_LOCALE
|
|
|
|
|
// A "C" numeric locale.
|
|
|
|
|
class 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) {
|
|
|
|
|
static locale_t newlocale(int category_mask, const char *locale, locale_t)
|
|
|
|
|
{
|
|
|
|
|
return _create_locale(category_mask, locale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void freelocale(locale_t locale) {
|
|
|
|
|
static void freelocale(locale_t locale)
|
|
|
|
|
{
|
|
|
|
|
_free_locale(locale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
|
|
|
|
|
static double strtod_l(const char *nptr, char **endptr, _locale_t locale)
|
|
|
|
|
{
|
|
|
|
|
return _strtod_l(nptr, endptr, locale);
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
@ -355,17 +397,25 @@ class Locale {
|
|
|
|
|
public:
|
|
|
|
|
typedef locale_t Type;
|
|
|
|
|
|
|
|
|
|
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL)) {
|
|
|
|
|
Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", NULL))
|
|
|
|
|
{
|
|
|
|
|
if (!locale_)
|
|
|
|
|
FMT_THROW(fmt::SystemError(errno, "cannot create locale"));
|
|
|
|
|
}
|
|
|
|
|
~Locale() { freelocale(locale_); }
|
|
|
|
|
~Locale()
|
|
|
|
|
{
|
|
|
|
|
freelocale(locale_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Type get() const { return 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 {
|
|
|
|
|
double strtod(const char *&str) const
|
|
|
|
|
{
|
|
|
|
|
char *end = 0;
|
|
|
|
|
double result = strtod_l(str, &end, locale_);
|
|
|
|
|
str = end;
|
|
|
|
@ -376,10 +426,17 @@ class Locale {
|
|
|
|
|
} // namespace fmt
|
|
|
|
|
|
|
|
|
|
#if !FMT_USE_RVALUE_REFERENCES
|
|
|
|
|
namespace std {
|
|
|
|
|
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; }
|
|
|
|
|
inline fmt::BufferedFile &move(fmt::BufferedFile &f)
|
|
|
|
|
{
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
inline fmt::File &move(fmt::File &f)
|
|
|
|
|
{
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|