diff --git a/format.cc b/format.cc index 9005302c..1a6e4e22 100644 --- a/format.cc +++ b/format.cc @@ -146,7 +146,7 @@ typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef); // other - failure // Buffer should be at least of size 1. 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); int result = 0; #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, - fmt::StringRef message) FMT_NOEXCEPT(true) { + fmt::StringRef message) FMT_NOEXCEPT { // Report error code making sure that the output fits into // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential // bad_alloc. @@ -198,7 +198,7 @@ void format_error_code(fmt::Writer &out, int error_code, } 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; func(full_message, error_code, message); // 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::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT(true) { + fmt::StringRef message) FMT_NOEXCEPT { FMT_TRY { MemoryBuffer buffer; buffer.resize(INLINE_BUFFER_SIZE); @@ -522,7 +522,7 @@ FMT_FUNC void fmt::internal::format_system_error( #ifdef _WIN32 FMT_FUNC void fmt::internal::format_windows_error( fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT(true) { + fmt::StringRef message) FMT_NOEXCEPT { class String { private: LPWSTR str_; @@ -1083,13 +1083,13 @@ void fmt::BasicFormatter::format( } 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); } #ifdef _WIN32 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); } #endif diff --git a/format.h b/format.h index c6bdd707..8468f89f 100644 --- a/format.h +++ b/format.h @@ -114,16 +114,26 @@ // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) -# define FMT_NOEXCEPT(expr) noexcept(expr) +# define FMT_NOEXCEPT noexcept +# define FMT_NOEXCEPT_EXPR(expr) noexcept(expr) #else -# define FMT_NOEXCEPT(expr) +# define FMT_NOEXCEPT throw() +# define FMT_NOEXCEPT_EXPR(expr) #endif // A macro to disallow the copy constructor and operator= functions // 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) \ TypeName(const TypeName&); \ void operator=(const TypeName&) +#endif namespace fmt { @@ -290,7 +300,7 @@ class Buffer { grow(capacity); } - void clear() FMT_NOEXCEPT(true) { size_ = 0; } + void clear() FMT_NOEXCEPT { size_ = 0; } void push_back(const T &value) { if (size_ == capacity_) @@ -623,11 +633,11 @@ class UTF16ToUTF8 { #endif void format_system_error(fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT(true); + fmt::StringRef message) FMT_NOEXCEPT; #ifdef _WIN32 void format_windows_error(fmt::Writer &out, int error_code, - fmt::StringRef message) FMT_NOEXCEPT(true); + fmt::StringRef message) FMT_NOEXCEPT; #endif // 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 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 @@ -1684,7 +1694,7 @@ class BasicWriter { return *this; } - void clear() FMT_NOEXCEPT(true) { buffer_.clear(); } + void clear() FMT_NOEXCEPT { buffer_.clear(); } }; template @@ -2101,7 +2111,7 @@ void format(BasicFormatter &f, const Char *&format_str, const T &value) { // Reports a system error without throwing an exception. // 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 @@ -2144,7 +2154,7 @@ class WindowsError : public SystemError { // Reports a Windows error without throwing an exception. // 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 diff --git a/posix.cc b/posix.cc index 945fe95b..b4893cd6 100644 --- a/posix.cc +++ b/posix.cc @@ -75,7 +75,7 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; } #endif } -fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT(true) { +fmt::BufferedFile::~BufferedFile() FMT_NOEXCEPT { if (file_ && FMT_SYSTEM(fclose(file_)) != 0) 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); } -fmt::File::~File() FMT_NOEXCEPT(true) { +fmt::File::~File() FMT_NOEXCEPT { // Don't retry close in case of EINTR! // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html 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; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); if (result == -1) diff --git a/posix.h b/posix.h index a7db31a1..cce1b1b2 100644 --- a/posix.h +++ b/posix.h @@ -68,7 +68,7 @@ # define FMT_UNUSED #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) #else # define FMT_CONCAT_(a, b) FMT_CONCAT(a, b) @@ -97,9 +97,9 @@ class ErrorCode { int value_; 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. @@ -113,10 +113,10 @@ class BufferedFile { public: // 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. - ~BufferedFile() FMT_NOEXCEPT(true); + ~BufferedFile() FMT_NOEXCEPT; #if !FMT_USE_RVALUE_REFERENCES // Emulate a move constructor and a move assignment operator if rvalue @@ -131,10 +131,10 @@ class BufferedFile { public: // 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. - BufferedFile(BufferedFile &f) FMT_NOEXCEPT(true) : file_(f.file_) { + BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) { f.file_ = 0; } @@ -155,7 +155,7 @@ public: // Returns a proxy object for moving from a temporary: // BufferedFile file = BufferedFile(...); - operator Proxy() FMT_NOEXCEPT(true) { + operator Proxy() FMT_NOEXCEPT { Proxy p = {file_}; file_ = 0; return p; @@ -166,7 +166,7 @@ public: FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile); public: - BufferedFile(BufferedFile &&other) FMT_NOEXCEPT(true) : file_(other.file_) { + BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) { other.file_ = 0; } @@ -223,7 +223,7 @@ public: }; // 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 // closing the file multiple times will cause a crash on Windows rather // 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. - File() FMT_NOEXCEPT(true) : fd_(-1) {} + File() FMT_NOEXCEPT : fd_(-1) {} // Opens a file and constructs a File object representing this file. File(fmt::StringRef path, int oflag); @@ -262,10 +262,10 @@ class File { public: // 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. - File(File &other) FMT_NOEXCEPT(true) : fd_(other.fd_) { + File(File &other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; } @@ -286,7 +286,7 @@ class File { // Returns a proxy object for moving from a temporary: // File file = File(...); - operator Proxy() FMT_NOEXCEPT(true) { + operator Proxy() FMT_NOEXCEPT { Proxy p = {fd_}; fd_ = -1; return p; @@ -297,7 +297,7 @@ class File { FMT_DISALLOW_COPY_AND_ASSIGN(File); public: - File(File &&other) FMT_NOEXCEPT(true) : fd_(other.fd_) { + File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; } @@ -310,10 +310,10 @@ class File { #endif // Destroys the object closing the file it represents if any. - ~File() FMT_NOEXCEPT(true); + ~File() FMT_NOEXCEPT; // Returns the file descriptor. - int descriptor() const FMT_NOEXCEPT(true) { return fd_; } + int descriptor() const FMT_NOEXCEPT { return fd_; } // Closes the file. void close(); @@ -337,7 +337,7 @@ class File { // Makes fd be the copy of this file descriptor, closing fd first if // 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 // and writing respectively. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7be4c78b..5ab3c2eb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -64,12 +64,14 @@ set_target_properties(header-only-test PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1") target_link_libraries(header-only-test gmock) -# Test that the library can be compiled with exceptions disabled. -check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) -if (HAVE_FNO_EXCEPTIONS_FLAG) - add_library(noexception-test STATIC ../format.cc) - set_target_properties(noexception-test - PROPERTIES COMPILE_FLAGS -fno-exceptions) +if (NOT CMAKE_GENERATOR MATCHES "Visual Studio") + # Test that the library can be compiled with exceptions disabled. + check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) + if (HAVE_FNO_EXCEPTIONS_FLAG) + add_library(noexception-test STATIC ../format.cc) + set_target_properties(noexception-test + PROPERTIES COMPILE_FLAGS -fno-exceptions) + endif () endif () add_test(compile-test ${CMAKE_CTEST_COMMAND} diff --git a/test/gtest-extra.cc b/test/gtest-extra.cc index cbd4e934..93ca2193 100644 --- a/test/gtest-extra.cc +++ b/test/gtest-extra.cc @@ -62,7 +62,7 @@ OutputRedirect::OutputRedirect(FILE *file) : file_(file) { write_end.dup2(fd); } -OutputRedirect::~OutputRedirect() FMT_NOEXCEPT(true) { +OutputRedirect::~OutputRedirect() FMT_NOEXCEPT { try { restore(); } catch (const std::exception &e) { diff --git a/test/gtest-extra.h b/test/gtest-extra.h index aa03bdff..df9cb7f0 100644 --- a/test/gtest-extra.h +++ b/test/gtest-extra.h @@ -104,7 +104,7 @@ class OutputRedirect { public: explicit OutputRedirect(FILE *file); - ~OutputRedirect() FMT_NOEXCEPT(true); + ~OutputRedirect() FMT_NOEXCEPT; // Restores the original file, reads output from the pipe into a string // and returns it. diff --git a/test/util-test.cc b/test/util-test.cc index fd295525..b04cb4a9 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -699,8 +699,7 @@ void test_count_digits() { } TEST(UtilTest, StringRef) { - char space[100]; - std::strcpy(space, "some string"); + char space[100] = "some string"; EXPECT_EQ(sizeof("some string") - 1, StringRef(space).size()); }