diff --git a/README.md b/README.md index ac35eae..826f444 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A simple header-only cross-platform C++14 memory mapping library. using offset_type = mio::mmap_source::size_type; using length_type = mio::mmap_source::size_type; -int handle_error(const std::error_code& ec) +int handle_error(const std::error_code& error) { const auto& errmsg = error.message(); std::printf("error mapping file: %s, exiting...\n", errmsg.c_str()); @@ -25,7 +25,7 @@ int main() // length of the mapping would otherwise be expected, with the factory method. std::error_code error; mio::mmap_source mmap1 = mio::make_mmap_source("log.txt", - offset_type(0), mio::mmap_source::use_full_file_size, error); + offset_type(0), mio::use_full_file_size, error); if(error) { return handle_error(error); } // Read-write memory map the beginning of some file using the `map` member function. @@ -42,10 +42,12 @@ int main() // Or just change one value with the subscript operator. mmap2[mmap2.size() / 2] = 42; - // Or map using the constructor, which throws a std::error_code upon failure. + // You can also create a mapping using the constructor, which throws a + // std::error_code upon failure. try { const auto page_size = mio::page_size(); - mio::mmap_sink mmap3("another/path/to/file", offset_type(4096), length_type(4096)); + mio::mmap_sink mmap3("another/path/to/file", + offset_type(page_size), length_type(page_size)); // ... } catch(const std::error_code& error) { return handle_error(error); diff --git a/include/mio/mmap.hpp b/include/mio/mmap.hpp index 5dc6c9c..0bfa3a9 100644 --- a/include/mio/mmap.hpp +++ b/include/mio/mmap.hpp @@ -24,6 +24,7 @@ #include "detail/basic_mmap.hpp" #include +#include // std::char_traits namespace mio { @@ -41,12 +42,12 @@ template< typename CharTraits = std::char_traits > class basic_mmap { - using impl_type = detail::basic_mmap; - impl_type impl_; - static_assert(AccessMode == access_mode::read_only || AccessMode == access_mode::read_write, "AccessMode must be either read_only or read_write"); + + using impl_type = detail::basic_mmap; + impl_type impl_; public: using value_type = typename impl_type::value_type; @@ -58,8 +59,8 @@ public: using difference_type = typename impl_type::difference_type; using iterator = typename impl_type::iterator; using const_iterator = typename impl_type::const_iterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; + using reverse_iterator = typename impl_type::reverse_iterator; + using const_reverse_iterator = typename impl_type::const_reverse_iterator; using iterator_category = typename impl_type::iterator_category; using handle_type = typename impl_type::handle_type; @@ -70,6 +71,25 @@ public: */ basic_mmap() = default; + /** + * `handle` must be a valid file handle, which is then used to memory map the + * requested region. Upon failure a `std::error_code` is thrown, detailing the + * cause of the error, and the object remains in an unmapped state. + * + * When specifying `offset`, there is no need to worry about providing + * a value that is aligned with the operating system's page allocation granularity. + * This is adjusted by the implementation such that the first requested byte (as + * returned by `data` or `begin`), so long as `offset` is valid, will be at `offset` + * from the start of the file. + */ + template + basic_mmap(const String& path, const size_type offset, const size_type length) + { + std::error_code error; + map(path, offset, length, error); + if(error) { throw error; } + } + /** * `handle` must be a valid file handle, which is then used to memory map the * requested region. Upon failure a `std::error_code` is thrown, detailing the