From 40d2dcabd7e5b978c0e1e5c76000de01e2d0c270 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
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 <typename T>
+    size_t ReadBytes(T* data, size_t length) {
+        static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable");
         return ReadArray(reinterpret_cast<char*>(data), length);
     }
 
-    size_t WriteBytes(const void* data, size_t length) {
+    template <typename T>
+    size_t WriteBytes(const T* data, size_t length) {
+        static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable");
         return WriteArray(reinterpret_cast<const char*>(data), length);
     }
 

From e8bbafb746ce7e178be757471305539c05bb7f23 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
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();