Various fixes for MSVC

This commit is contained in:
carterl 2015-02-11 10:02:20 +01:00
parent 704e7a8817
commit 240965305f
8 changed files with 58 additions and 47 deletions

View File

@ -146,7 +146,7 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
// other - failure // other - failure
// Buffer should be at least of size 1. // Buffer should be at least of size 1.
int safe_strerror( int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) { int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
assert(buffer != 0 && buffer_size != 0); assert(buffer != 0 && buffer_size != 0);
int result = 0; int result = 0;
#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || __ANDROID__ #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || __ANDROID__
@ -180,7 +180,7 @@ int safe_strerror(
} }
void format_error_code(fmt::Writer &out, int error_code, void format_error_code(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT(true) { fmt::StringRef message) FMT_NOEXCEPT {
// Report error code making sure that the output fits into // Report error code making sure that the output fits into
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// bad_alloc. // bad_alloc.
@ -198,7 +198,7 @@ void format_error_code(fmt::Writer &out, int error_code,
} }
void report_error(FormatFunc func, void report_error(FormatFunc func,
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { int error_code, fmt::StringRef message) FMT_NOEXCEPT {
fmt::MemoryWriter full_message; fmt::MemoryWriter full_message;
func(full_message, error_code, message); func(full_message, error_code, message);
// Use Writer::data instead of Writer::c_str to avoid potential memory // Use Writer::data instead of Writer::c_str to avoid potential memory
@ -500,7 +500,7 @@ FMT_FUNC void fmt::WindowsError::init(
FMT_FUNC void fmt::internal::format_system_error( FMT_FUNC void fmt::internal::format_system_error(
fmt::Writer &out, int error_code, fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT(true) { fmt::StringRef message) FMT_NOEXCEPT {
FMT_TRY { FMT_TRY {
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer; MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
buffer.resize(INLINE_BUFFER_SIZE); buffer.resize(INLINE_BUFFER_SIZE);
@ -522,7 +522,7 @@ FMT_FUNC void fmt::internal::format_system_error(
#ifdef _WIN32 #ifdef _WIN32
FMT_FUNC void fmt::internal::format_windows_error( FMT_FUNC void fmt::internal::format_windows_error(
fmt::Writer &out, int error_code, fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT(true) { fmt::StringRef message) FMT_NOEXCEPT {
class String { class String {
private: private:
LPWSTR str_; LPWSTR str_;
@ -1083,13 +1083,13 @@ void fmt::BasicFormatter<Char>::format(
} }
FMT_FUNC void fmt::report_system_error( FMT_FUNC void fmt::report_system_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { int error_code, fmt::StringRef message) FMT_NOEXCEPT {
report_error(internal::format_system_error, error_code, message); report_error(internal::format_system_error, error_code, message);
} }
#ifdef _WIN32 #ifdef _WIN32
FMT_FUNC void fmt::report_windows_error( FMT_FUNC void fmt::report_windows_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { int error_code, fmt::StringRef message) FMT_NOEXCEPT {
report_error(internal::format_windows_error, error_code, message); report_error(internal::format_windows_error, error_code, message);
} }
#endif #endif

View File

@ -114,16 +114,26 @@
// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
(FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103)
# define FMT_NOEXCEPT(expr) noexcept(expr) # define FMT_NOEXCEPT noexcept
# define FMT_NOEXCEPT_EXPR(expr) noexcept(expr)
#else #else
# define FMT_NOEXCEPT(expr) # define FMT_NOEXCEPT throw()
# define FMT_NOEXCEPT_EXPR(expr)
#endif #endif
// A macro to disallow the copy constructor and operator= functions // A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class // This should be used in the private: declarations for a class
#if FMT_HAS_FEATURE(cxx_deleted_functions)\
|| (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103)\
|| (_MSC_VER >= 1800)
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
#else
#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ #define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \ TypeName(const TypeName&); \
void operator=(const TypeName&) void operator=(const TypeName&)
#endif
namespace fmt { namespace fmt {
@ -290,7 +300,7 @@ class Buffer {
grow(capacity); grow(capacity);
} }
void clear() FMT_NOEXCEPT(true) { size_ = 0; } void clear() FMT_NOEXCEPT { size_ = 0; }
void push_back(const T &value) { void push_back(const T &value) {
if (size_ == capacity_) if (size_ == capacity_)
@ -623,11 +633,11 @@ class UTF16ToUTF8 {
#endif #endif
void format_system_error(fmt::Writer &out, int error_code, void format_system_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT(true); fmt::StringRef message) FMT_NOEXCEPT;
#ifdef _WIN32 #ifdef _WIN32
void format_windows_error(fmt::Writer &out, int error_code, void format_windows_error(fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT(true); fmt::StringRef message) FMT_NOEXCEPT;
#endif #endif
// Computes max(Arg, 1) at compile time. It is used to avoid errors about // Computes max(Arg, 1) at compile time. It is used to avoid errors about
@ -1560,7 +1570,7 @@ class BasicWriter {
Returns a pointer to the output buffer content. No terminating null Returns a pointer to the output buffer content. No terminating null
character is appended. character is appended.
*/ */
const Char *data() const FMT_NOEXCEPT(true) { return &buffer_[0]; } const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; }
/** /**
Returns a pointer to the output buffer content with terminating null Returns a pointer to the output buffer content with terminating null
@ -1684,7 +1694,7 @@ class BasicWriter {
return *this; return *this;
} }
void clear() FMT_NOEXCEPT(true) { buffer_.clear(); } void clear() FMT_NOEXCEPT { buffer_.clear(); }
}; };
template <typename Char> template <typename Char>
@ -2101,7 +2111,7 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
// Reports a system error without throwing an exception. // Reports a system error without throwing an exception.
// Can be used to report errors from destructors. // Can be used to report errors from destructors.
void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT(true); void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
#ifdef _WIN32 #ifdef _WIN32
@ -2144,7 +2154,7 @@ class WindowsError : public SystemError {
// Reports a Windows error without throwing an exception. // Reports a Windows error without throwing an exception.
// Can be used to report errors from destructors. // Can be used to report errors from destructors.
void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT(true); void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
#endif #endif

View File

@ -75,7 +75,7 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; }
#endif #endif
} }
fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) { fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT {
if (file_ && FMT_SYSTEM(fclose(file_)) != 0) if (file_ && FMT_SYSTEM(fclose(file_)) != 0)
fmt::report_system_error(errno, "cannot close file"); fmt::report_system_error(errno, "cannot close file");
} }
@ -114,7 +114,7 @@ fmt::File::File(fmt::StringRef path, int oflag) {
throw SystemError(errno, "cannot open file {}", path); throw SystemError(errno, "cannot open file {}", path);
} }
fmt::File::~File() FMT_NOEXCEPT(true) { fmt::File::~File() FMT_NOEXCEPT {
// Don't retry close in case of EINTR! // Don't retry close in case of EINTR!
// See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)
@ -186,7 +186,7 @@ void fmt::File::dup2(int fd) {
} }
} }
void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true) { void fmt::File::dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT {
int result = 0; int result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
if (result == -1) if (result == -1)

36
posix.h
View File

@ -68,7 +68,7 @@
# define FMT_UNUSED # define FMT_UNUSED
#endif #endif
#if FMT_USE_STATIC_ASSERT #if FMT_USE_STATIC_ASSERT || (defined _MSC_VER && _MSC_VER >= 1700) || FMT_HAS_CPP_ATTRIBUTE(cxx_static_assert) || (__cplusplus >= 201103L && FMT_GCC_VERSION >= 403)
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message) # define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
#else #else
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) # define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
@ -97,9 +97,9 @@ class ErrorCode {
int value_; int value_;
public: public:
explicit ErrorCode(int value = 0) FMT_NOEXCEPT(true) : value_(value) {} explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT(true) { return value_; } int get() const FMT_NOEXCEPT { return value_; }
}; };
// A buffered file. // A buffered file.
@ -113,10 +113,10 @@ class BufferedFile {
public: public:
// Constructs a BufferedFile object which doesn't represent any file. // Constructs a BufferedFile object which doesn't represent any file.
BufferedFile() FMT_NOEXCEPT(true) : file_(0) {} BufferedFile() FMT_NOEXCEPT : file_(0) {}
// Destroys the object closing the file it represents if any. // Destroys the object closing the file it represents if any.
~BufferedFile() FMT_NOEXCEPT(true); ~BufferedFile() FMT_NOEXCEPT;
#if !FMT_USE_RVALUE_REFERENCES #if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue // Emulate a move constructor and a move assignment operator if rvalue
@ -131,10 +131,10 @@ class BufferedFile {
public: public:
// A "move constructor" for moving from a temporary. // A "move constructor" for moving from a temporary.
BufferedFile(Proxy p) FMT_NOEXCEPT(true) : file_(p.file) {} BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
// A "move constructor" for for moving from an lvalue. // A "move constructor" for for moving from an lvalue.
BufferedFile(BufferedFile &f) FMT_NOEXCEPT(true) : file_(f.file_) { BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
f.file_ = 0; f.file_ = 0;
} }
@ -155,7 +155,7 @@ public:
// Returns a proxy object for moving from a temporary: // Returns a proxy object for moving from a temporary:
// BufferedFile file = BufferedFile(...); // BufferedFile file = BufferedFile(...);
operator Proxy() FMT_NOEXCEPT(true) { operator Proxy() FMT_NOEXCEPT {
Proxy p = {file_}; Proxy p = {file_};
file_ = 0; file_ = 0;
return p; return p;
@ -166,7 +166,7 @@ public:
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile); FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
public: public:
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT(true) : file_(other.file_) { BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = 0; other.file_ = 0;
} }
@ -223,7 +223,7 @@ public:
}; };
// A file. Closed file is represented by a File object with descriptor -1. // A file. Closed file is represented by a File object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT(true) may throw // Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::SystemError in case of failure. Note that some errors such as // fmt::SystemError in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather // closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the // than an exception. You can get standard behavior by overriding the
@ -244,7 +244,7 @@ class File {
}; };
// Constructs a File object which doesn't represent any file. // Constructs a File object which doesn't represent any file.
File() FMT_NOEXCEPT(true) : fd_(-1) {} File() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a File object representing this file. // Opens a file and constructs a File object representing this file.
File(fmt::StringRef path, int oflag); File(fmt::StringRef path, int oflag);
@ -262,10 +262,10 @@ class File {
public: public:
// A "move constructor" for moving from a temporary. // A "move constructor" for moving from a temporary.
File(Proxy p) FMT_NOEXCEPT(true) : fd_(p.fd) {} File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
// A "move constructor" for for moving from an lvalue. // A "move constructor" for for moving from an lvalue.
File(File &other) FMT_NOEXCEPT(true) : fd_(other.fd_) { File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1; other.fd_ = -1;
} }
@ -286,7 +286,7 @@ class File {
// Returns a proxy object for moving from a temporary: // Returns a proxy object for moving from a temporary:
// File file = File(...); // File file = File(...);
operator Proxy() FMT_NOEXCEPT(true) { operator Proxy() FMT_NOEXCEPT {
Proxy p = {fd_}; Proxy p = {fd_};
fd_ = -1; fd_ = -1;
return p; return p;
@ -297,7 +297,7 @@ class File {
FMT_DISALLOW_COPY_AND_ASSIGN(File); FMT_DISALLOW_COPY_AND_ASSIGN(File);
public: public:
File(File &&other) FMT_NOEXCEPT(true) : fd_(other.fd_) { File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1; other.fd_ = -1;
} }
@ -310,10 +310,10 @@ class File {
#endif #endif
// Destroys the object closing the file it represents if any. // Destroys the object closing the file it represents if any.
~File() FMT_NOEXCEPT(true); ~File() FMT_NOEXCEPT;
// Returns the file descriptor. // Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT(true) { return fd_; } int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file. // Closes the file.
void close(); void close();
@ -337,7 +337,7 @@ class File {
// Makes fd be the copy of this file descriptor, closing fd first if // Makes fd be the copy of this file descriptor, closing fd first if
// necessary. // necessary.
void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT(true); void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading // Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively. // and writing respectively.

View File

@ -64,12 +64,14 @@ set_target_properties(header-only-test
PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1") PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1")
target_link_libraries(header-only-test gmock) target_link_libraries(header-only-test gmock)
# Test that the library can be compiled with exceptions disabled. if (NOT CMAKE_GENERATOR MATCHES "Visual Studio")
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) # Test that the library can be compiled with exceptions disabled.
if (HAVE_FNO_EXCEPTIONS_FLAG) check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
add_library(noexception-test STATIC ../format.cc) if (HAVE_FNO_EXCEPTIONS_FLAG)
set_target_properties(noexception-test add_library(noexception-test STATIC ../format.cc)
PROPERTIES COMPILE_FLAGS -fno-exceptions) set_target_properties(noexception-test
PROPERTIES COMPILE_FLAGS -fno-exceptions)
endif ()
endif () endif ()
add_test(compile-test ${CMAKE_CTEST_COMMAND} add_test(compile-test ${CMAKE_CTEST_COMMAND}

View File

@ -62,7 +62,7 @@ OutputRedirect::OutputRedirect(FILE *file) : file_(file) {
write_end.dup2(fd); write_end.dup2(fd);
} }
OutputRedirect::~OutputRedirect() FMT_NOEXCEPT(true) { OutputRedirect::~OutputRedirect() FMT_NOEXCEPT {
try { try {
restore(); restore();
} catch (const std::exception &e) { } catch (const std::exception &e) {

View File

@ -104,7 +104,7 @@ class OutputRedirect {
public: public:
explicit OutputRedirect(FILE *file); explicit OutputRedirect(FILE *file);
~OutputRedirect() FMT_NOEXCEPT(true); ~OutputRedirect() FMT_NOEXCEPT;
// Restores the original file, reads output from the pipe into a string // Restores the original file, reads output from the pipe into a string
// and returns it. // and returns it.

View File

@ -699,8 +699,7 @@ void test_count_digits() {
} }
TEST(UtilTest, StringRef) { TEST(UtilTest, StringRef) {
char space[100]; char space[100] = "some string";
std::strcpy(space, "some string");
EXPECT_EQ(sizeof("some string") - 1, StringRef(space).size()); EXPECT_EQ(sizeof("some string") - 1, StringRef(space).size());
} }