From 40d2dcabd7e5b978c0e1e5c76000de01e2d0c270 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 29 Apr 2018 18:18:39 -0400 Subject: [PATCH 1/2] file_util: Add static assertions to ReadBytes() and WriteBytes() Ensure that the actual types being passed in are trivially copyable. The internal call to ReadArray() and WriteArray() will always succeed, since they're passed a pointer to char* which is always trivially copyable. --- src/common/file_util.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/file_util.h b/src/common/file_util.h index 4c11849eea..32ff4d8ca2 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -202,11 +202,15 @@ public: return items_written; } - size_t ReadBytes(void* data, size_t length) { + template + size_t ReadBytes(T* data, size_t length) { + static_assert(std::is_trivially_copyable(), "T must be trivially copyable"); return ReadArray(reinterpret_cast(data), length); } - size_t WriteBytes(const void* data, size_t length) { + template + size_t WriteBytes(const T* data, size_t length) { + static_assert(std::is_trivially_copyable(), "T must be trivially copyable"); return WriteArray(reinterpret_cast(data), length); } From e8bbafb746ce7e178be757471305539c05bb7f23 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 29 Apr 2018 18:29:03 -0400 Subject: [PATCH 2/2] file_util: Make move constructor/assignment operator and related functions noexcept Without this, it's possible to get compilation failures in the (rare) scenario where a container is used to store a bunch of live IOFile instances, as they may be using std::move_if_noexcept under the hood. Given these definitely don't throw exceptions this is also not incorrect to add either. --- src/common/file_util.cpp | 6 +++--- src/common/file_util.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index cd852bfd85..2d0b81c6ee 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -809,16 +809,16 @@ IOFile::~IOFile() { Close(); } -IOFile::IOFile(IOFile&& other) { +IOFile::IOFile(IOFile&& other) noexcept { Swap(other); } -IOFile& IOFile::operator=(IOFile&& other) { +IOFile& IOFile::operator=(IOFile&& other) noexcept { Swap(other); return *this; } -void IOFile::Swap(IOFile& other) { +void IOFile::Swap(IOFile& other) noexcept { std::swap(m_file, other.m_file); std::swap(m_good, other.m_good); } diff --git a/src/common/file_util.h b/src/common/file_util.h index 32ff4d8ca2..fc6b3ea466 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -160,10 +160,10 @@ public: ~IOFile(); - IOFile(IOFile&& other); - IOFile& operator=(IOFile&& other); + IOFile(IOFile&& other) noexcept; + IOFile& operator=(IOFile&& other) noexcept; - void Swap(IOFile& other); + void Swap(IOFile& other) noexcept; bool Open(const std::string& filename, const char openmode[]); bool Close();