mirror of
https://github.com/vimpunk/mio.git
synced 2025-12-06 16:57:01 +08:00
converted mio to templatize the char type
This commit is contained in:
parent
fbc24fa73c
commit
1a88259c02
@ -37,11 +37,18 @@
|
|||||||
namespace mio {
|
namespace mio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename CharT> struct basic_mmap;
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||||
|
|
||||||
size_t page_size();
|
size_t page_size();
|
||||||
|
|
||||||
struct mmap
|
template<typename CharT> struct basic_mmap
|
||||||
{
|
{
|
||||||
using value_type = char;
|
using value_type = CharT;
|
||||||
using size_type = int64_t;
|
using size_type = int64_t;
|
||||||
using reference = value_type&;
|
using reference = value_type&;
|
||||||
using const_reference = const value_type&;
|
using const_reference = const value_type&;
|
||||||
@ -93,12 +100,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
mmap() = default;
|
basic_mmap() = default;
|
||||||
mmap(const mmap&) = delete;
|
basic_mmap(const basic_mmap&) = delete;
|
||||||
mmap& operator=(const mmap&) = delete;
|
basic_mmap& operator=(const basic_mmap&) = delete;
|
||||||
mmap(mmap&&);
|
basic_mmap(basic_mmap&&);
|
||||||
mmap& operator=(mmap&&);
|
basic_mmap& operator=(basic_mmap&&);
|
||||||
~mmap();
|
~basic_mmap();
|
||||||
|
|
||||||
handle_type file_handle() const noexcept { return file_handle_; }
|
handle_type file_handle() const noexcept { return file_handle_; }
|
||||||
handle_type mapping_handle() const noexcept;
|
handle_type mapping_handle() const noexcept;
|
||||||
@ -107,9 +114,10 @@ public:
|
|||||||
bool is_mapped() const noexcept;
|
bool is_mapped() const noexcept;
|
||||||
bool empty() const noexcept { return length() == 0; }
|
bool empty() const noexcept { return length() == 0; }
|
||||||
|
|
||||||
size_type size() const noexcept { return length_; }
|
// TODO return the number of BYTES or the number of times sizeof(CharT) fits into length_?
|
||||||
size_type length() const noexcept { return length_; }
|
size_type size() const noexcept { return length_ >> sizeof(CharT); }
|
||||||
size_type mapped_length() const noexcept { return mapped_length_; }
|
size_type length() const noexcept { return length_ >> sizeof(CharT); }
|
||||||
|
size_type mapped_length() const noexcept { return mapped_length_ >> sizeof(CharT); }
|
||||||
|
|
||||||
pointer data() noexcept { return data_; }
|
pointer data() noexcept { return data_; }
|
||||||
const_pointer data() const noexcept { return data_; }
|
const_pointer data() const noexcept { return data_; }
|
||||||
@ -134,19 +142,19 @@ public:
|
|||||||
const_reference operator[](const size_type i) const noexcept { return data_[i]; }
|
const_reference operator[](const size_type i) const noexcept { return data_[i]; }
|
||||||
|
|
||||||
template<typename String>
|
template<typename String>
|
||||||
void map(const String& path, const size_type offset, const size_type length,
|
void map(String& path, size_type offset, size_type length,
|
||||||
const access_mode mode, std::error_code& error);
|
access_mode mode, std::error_code& error);
|
||||||
void map(const handle_type handle, const size_type offset, const size_type length,
|
void map(handle_type handle, size_type offset, size_type length,
|
||||||
const access_mode mode, std::error_code& error);
|
access_mode mode, std::error_code& error);
|
||||||
void unmap();
|
void unmap();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void sync(std::error_code& error);
|
void sync(std::error_code& error);
|
||||||
|
|
||||||
void swap(mmap& other);
|
void swap(basic_mmap& other);
|
||||||
|
|
||||||
friend bool operator==(const mmap& a, const mmap& b);
|
friend bool operator==<CharT>(const basic_mmap& a, const basic_mmap& b);
|
||||||
friend bool operator!=(const mmap& a, const mmap& b);
|
friend bool operator!=<CharT>(const basic_mmap& a, const basic_mmap& b);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@ -37,6 +37,8 @@
|
|||||||
namespace mio {
|
namespace mio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
using handle_type = basic_mmap<char>::handle_type;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
inline DWORD int64_high(int64_t n) noexcept
|
inline DWORD int64_high(int64_t n) noexcept
|
||||||
{
|
{
|
||||||
@ -64,11 +66,11 @@ inline size_t page_size()
|
|||||||
return page_size;
|
return page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t make_page_aligned(size_t offset) noexcept
|
inline size_t make_page_aligned(size_t t) noexcept
|
||||||
{
|
{
|
||||||
const static size_t page_size_ = page_size();
|
const static size_t page_size_ = page_size();
|
||||||
// Use integer division to round down to the nearest page alignment.
|
// Use integer division to round down to the nearest page alignment.
|
||||||
return offset / page_size_ * page_size_;
|
return t / page_size_ * page_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::error_code last_error() noexcept
|
inline std::error_code last_error() noexcept
|
||||||
@ -83,8 +85,8 @@ inline std::error_code last_error() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Path>
|
template<typename Path>
|
||||||
mmap::handle_type open_file(const Path& path,
|
handle_type open_file(const Path& path,
|
||||||
const mmap::access_mode mode, std::error_code& error)
|
const basic_mmap<char>::access_mode mode, std::error_code& error)
|
||||||
{
|
{
|
||||||
error.clear();
|
error.clear();
|
||||||
if(detail::empty(path))
|
if(detail::empty(path))
|
||||||
@ -94,7 +96,7 @@ mmap::handle_type open_file(const Path& path,
|
|||||||
}
|
}
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
const auto handle = ::CreateFile(c_str(path),
|
const auto handle = ::CreateFile(c_str(path),
|
||||||
mode == mmap::access_mode::read_only
|
mode == basic_mmap<char>::access_mode::read_only
|
||||||
? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
0,
|
0,
|
||||||
@ -103,7 +105,7 @@ mmap::handle_type open_file(const Path& path,
|
|||||||
0);
|
0);
|
||||||
#else
|
#else
|
||||||
const auto handle = ::open(c_str(path),
|
const auto handle = ::open(c_str(path),
|
||||||
mode == mmap::access_mode::read_only ? O_RDONLY : O_RDWR);
|
mode == basic_mmap<char>::access_mode::read_only ? O_RDONLY : O_RDWR);
|
||||||
#endif
|
#endif
|
||||||
if(handle == INVALID_HANDLE_VALUE)
|
if(handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@ -112,7 +114,7 @@ mmap::handle_type open_file(const Path& path,
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mmap::size_type query_file_size(mmap::handle_type handle, std::error_code& error)
|
int64_t query_file_size(handle_type handle, std::error_code& error)
|
||||||
{
|
{
|
||||||
error.clear();
|
error.clear();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -122,7 +124,7 @@ inline mmap::size_type query_file_size(mmap::handle_type handle, std::error_code
|
|||||||
error = last_error();
|
error = last_error();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return static_cast<mmap::size_type>(file_size.QuadPart);
|
return static_cast<int64_t>(file_size.QuadPart);
|
||||||
#else
|
#else
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
if(::fstat(handle, &sbuf) == -1)
|
if(::fstat(handle, &sbuf) == -1)
|
||||||
@ -134,14 +136,16 @@ inline mmap::size_type query_file_size(mmap::handle_type handle, std::error_code
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- mmap --
|
// -- basic_mmap --
|
||||||
|
|
||||||
inline mmap::~mmap()
|
template<typename CharT>
|
||||||
|
basic_mmap<CharT>::~basic_mmap()
|
||||||
{
|
{
|
||||||
unmap();
|
unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mmap::mmap(mmap&& other)
|
template<typename CharT>
|
||||||
|
basic_mmap<CharT>::basic_mmap(basic_mmap<CharT>&& other)
|
||||||
: data_(std::move(other.data_))
|
: data_(std::move(other.data_))
|
||||||
, length_(std::move(other.length_))
|
, length_(std::move(other.length_))
|
||||||
, mapped_length_(std::move(other.mapped_length_))
|
, mapped_length_(std::move(other.mapped_length_))
|
||||||
@ -159,7 +163,8 @@ inline mmap::mmap(mmap&& other)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mmap& mmap::operator=(mmap&& other)
|
template<typename CharT>
|
||||||
|
basic_mmap<CharT>& basic_mmap<CharT>::operator=(basic_mmap<CharT>&& other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
@ -174,7 +179,7 @@ inline mmap& mmap::operator=(mmap&& other)
|
|||||||
#endif
|
#endif
|
||||||
is_handle_internal_ = std::move(other.is_handle_internal_);
|
is_handle_internal_ = std::move(other.is_handle_internal_);
|
||||||
|
|
||||||
// The moved from mmap's fields need to be reset, because otherwise other's
|
// The moved from basic_mmap's fields need to be reset, because otherwise other's
|
||||||
// destructor will unmap the same mapping that was just moved into this.
|
// destructor will unmap the same mapping that was just moved into this.
|
||||||
other.data_ = nullptr;
|
other.data_ = nullptr;
|
||||||
other.length_ = other.mapped_length_ = 0;
|
other.length_ = other.mapped_length_ = 0;
|
||||||
@ -187,7 +192,9 @@ inline mmap& mmap::operator=(mmap&& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mmap::handle_type mmap::mapping_handle() const noexcept
|
template<typename CharT>
|
||||||
|
typename basic_mmap<CharT>::handle_type
|
||||||
|
basic_mmap<CharT>::mapping_handle() const noexcept
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return file_mapping_handle_;
|
return file_mapping_handle_;
|
||||||
@ -196,9 +203,10 @@ inline mmap::handle_type mmap::mapping_handle() const noexcept
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
template<typename String>
|
template<typename String>
|
||||||
void mmap::map(const String& path, const size_type offset, const size_type length,
|
void basic_mmap<CharT>::map(String& path, size_type offset,
|
||||||
const access_mode mode, std::error_code& error)
|
size_type length, access_mode mode, std::error_code& error)
|
||||||
{
|
{
|
||||||
error.clear();
|
error.clear();
|
||||||
if(detail::empty(path))
|
if(detail::empty(path))
|
||||||
@ -216,8 +224,9 @@ void mmap::map(const String& path, const size_type offset, const size_type lengt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mmap::map(const handle_type handle, const size_type offset,
|
template<typename CharT>
|
||||||
size_type length, const access_mode mode, std::error_code& error)
|
void basic_mmap<CharT>::map(handle_type handle, size_type offset,
|
||||||
|
size_type length, access_mode mode, std::error_code& error)
|
||||||
{
|
{
|
||||||
error.clear();
|
error.clear();
|
||||||
if(handle == INVALID_HANDLE_VALUE)
|
if(handle == INVALID_HANDLE_VALUE)
|
||||||
@ -244,7 +253,8 @@ inline void mmap::map(const handle_type handle, const size_type offset,
|
|||||||
map(offset, length, mode, error);
|
map(offset, length, mode, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mmap::map(const size_type offset, const size_type length,
|
template<typename CharT>
|
||||||
|
void basic_mmap<CharT>::map(const size_type offset, const size_type length,
|
||||||
const access_mode mode, std::error_code& error)
|
const access_mode mode, std::error_code& error)
|
||||||
{
|
{
|
||||||
const size_type aligned_offset = make_page_aligned(offset);
|
const size_type aligned_offset = make_page_aligned(offset);
|
||||||
@ -279,7 +289,7 @@ inline void mmap::map(const size_type offset, const size_type length,
|
|||||||
const pointer mapping_start = static_cast<pointer>(::mmap(
|
const pointer mapping_start = static_cast<pointer>(::mmap(
|
||||||
0, // Don't give hint as to where to map.
|
0, // Don't give hint as to where to map.
|
||||||
length_to_map,
|
length_to_map,
|
||||||
mode == mmap::access_mode::read_only ? PROT_READ : PROT_WRITE,
|
mode == basic_mmap<CharT>::access_mode::read_only ? PROT_READ : PROT_WRITE,
|
||||||
MAP_SHARED, // TODO do we want to share it?
|
MAP_SHARED, // TODO do we want to share it?
|
||||||
file_handle_,
|
file_handle_,
|
||||||
aligned_offset));
|
aligned_offset));
|
||||||
@ -294,7 +304,8 @@ inline void mmap::map(const size_type offset, const size_type length,
|
|||||||
mapped_length_ = length_to_map;
|
mapped_length_ = length_to_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mmap::sync(std::error_code& error)
|
template<typename CharT>
|
||||||
|
void basic_mmap<CharT>::sync(std::error_code& error)
|
||||||
{
|
{
|
||||||
error.clear();
|
error.clear();
|
||||||
if(!is_open())
|
if(!is_open())
|
||||||
@ -324,7 +335,8 @@ inline void mmap::sync(std::error_code& error)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mmap::unmap()
|
template<typename CharT>
|
||||||
|
void basic_mmap<CharT>::unmap()
|
||||||
{
|
{
|
||||||
if(!is_open()) { return; }
|
if(!is_open()) { return; }
|
||||||
// TODO do we care about errors here?
|
// TODO do we care about errors here?
|
||||||
@ -341,7 +353,7 @@ inline void mmap::unmap()
|
|||||||
|
|
||||||
// If file handle was obtained by our opening it (when map is called with a path,
|
// If file handle was obtained by our opening it (when map is called with a path,
|
||||||
// rather than an existing file handle), we need to close it, otherwise it must not
|
// rather than an existing file handle), we need to close it, otherwise it must not
|
||||||
// be closed as it may still be used outside of this mmap instance.
|
// be closed as it may still be used outside of this basic_mmap instance.
|
||||||
if(is_handle_internal_)
|
if(is_handle_internal_)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -360,19 +372,22 @@ inline void mmap::unmap()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mmap::pointer mmap::get_mapping_start() noexcept
|
template<typename CharT>
|
||||||
|
typename basic_mmap<CharT>::pointer basic_mmap<CharT>::get_mapping_start() noexcept
|
||||||
{
|
{
|
||||||
if(!data_) { return nullptr; }
|
if(!data_) { return nullptr; }
|
||||||
const auto offset = mapped_length_ - length_;
|
const auto offset = mapped_length_ - length_;
|
||||||
return data_ - offset;
|
return data_ - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool mmap::is_open() const noexcept
|
template<typename CharT>
|
||||||
|
bool basic_mmap<CharT>::is_open() const noexcept
|
||||||
{
|
{
|
||||||
return file_handle_ != INVALID_HANDLE_VALUE;
|
return file_handle_ != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool mmap::is_mapped() const noexcept
|
template<typename CharT>
|
||||||
|
bool basic_mmap<CharT>::is_mapped() const noexcept
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return file_mapping_handle_ != INVALID_HANDLE_VALUE;
|
return file_mapping_handle_ != INVALID_HANDLE_VALUE;
|
||||||
@ -381,7 +396,8 @@ inline bool mmap::is_mapped() const noexcept
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void mmap::swap(mmap& other)
|
template<typename CharT>
|
||||||
|
void basic_mmap<CharT>::swap(basic_mmap<CharT>& other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
@ -397,7 +413,8 @@ inline void mmap::swap(mmap& other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const mmap& a, const mmap& b)
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||||
{
|
{
|
||||||
if(a.is_mapped() && b.is_mapped())
|
if(a.is_mapped() && b.is_mapped())
|
||||||
{
|
{
|
||||||
@ -406,7 +423,8 @@ inline bool operator==(const mmap& a, const mmap& b)
|
|||||||
return !a.is_mapped() && !b.is_mapped();
|
return !a.is_mapped() && !b.is_mapped();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const mmap& a, const mmap& b)
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,26 +28,26 @@
|
|||||||
namespace mio {
|
namespace mio {
|
||||||
|
|
||||||
/** A read-only file memory mapping. */
|
/** A read-only file memory mapping. */
|
||||||
class mmap_source
|
template<typename CharT> class basic_mmap_source
|
||||||
{
|
{
|
||||||
using impl_type = detail::mmap;
|
using impl_type = detail::basic_mmap<CharT>;
|
||||||
impl_type impl_;
|
impl_type impl_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using value_type = impl_type::value_type;
|
using value_type = typename impl_type::value_type;
|
||||||
using size_type = impl_type::size_type;
|
using size_type = typename impl_type::size_type;
|
||||||
using reference = impl_type::reference;
|
using reference = typename impl_type::reference;
|
||||||
using const_reference = impl_type::const_reference;
|
using const_reference = typename impl_type::const_reference;
|
||||||
using pointer = impl_type::pointer;
|
using pointer = typename impl_type::pointer;
|
||||||
using const_pointer = impl_type::const_pointer;
|
using const_pointer = typename impl_type::const_pointer;
|
||||||
using difference_type = impl_type::difference_type;
|
using difference_type = typename impl_type::difference_type;
|
||||||
using iterator = impl_type::iterator;
|
using iterator = typename impl_type::iterator;
|
||||||
using const_iterator = impl_type::const_iterator;
|
using const_iterator = typename impl_type::const_iterator;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
using iterator_category = impl_type::iterator_category;
|
using iterator_category = typename impl_type::iterator_category;
|
||||||
using handle_type = impl_type::handle_type;
|
using handle_type = typename impl_type::handle_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This value may be provided as the `length` parameter to the constructor or
|
* This value may be provided as the `length` parameter to the constructor or
|
||||||
@ -60,7 +60,7 @@ public:
|
|||||||
* operations that attempt to access nonexistent underlying date will result in
|
* operations that attempt to access nonexistent underlying date will result in
|
||||||
* undefined behaviour/segmentation faults.
|
* undefined behaviour/segmentation faults.
|
||||||
*/
|
*/
|
||||||
mmap_source() = default;
|
basic_mmap_source() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `handle` must be a valid file handle, which is then used to memory map the
|
* `handle` must be a valid file handle, which is then used to memory map the
|
||||||
@ -73,7 +73,7 @@ public:
|
|||||||
* returned by `data` or `begin`), so long as `offset` is valid, will be at `offset`
|
* returned by `data` or `begin`), so long as `offset` is valid, will be at `offset`
|
||||||
* from the start of the file.
|
* from the start of the file.
|
||||||
*/
|
*/
|
||||||
mmap_source(const handle_type handle, const size_type offset, const size_type length)
|
basic_mmap_source(const handle_type handle, const size_type offset, const size_type length)
|
||||||
{
|
{
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
map(handle, offset, length, error);
|
map(handle, offset, length, error);
|
||||||
@ -84,11 +84,11 @@ public:
|
|||||||
* This class has single-ownership semantics, so transferring ownership may only be
|
* This class has single-ownership semantics, so transferring ownership may only be
|
||||||
* accomplished by moving the object.
|
* accomplished by moving the object.
|
||||||
*/
|
*/
|
||||||
mmap_source(mmap_source&&) = default;
|
basic_mmap_source(basic_mmap_source&&) = default;
|
||||||
mmap_source& operator=(mmap_source&&) = default;
|
basic_mmap_source& operator=(basic_mmap_source&&) = default;
|
||||||
|
|
||||||
/** The destructor invokes unmap. */
|
/** The destructor invokes unmap. */
|
||||||
~mmap_source() = default;
|
~basic_mmap_source() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows,
|
* On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows,
|
||||||
@ -206,40 +206,40 @@ public:
|
|||||||
*/
|
*/
|
||||||
void unmap() { impl_.unmap(); }
|
void unmap() { impl_.unmap(); }
|
||||||
|
|
||||||
void swap(mmap_source& other) { impl_.swap(other.impl_); }
|
void swap(basic_mmap_source& other) { impl_.swap(other.impl_); }
|
||||||
|
|
||||||
friend bool operator==(const mmap_source& a, const mmap_source& b)
|
friend bool operator==(const basic_mmap_source& a, const basic_mmap_source& b)
|
||||||
{
|
{
|
||||||
return a.impl_ == b.impl_;
|
return a.impl_ == b.impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const mmap_source& a, const mmap_source& b)
|
friend bool operator!=(const basic_mmap_source& a, const basic_mmap_source& b)
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A read-write file memory mapping. */
|
/** A read-write file memory mapping. */
|
||||||
class mmap_sink
|
template<typename CharT> class basic_mmap_sink
|
||||||
{
|
{
|
||||||
using impl_type = detail::mmap;
|
using impl_type = detail::basic_mmap<CharT>;
|
||||||
impl_type impl_;
|
impl_type impl_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using value_type = impl_type::value_type;
|
using value_type = typename impl_type::value_type;
|
||||||
using size_type = impl_type::size_type;
|
using size_type = typename impl_type::size_type;
|
||||||
using reference = impl_type::reference;
|
using reference = typename impl_type::reference;
|
||||||
using const_reference = impl_type::const_reference;
|
using const_reference = typename impl_type::const_reference;
|
||||||
using pointer = impl_type::pointer;
|
using pointer = typename impl_type::pointer;
|
||||||
using const_pointer = impl_type::const_pointer;
|
using const_pointer = typename impl_type::const_pointer;
|
||||||
using difference_type = impl_type::difference_type;
|
using difference_type = typename impl_type::difference_type;
|
||||||
using iterator = impl_type::iterator;
|
using iterator = typename impl_type::iterator;
|
||||||
using const_iterator = impl_type::const_iterator;
|
using const_iterator = typename impl_type::const_iterator;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
using iterator_category = impl_type::iterator_category;
|
using iterator_category = typename impl_type::iterator_category;
|
||||||
using handle_type = impl_type::handle_type;
|
using handle_type = typename impl_type::handle_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This value may be provided as the `length` parameter to the constructor or
|
* This value may be provided as the `length` parameter to the constructor or
|
||||||
@ -252,7 +252,7 @@ public:
|
|||||||
* operations that attempt to access nonexistent underlying date will result in
|
* operations that attempt to access nonexistent underlying date will result in
|
||||||
* undefined behaviour/segmentation faults.
|
* undefined behaviour/segmentation faults.
|
||||||
*/
|
*/
|
||||||
mmap_sink() = default;
|
basic_mmap_sink() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `handle` must be a valid file handle, which is then used to memory map the
|
* `handle` must be a valid file handle, which is then used to memory map the
|
||||||
@ -265,7 +265,7 @@ public:
|
|||||||
* returned by `data` or `begin`), so long as `offset` is valid, will be at `offset`
|
* returned by `data` or `begin`), so long as `offset` is valid, will be at `offset`
|
||||||
* from the start of the file.
|
* from the start of the file.
|
||||||
*/
|
*/
|
||||||
mmap_sink(const handle_type handle, const size_type offset, const size_type length)
|
basic_mmap_sink(const handle_type handle, const size_type offset, const size_type length)
|
||||||
{
|
{
|
||||||
std::error_code error;
|
std::error_code error;
|
||||||
map(handle, offset, length, error);
|
map(handle, offset, length, error);
|
||||||
@ -276,15 +276,15 @@ public:
|
|||||||
* This class has single-ownership semantics, so transferring ownership may only be
|
* This class has single-ownership semantics, so transferring ownership may only be
|
||||||
* accomplished by moving the object.
|
* accomplished by moving the object.
|
||||||
*/
|
*/
|
||||||
mmap_sink(mmap_sink&&) = default;
|
basic_mmap_sink(basic_mmap_sink&&) = default;
|
||||||
mmap_sink& operator=(mmap_sink&&) = default;
|
basic_mmap_sink& operator=(basic_mmap_sink&&) = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The destructor invokes unmap, but does NOT invoke `sync`. Thus, if the mapped
|
* The destructor invokes unmap, but does NOT invoke `sync`. Thus, if the mapped
|
||||||
* region has been written to, `sync` needs to be called in order to persist the
|
* region has been written to, `sync` needs to be called in order to persist the
|
||||||
* changes to disk.
|
* changes to disk.
|
||||||
*/
|
*/
|
||||||
~mmap_sink() = default;
|
~basic_mmap_sink() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows,
|
* On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows,
|
||||||
@ -411,19 +411,25 @@ public:
|
|||||||
/** Flushes the memory mapped page to disk. */
|
/** Flushes the memory mapped page to disk. */
|
||||||
void sync(std::error_code& error) { impl_.sync(error); }
|
void sync(std::error_code& error) { impl_.sync(error); }
|
||||||
|
|
||||||
void swap(mmap_sink& other) { impl_.swap(other.impl_); }
|
void swap(basic_mmap_sink& other) { impl_.swap(other.impl_); }
|
||||||
|
|
||||||
friend bool operator==(const mmap_sink& a, const mmap_sink& b)
|
friend bool operator==(const basic_mmap_sink& a, const basic_mmap_sink& b)
|
||||||
{
|
{
|
||||||
return a.impl_ == b.impl_;
|
return a.impl_ == b.impl_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator!=(const mmap_sink& a, const mmap_sink& b)
|
friend bool operator!=(const basic_mmap_sink& a, const basic_mmap_sink& b)
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using mmap_source = basic_mmap_source<char>;
|
||||||
|
using ummap_source = basic_mmap_source<unsigned char>;
|
||||||
|
|
||||||
|
using mmap_sink = basic_mmap_sink<char>;
|
||||||
|
using ummap_sink = basic_mmap_sink<unsigned char>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience factory method.
|
* Convenience factory method.
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user