From cede64f865d9bbd24e532792bee744ac6283f248 Mon Sep 17 00:00:00 2001 From: mandreyel Date: Wed, 20 Sep 2017 13:12:17 +0200 Subject: [PATCH] minor changes --- include/mio/detail/mmap.ipp | 105 ----------- .../detail/{basic_mmap.hpp => mmap_impl.hpp} | 42 ++--- .../detail/{basic_mmap.ipp => mmap_impl.ipp} | 69 +++---- include/mio/mmap.hpp | 174 ++++++++++-------- test/test.cpp | 11 +- 5 files changed, 143 insertions(+), 258 deletions(-) delete mode 100644 include/mio/detail/mmap.ipp rename include/mio/detail/{basic_mmap.hpp => mmap_impl.hpp} (80%) rename include/mio/detail/{basic_mmap.ipp => mmap_impl.ipp} (78%) diff --git a/include/mio/detail/mmap.ipp b/include/mio/detail/mmap.ipp deleted file mode 100644 index 1720a10..0000000 --- a/include/mio/detail/mmap.ipp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef MIO_MMAP_IMPL -#define MIO_MMAP_IMPL - -#include "../mmap.hpp" - -namespace mio { - -// -- basic_mmap_source -- - -template -basic_mmap_source::basic_mmap_source(const std::string& path, - const size_type offset, const size_type length) -{ - std::error_code error; - map(path, offset, length, error); - if(error) { throw error; } -} - -template -basic_mmap_source::basic_mmap_source(const handle_type handle, - const size_type offset, const size_type length) -{ - std::error_code error; - map(handle, offset, length, error); - if(error) { throw error; } -} - -template -void basic_mmap_source::map(const std::string& path, const size_type offset, - const size_type length, std::error_code& error) -{ - impl_.map(path, offset, length, impl_type::access_mode::read_only, error); -} - -template -void basic_mmap_source::map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error) -{ - impl_.map(handle, offset, length, impl_type::access_mode::read_only, error); -} - -// -- basic_mmap_sink -- - -template -basic_mmap_sink::basic_mmap_sink(const std::string& path, - const size_type offset, const size_type length) -{ - std::error_code error; - map(path, offset, length, error); - if(error) { throw error; } -} - -template -basic_mmap_sink::basic_mmap_sink(const handle_type handle, - const size_type offset, const size_type length) -{ - std::error_code error; - map(handle, offset, length, error); - if(error) { throw error; } -} - -template -void basic_mmap_sink::map(const std::string& path, const size_type offset, - const size_type length, std::error_code& error) -{ - impl_.map(path, offset, length, impl_type::access_mode::read_only, error); -} - -template -void basic_mmap_sink::map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error) -{ - impl_.map(handle, offset, length, impl_type::access_mode::read_write, error); -} - -template -void basic_mmap_sink::sync(std::error_code& error) { impl_.sync(error); } - -template -bool operator==(const basic_mmap_source& a, const basic_mmap_source& b) -{ - return a.impl_ == b.impl_; -} - -template -bool operator!=(const basic_mmap_source& a, const basic_mmap_source& b) -{ - return a.impl_ != b.impl_; -} - -template -bool operator==(const basic_mmap_sink& a, const basic_mmap_sink& b) -{ - return a.impl_ == b.impl_; -} - -template -bool operator!=(const basic_mmap_sink& a, const basic_mmap_sink& b) -{ - return a.impl_ != b.impl_; -} - -} // namespace mio - -#endif // MIO_MMAP_IMPL diff --git a/include/mio/detail/basic_mmap.hpp b/include/mio/detail/mmap_impl.hpp similarity index 80% rename from include/mio/detail/basic_mmap.hpp rename to include/mio/detail/mmap_impl.hpp index 84afbe2..ea6e802 100644 --- a/include/mio/detail/basic_mmap.hpp +++ b/include/mio/detail/mmap_impl.hpp @@ -18,20 +18,9 @@ namespace detail { size_t page_size(); -template struct basic_mmap; - -template -bool operator==(const basic_mmap& a, const basic_mmap& b); -template -bool operator!=(const basic_mmap& a, const basic_mmap& b); - -/** - * Most of the logic in establishing a memory mapping is the same for both read-only and - * read-write mappings, so they both inherit from basic_mmap. - */ -template struct basic_mmap +struct mmap { - using value_type = CharT; + using value_type = char; using size_type = int64_t; using reference = value_type&; using const_reference = const value_type&; @@ -68,18 +57,19 @@ private: handle_type file_mapping_handle_ = INVALID_HANDLE_VALUE; #endif - // Length requested by user, which may not be the length of the full mapping. + // Length, in bytes, requested by user, which may not be the length of the full + // mapping. size_type length_ = 0; size_type mapped_length_ = 0; public: - basic_mmap() = default; - basic_mmap(const basic_mmap&) = delete; - basic_mmap& operator=(const basic_mmap&) = delete; - basic_mmap(basic_mmap&&); - basic_mmap& operator=(basic_mmap&&); - ~basic_mmap(); + mmap() = default; + mmap(const mmap&) = delete; + mmap& operator=(const mmap&) = delete; + mmap(mmap&&); + mmap& operator=(mmap&&); + ~mmap(); /** * On *nix systems is_open and is_mapped are the same and don't actually say if @@ -117,11 +107,11 @@ public: reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator rcbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - const_reverse_iterator rcend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } reference operator[](const size_type i) noexcept { return data_[i]; } const_reference operator[](const size_type i) const noexcept { return data_[i]; } @@ -134,10 +124,10 @@ public: void sync(std::error_code& error); - void swap(basic_mmap& other); + void swap(mmap& other); - friend bool operator==(const basic_mmap& a, const basic_mmap& b); - friend bool operator!=(const basic_mmap& a, const basic_mmap& b); + friend bool operator==(const mmap& a, const mmap& b); + friend bool operator!=(const mmap& a, const mmap& b); private: @@ -158,6 +148,6 @@ private: } // namespace detail } // namespace mio -#include "basic_mmap.ipp" +#include "mmap_impl.ipp" #endif // MIO_BASIC_MMAP_HEADER diff --git a/include/mio/detail/basic_mmap.ipp b/include/mio/detail/mmap_impl.ipp similarity index 78% rename from include/mio/detail/basic_mmap.ipp rename to include/mio/detail/mmap_impl.ipp index 16bf267..3e708f7 100644 --- a/include/mio/detail/basic_mmap.ipp +++ b/include/mio/detail/mmap_impl.ipp @@ -1,7 +1,7 @@ #ifndef MIO_BASIC_MMAP_IMPL #define MIO_BASIC_MMAP_IMPL -#include "basic_mmap.hpp" +#include "mmap_impl.hpp" #include @@ -23,11 +23,11 @@ inline DWORD int64_high(int64_t n) noexcept inline DWORD int64_low(int64_t n) noexcept { - return n & 0xFF'FF'FF'FF; + return n & 0xff'ff'ff'ff; } #endif -size_t page_size() +inline size_t page_size() { static const size_t page_size = [] { @@ -60,16 +60,14 @@ inline std::error_code last_error() noexcept return error; } -// -- basic_mmap -- +// -- mmap -- -template -basic_mmap::~basic_mmap() +inline mmap::~mmap() { unmap(); } -template -basic_mmap::basic_mmap(basic_mmap&& other) +inline mmap::mmap(mmap&& other) : data_(std::move(other.data_)) , length_(std::move(other.length_)) , mapped_length_(std::move(other.mapped_length_)) @@ -86,8 +84,7 @@ basic_mmap::basic_mmap(basic_mmap&& other) #endif } -template -basic_mmap& basic_mmap::operator=(basic_mmap&& other) +inline mmap& mmap::operator=(mmap&& other) { if(this != &other) { @@ -108,8 +105,7 @@ basic_mmap& basic_mmap::operator=(basic_mmap&& other) return *this; } -template -void basic_mmap::map(const std::string& path, const size_type offset, +inline void mmap::map(const std::string& path, const size_type offset, const size_type length, const access_mode mode, std::error_code& error) { if(!path.empty() && !is_open()) @@ -121,14 +117,12 @@ void basic_mmap::map(const std::string& path, const size_type offset, } } -template -typename basic_mmap::handle_type -basic_mmap::open_file(const std::string& path, - const basic_mmap::access_mode mode, std::error_code& error) +inline mmap::handle_type mmap::open_file(const std::string& path, + const mmap::access_mode mode, std::error_code& error) { #if defined(_WIN32) const auto handle = ::CreateFile(path.c_str(), - mode == basic_mmap::access_mode::read_only + mode == mmap::access_mode::read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, @@ -141,7 +135,7 @@ basic_mmap::open_file(const std::string& path, } #else const auto handle = ::open(path.c_str(), - mode == basic_mmap::access_mode::read_only ? O_RDONLY : O_RDWR); + mode == mmap::access_mode::read_only ? O_RDONLY : O_RDWR); if(handle == -1) { error = last_error(); @@ -150,8 +144,7 @@ basic_mmap::open_file(const std::string& path, return handle; } -template -void basic_mmap::map(const handle_type handle, const size_type offset, +inline void mmap::map(const handle_type handle, const size_type offset, const size_type length, const access_mode mode, std::error_code& error) { error.clear(); @@ -175,8 +168,7 @@ void basic_mmap::map(const handle_type handle, const size_type offset, map(offset, length, mode, error); } -template -void basic_mmap::map(const size_type offset, const size_type length, +inline void mmap::map(const size_type offset, const size_type length, const access_mode mode, std::error_code& error) { const size_type aligned_offset = make_page_aligned(offset); @@ -211,7 +203,7 @@ void basic_mmap::map(const size_type offset, const size_type length, const pointer mapping_start = static_cast(::mmap( 0, // don't give hint as to where to map length_to_map, - mode == basic_mmap::access_mode::read_only ? PROT_READ : PROT_WRITE, + mode == mmap::access_mode::read_only ? PROT_READ : PROT_WRITE, MAP_SHARED, // TODO do we want to share it? file_handle_, aligned_offset)); @@ -226,8 +218,7 @@ void basic_mmap::map(const size_type offset, const size_type length, mapped_length_ = length_to_map; } -template -void basic_mmap::sync(std::error_code& error) +inline void mmap::sync(std::error_code& error) { error.clear(); verify_file_handle(error); @@ -254,8 +245,7 @@ void basic_mmap::sync(std::error_code& error) #endif } -template -void basic_mmap::unmap() +inline void mmap::unmap() { // TODO do we care about errors here? if((data_ != nullptr) && (file_handle_ != INVALID_HANDLE_VALUE)) @@ -276,9 +266,7 @@ void basic_mmap::unmap() #endif } -template -typename basic_mmap::size_type -basic_mmap::query_file_size(std::error_code& error) noexcept +inline mmap::size_type mmap::query_file_size(std::error_code& error) noexcept { #ifdef _WIN32 PLARGE_INTEGER file_size; @@ -299,16 +287,14 @@ basic_mmap::query_file_size(std::error_code& error) noexcept #endif } -template -typename basic_mmap::pointer basic_mmap::get_mapping_start() noexcept +inline mmap::pointer mmap::get_mapping_start() noexcept { if(!data_) { return nullptr; } const auto offset = mapped_length_ - length_; return data_ - offset; } -template -void basic_mmap::verify_file_handle(std::error_code& error) const noexcept +inline void mmap::verify_file_handle(std::error_code& error) const noexcept { if(!is_open() || !is_mapped()) { @@ -316,14 +302,12 @@ void basic_mmap::verify_file_handle(std::error_code& error) const noexcep } } -template -bool basic_mmap::is_open() const noexcept +inline bool mmap::is_open() const noexcept { return file_handle_ != INVALID_HANDLE_VALUE; } -template -bool basic_mmap::is_mapped() const noexcept +inline bool mmap::is_mapped() const noexcept { #ifdef _WIN32 return file_mapping_handle_ != INVALID_HANDLE_VALUE; @@ -332,8 +316,7 @@ bool basic_mmap::is_mapped() const noexcept #endif } -template -void basic_mmap::swap(basic_mmap& other) +inline void mmap::swap(mmap& other) { if(this != &other) { @@ -348,8 +331,7 @@ void basic_mmap::swap(basic_mmap& other) } } -template -bool operator==(const basic_mmap& a, const basic_mmap& b) +inline bool operator==(const mmap& a, const mmap& b) { if(a.is_mapped() && b.is_mapped()) { @@ -358,8 +340,7 @@ bool operator==(const basic_mmap& a, const basic_mmap& b) return !a.is_mapped() && !b.is_mapped(); } -template -bool operator!=(const basic_mmap& a, const basic_mmap& b) +inline bool operator!=(const mmap& a, const mmap& b) { return !(a == b); } diff --git a/include/mio/mmap.hpp b/include/mio/mmap.hpp index 673d217..da1dbde 100644 --- a/include/mio/mmap.hpp +++ b/include/mio/mmap.hpp @@ -1,22 +1,10 @@ #ifndef MIO_MMAP_HEADER #define MIO_MMAP_HEADER -#include "detail/basic_mmap.hpp" +#include "detail/mmap_impl.hpp" namespace mio { -template class basic_mmap_source; -template class basic_mmap_sink; - -template -bool operator==(const basic_mmap_source& a, const basic_mmap_source& b); -template -bool operator!=(const basic_mmap_source& a, const basic_mmap_source& b); -template -bool operator==(const basic_mmap_sink& a, const basic_mmap_sink& b); -template -bool operator!=(const basic_mmap_sink& a, const basic_mmap_sink& b); - /** * When specifying a file to map, there is no need to worry about providing * offsets that are aligned with the operating system's page granularity, this is taken @@ -35,32 +23,41 @@ bool operator!=(const basic_mmap_sink& a, const basic_mmap_sink& b */ /** A read-only file memory mapping. */ -template class basic_mmap_source +class mmap_source { - using impl_type = detail::basic_mmap; + using impl_type = detail::mmap; impl_type impl_; public: - using value_type = typename impl_type::value_type; - using size_type = typename impl_type::size_type; - using reference = typename impl_type::reference; - using const_reference = typename impl_type::const_reference; - using pointer = typename impl_type::pointer; - using const_pointer = typename impl_type::const_pointer; - using difference_type = typename impl_type::difference_type; - using iterator = typename impl_type::iterator; - using const_iterator = typename impl_type::const_iterator; + using value_type = impl_type::value_type; + using size_type = impl_type::size_type; + using reference = impl_type::reference; + using const_reference = impl_type::const_reference; + using pointer = impl_type::pointer; + using const_pointer = impl_type::const_pointer; + using difference_type = impl_type::difference_type; + using iterator = impl_type::iterator; + using const_iterator = impl_type::const_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - using iterator_category = typename impl_type::iterator_category; - using handle_type = typename impl_type::handle_type; + using iterator_category = impl_type::iterator_category; + using handle_type = impl_type::handle_type; - basic_mmap_source() = default; - basic_mmap_source(const std::string& path, - const size_type offset, const size_type length); - basic_mmap_source(const handle_type handle, - const size_type offset, const size_type length); + mmap_source() = default; + mmap_source(const std::string& path, const size_type offset, const size_type length) + { + std::error_code error; + map(path, offset, length, error); + if(error) { throw error; } + } + + mmap_source(const handle_type handle, const size_type offset, const size_type length) + { + std::error_code error; + map(handle, offset, length, error); + if(error) { throw error; } + } /** * On *nix systems is_open and is_mapped are the same and don't actually say if @@ -74,7 +71,7 @@ public: */ bool is_open() const noexcept { return impl_.is_open(); } bool is_mapped() const noexcept { return impl_.is_mapped(); } - bool empty() const noexcept { return impl_.is_empty(); } + bool empty() const noexcept { return impl_.empty(); } /** * size/length returns the logical length (i.e. the one user requested), while @@ -100,44 +97,68 @@ public: const_reference operator[](const size_type i) const noexcept { return impl_[i]; } void map(const std::string& path, const size_type offset, - const size_type length, std::error_code& error); + const size_type length, std::error_code& error) + { + impl_.map(path, offset, length, impl_type::access_mode::read_only, error); + } + void map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error); + const size_type length, std::error_code& error) + { + impl_.map(handle, offset, length, impl_type::access_mode::read_only, error); + } + void unmap() { impl_.unmap(); } - void swap(basic_mmap_source& other) { impl_.swap(other.impl_); } + void swap(mmap_source& other) { impl_.swap(other.impl_); } - friend bool operator==(const basic_mmap_source& a, const basic_mmap_source& b); - friend bool operator!=(const basic_mmap_source& a, const basic_mmap_source& b); + friend bool operator==(const mmap_source& a, const mmap_source& b) + { + return a.impl_ == b.impl_; + } + + friend bool operator!=(const mmap_source& a, const mmap_source& b) + { + return !(a == b); + } }; /** A read-write file memory mapping. */ -template class basic_mmap_sink +class mmap_sink { - using impl_type = detail::basic_mmap; + using impl_type = detail::mmap; impl_type impl_; public: - using value_type = typename impl_type::value_type; - using size_type = typename impl_type::size_type; - using reference = typename impl_type::reference; - using const_reference = typename impl_type::const_reference; - using pointer = typename impl_type::pointer; - using const_pointer = typename impl_type::const_pointer; - using difference_type = typename impl_type::difference_type; - using iterator = typename impl_type::iterator; - using const_iterator = typename impl_type::const_iterator; + using value_type = impl_type::value_type; + using size_type = impl_type::size_type; + using reference = impl_type::reference; + using const_reference = impl_type::const_reference; + using pointer = impl_type::pointer; + using const_pointer = impl_type::const_pointer; + using difference_type = impl_type::difference_type; + using iterator = impl_type::iterator; + using const_iterator = impl_type::const_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - using iterator_category = typename impl_type::iterator_category; - using handle_type = typename impl_type::handle_type; + using iterator_category = impl_type::iterator_category; + using handle_type = impl_type::handle_type; - basic_mmap_sink() = default; - basic_mmap_sink(const std::string& path, - const size_type offset, const size_type length); - basic_mmap_sink(const handle_type handle, - const size_type offset, const size_type length); + mmap_sink() = default; + mmap_sink(const std::string& path, const size_type offset, const size_type length) + { + std::error_code error; + map(path, offset, length, error); + if(error) { throw error; } + } + + mmap_sink(const handle_type handle, const size_type offset, const size_type length) + { + std::error_code error; + map(handle, offset, length, error); + if(error) { throw error; } + } /** * On *nix systems is_open and is_mapped are the same and don't actually say if @@ -151,7 +172,7 @@ public: */ bool is_open() const noexcept { return impl_.is_open(); } bool is_mapped() const noexcept { return impl_.is_mapped(); } - bool empty() const noexcept { return impl_.is_empty(); } + bool empty() const noexcept { return impl_.empty(); } /** * size/length returns the logical length (i.e. the one user requested), while @@ -185,34 +206,35 @@ public: const_reference operator[](const size_type i) const noexcept { return impl_[i]; } void map(const std::string& path, const size_type offset, - const size_type length, std::error_code& error); + const size_type length, std::error_code& error) + { + impl_.map(path, offset, length, impl_type::access_mode::read_only, error); + } + void map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error); + const size_type length, std::error_code& error) + { + impl_.map(handle, offset, length, impl_type::access_mode::read_write, error); + } + void unmap() { impl_.unmap(); } /** Flushes the memory mapped page to disk. */ - void sync(std::error_code& error); + void sync(std::error_code& error) { impl_.sync(error); } - void swap(basic_mmap_sink& other) { impl_.swap(other.impl_); } + void swap(mmap_sink& other) { impl_.swap(other.impl_); } - friend bool operator==(const basic_mmap_sink& a, const basic_mmap_sink& b); - friend bool operator!=(const basic_mmap_sink& a, const basic_mmap_sink& b); + friend bool operator==(const mmap_sink& a, const mmap_sink& b) + { + return a.impl_ == b.impl_; + } + + friend bool operator!=(const mmap_sink& a, const mmap_sink& b) + { + return !(a == b); + } }; -using mmap_sink = basic_mmap_sink; -using mmap_source = basic_mmap_source; - -using wmmap_sink = basic_mmap_sink; -using wmmap_source = basic_mmap_source; - -using u16mmap_sink = basic_mmap_sink; -using u16mmap_source = basic_mmap_source; - -using u32mmap_sink = basic_mmap_sink; -using u32mmap_source = basic_mmap_source; - } // namespace mio -#include "detail/mmap.ipp" - #endif // MIO_MMAP_HEADER diff --git a/test/test.cpp b/test/test.cpp index 0b9020b..ca24ab1 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -8,17 +8,17 @@ int main(int argc, char** argv) { - const char* path = argc >= 2 ? argv[1] : "."; + const char* test_file_name = argc >= 2 ? argv[1] : "test-file"; - std::error_code error; std::string buffer(0x4000 - 250, 'M'); - std::ofstream file(path); + std::ofstream file(test_file_name); file << buffer; file.close(); + std::error_code error; mio::mmap_source file_view; - file_view.map(path, 0, buffer.size(), error); + file_view.map(test_file_name, 0, buffer.size(), error); if(error) { const auto& errmsg = error.message(); @@ -39,7 +39,4 @@ int main(int argc, char** argv) assert(0); } } - - auto rit = file_view.rbegin(); - auto rend = file_view.rend(); }