diff --git a/include/mio/detail/mmap.ipp b/include/mio/detail/mmap.ipp index 1618ef1..beba9d7 100644 --- a/include/mio/detail/mmap.ipp +++ b/include/mio/detail/mmap.ipp @@ -185,15 +185,15 @@ inline mmap_context memory_map(const file_handle_type file_handle, const int64_t // -- basic_mmap -- -template -basic_mmap::~basic_mmap() +template +basic_mmap::~basic_mmap() { conditional_sync(); unmap(); } -template -basic_mmap::basic_mmap(basic_mmap&& other) +template +basic_mmap::basic_mmap(basic_mmap&& other) : data_(std::move(other.data_)) , length_(std::move(other.length_)) , mapped_length_(std::move(other.mapped_length_)) @@ -211,9 +211,9 @@ basic_mmap::basic_mmap(basic_mmap&& other) #endif } -template -basic_mmap& -basic_mmap::operator=(basic_mmap&& other) +template +basic_mmap& +basic_mmap::operator=(basic_mmap&& other) { if(this != &other) { @@ -242,9 +242,9 @@ basic_mmap::operator=(basic_mmap&& other) return *this; } -template -typename basic_mmap::handle_type -basic_mmap::mapping_handle() const noexcept +template +typename basic_mmap::handle_type +basic_mmap::mapping_handle() const noexcept { #ifdef _WIN32 return file_mapping_handle_; @@ -253,9 +253,9 @@ basic_mmap::mapping_handle() const noexcept #endif } -template +template template -void basic_mmap::map(const String& path, const size_type offset, +void basic_mmap::map(const String& path, const size_type offset, const size_type length, std::error_code& error) { error.clear(); @@ -278,8 +278,8 @@ void basic_mmap::map(const String& path, const size_type offs } } -template -void basic_mmap::map(const handle_type handle, +template +void basic_mmap::map(const handle_type handle, const size_type offset, const size_type length, std::error_code& error) { error.clear(); @@ -323,9 +323,9 @@ void basic_mmap::map(const handle_type handle, } } -template +template template -void basic_mmap::sync(std::error_code& error) +void basic_mmap::sync(std::error_code& error) { error.clear(); if(!is_open()) @@ -355,8 +355,8 @@ void basic_mmap::sync(std::error_code& error) #endif } -template -void basic_mmap::unmap() +template +void basic_mmap::unmap() { if(!is_open()) { return; } // TODO do we care about errors here? @@ -391,8 +391,8 @@ void basic_mmap::unmap() #endif } -template -bool basic_mmap::is_mapped() const noexcept +template +bool basic_mmap::is_mapped() const noexcept { #ifdef _WIN32 return file_mapping_handle_ != invalid_handle; @@ -401,8 +401,8 @@ bool basic_mmap::is_mapped() const noexcept #endif } -template -void basic_mmap::swap(basic_mmap& other) +template +void basic_mmap::swap(basic_mmap& other) { if(this != &other) { @@ -418,47 +418,47 @@ void basic_mmap::swap(basic_mmap& other) } } -template -bool operator==(const basic_mmap& a, - const basic_mmap& b) +template +bool operator==(const basic_mmap& a, + const basic_mmap& b) { return a.data() == b.data() && a.size() == b.size(); } -template -bool operator!=(const basic_mmap& a, - const basic_mmap& b) +template +bool operator!=(const basic_mmap& a, + const basic_mmap& b) { return !(a == b); } -template -bool operator<(const basic_mmap& a, - const basic_mmap& b) +template +bool operator<(const basic_mmap& a, + const basic_mmap& b) { if(a.data() == b.data()) { return a.size() < b.size(); } return a.data() < b.data(); } -template -bool operator<=(const basic_mmap& a, - const basic_mmap& b) +template +bool operator<=(const basic_mmap& a, + const basic_mmap& b) { return !(a > b); } -template -bool operator>(const basic_mmap& a, - const basic_mmap& b) +template +bool operator>(const basic_mmap& a, + const basic_mmap& b) { if(a.data() == b.data()) { return a.size() > b.size(); } return a.data() > b.data(); } -template -bool operator>=(const basic_mmap& a, - const basic_mmap& b) +template +bool operator>=(const basic_mmap& a, + const basic_mmap& b) { return !(a < b); } diff --git a/include/mio/mmap.hpp b/include/mio/mmap.hpp index 855fefa..ae4958f 100644 --- a/include/mio/mmap.hpp +++ b/include/mio/mmap.hpp @@ -53,8 +53,17 @@ using file_handle_type = int; // determine whether `basic_mmap::file_handle` is valid, for example. constexpr static file_handle_type invalid_handle = INVALID_HANDLE_VALUE; -template -struct basic_mmap +// `basic_mmap`'s constructor syncs changes to disk if it's in write mode, but +// some user's may prefer the absence of this feature and instead syncing +// manually. This optional template parameter may be used to change this +// beharior. +enum class dtor_policy { sync, no_sync, }; + +template< + access_mode AccessMode, + typename ByteT, + dtor_policy DtorPolicy = dtor_policy::sync +> struct basic_mmap { using value_type = ByteT; using size_type = int64_t; @@ -70,7 +79,8 @@ struct basic_mmap using iterator_category = std::random_access_iterator_tag; using handle_type = file_handle_type; - static_assert(sizeof(ByteT) == sizeof(char), "ByteT must be the same size as char."); + static_assert(sizeof(ByteT) == sizeof(char), + "ByteT must be the same size as char."); private: // Points to the first requested byte, and not to the actual start of the mapping. @@ -331,50 +341,64 @@ private: * if it's `read`, but since the destructor cannot be templated, we need to * do SFINAE in a dedicated function, where one syncs and the other is a noop. */ - template::type> - void conditional_sync() { sync(); } - template - typename std::enable_if::type conditional_sync() {} + template< + access_mode A = AccessMode, + dtor_policy D = DtorPolicy, + typename = typename std::enable_if< + A == access_mode::write and D == dtor_policy::sync + >::type + > void conditional_sync() + { + // Not much we can do about errors in the destructor. + std::error_code ec; + sync(ec); + } + + template< + access_mode A = AccessMode, + dtor_policy D = DtorPolicy + > typename std::enable_if< + A == access_mode::read or D == dtor_policy::no_sync, void + >::type conditional_sync() {} }; -template -bool operator==(const basic_mmap& a, - const basic_mmap& b); +template +bool operator==(const basic_mmap& a, + const basic_mmap& b); -template -bool operator!=(const basic_mmap& a, - const basic_mmap& b); +template +bool operator!=(const basic_mmap& a, + const basic_mmap& b); -template -bool operator<(const basic_mmap& a, - const basic_mmap& b); +template +bool operator<(const basic_mmap& a, + const basic_mmap& b); -template -bool operator<=(const basic_mmap& a, - const basic_mmap& b); +template +bool operator<=(const basic_mmap& a, + const basic_mmap& b); -template -bool operator>(const basic_mmap& a, - const basic_mmap& b); +template +bool operator>(const basic_mmap& a, + const basic_mmap& b); -template -bool operator>=(const basic_mmap& a, - const basic_mmap& b); +template +bool operator>=(const basic_mmap& a, + const basic_mmap& b); /** * This is the basis for all read-only mmap objects and should be preferred over * directly using `basic_mmap`. */ -template -using basic_mmap_source = basic_mmap; +template +using basic_mmap_source = basic_mmap; /** * This is the basis for all read-write mmap objects and should be preferred over * directly using `basic_mmap`. */ -template -using basic_mmap_sink = basic_mmap; +template +using basic_mmap_sink = basic_mmap; /** * These aliases cover the most common use cases, both representing a raw byte stream diff --git a/include/mio/shared_mmap.hpp b/include/mio/shared_mmap.hpp index 7dcf74b..133b225 100644 --- a/include/mio/shared_mmap.hpp +++ b/include/mio/shared_mmap.hpp @@ -37,10 +37,11 @@ namespace mio { */ template< access_mode AccessMode, - typename ByteT + typename ByteT, + dtor_policy DtorPolicy = dtor_policy::sync > class basic_shared_mmap { - using impl_type = basic_mmap; + using impl_type = basic_mmap; std::shared_ptr pimpl_; public: @@ -344,15 +345,15 @@ private: * This is the basis for all read-only mmap objects and should be preferred over * directly using basic_shared_mmap. */ -template -using basic_shared_mmap_source = basic_shared_mmap; +template +using basic_shared_mmap_source = basic_shared_mmap; /** * This is the basis for all read-write mmap objects and should be preferred over * directly using basic_shared_mmap. */ -template -using basic_shared_mmap_sink = basic_shared_mmap; +template +using basic_shared_mmap_sink = basic_shared_mmap; /** * These aliases cover the most common use cases, both representing a raw byte stream