mirror of
https://github.com/vimpunk/mio.git
synced 2025-12-06 16:57:01 +08:00
added a few Container ops
This commit is contained in:
parent
4583a6529e
commit
cc46c17e8f
@ -1,6 +1,9 @@
|
|||||||
#ifndef MIO_BASIC_MMAP_HEADER
|
#ifndef MIO_BASIC_MMAP_HEADER
|
||||||
#define MIO_BASIC_MMAP_HEADER
|
#define MIO_BASIC_MMAP_HEADER
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# ifndef WIN32_LEAN_AND_MEAN
|
# ifndef WIN32_LEAN_AND_MEAN
|
||||||
# define WIN32_LEAN_AND_MEAN
|
# define WIN32_LEAN_AND_MEAN
|
||||||
@ -10,14 +13,18 @@
|
|||||||
# define INVALID_HANDLE_VALUE -1
|
# define INVALID_HANDLE_VALUE -1
|
||||||
#endif // ifdef _WIN32
|
#endif // ifdef _WIN32
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace mio {
|
namespace mio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
size_t page_size();
|
size_t page_size();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Most of the logic in establishing a memory mapping is the same for both read-only and
|
* 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.
|
* read-write mappings, so they both inherit from basic_mmap.
|
||||||
@ -27,15 +34,14 @@ template<typename CharT> struct basic_mmap
|
|||||||
using value_type = CharT;
|
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 reference;
|
using const_reference = const value_type&;
|
||||||
using pointer = value_type*;
|
using pointer = value_type*;
|
||||||
using const_pointer = const pointer;
|
using const_pointer = const value_type*;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using iterator = pointer;
|
using iterator = pointer;
|
||||||
using const_iterator = const_pointer;
|
using const_iterator = const_pointer;
|
||||||
// TODO these don't seem to work with regular pointers
|
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 = std::random_access_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
using handle_type = HANDLE;
|
using handle_type = HANDLE;
|
||||||
@ -56,8 +62,7 @@ private:
|
|||||||
|
|
||||||
// On POSIX, we only need a file handle to create a mapping, while on Windows
|
// On POSIX, we only need a file handle to create a mapping, while on Windows
|
||||||
// systems the file handle is necessary to retrieve a file mapping handle, but any
|
// systems the file handle is necessary to retrieve a file mapping handle, but any
|
||||||
// subsequent operations on the mapped region must be done through the file mapping
|
// subsequent operations on the mapped region must be done through the latter.
|
||||||
// handle.
|
|
||||||
handle_type file_handle_ = INVALID_HANDLE_VALUE;
|
handle_type file_handle_ = INVALID_HANDLE_VALUE;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
handle_type file_mapping_handle_ = INVALID_HANDLE_VALUE;
|
handle_type file_mapping_handle_ = INVALID_HANDLE_VALUE;
|
||||||
@ -110,6 +115,14 @@ public:
|
|||||||
const_iterator end() const noexcept { return begin() + length(); }
|
const_iterator end() const noexcept { return begin() + length(); }
|
||||||
const_iterator cend() const noexcept { return begin() + length(); }
|
const_iterator cend() const noexcept { return begin() + length(); }
|
||||||
|
|
||||||
|
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()); }
|
||||||
|
|
||||||
|
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()); }
|
||||||
|
|
||||||
reference operator[](const size_type i) noexcept { return data_[i]; }
|
reference operator[](const size_type i) noexcept { return data_[i]; }
|
||||||
const_reference operator[](const size_type i) const noexcept { return data_[i]; }
|
const_reference operator[](const size_type i) const noexcept { return data_[i]; }
|
||||||
|
|
||||||
@ -117,11 +130,15 @@ public:
|
|||||||
const access_mode mode, std::error_code& error);
|
const access_mode mode, std::error_code& error);
|
||||||
void map(const handle_type handle, const size_type offset, const size_type length,
|
void map(const handle_type handle, const size_type offset, const size_type length,
|
||||||
const access_mode mode, std::error_code& error);
|
const access_mode mode, std::error_code& error);
|
||||||
|
|
||||||
void unmap();
|
void unmap();
|
||||||
|
|
||||||
void sync(std::error_code& error);
|
void sync(std::error_code& error);
|
||||||
|
|
||||||
|
void swap(basic_mmap& other);
|
||||||
|
|
||||||
|
friend bool operator==<CharT>(const basic_mmap& a, const basic_mmap& b);
|
||||||
|
friend bool operator!=<CharT>(const basic_mmap& a, const basic_mmap& b);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static handle_type open_file(const std::string& path,
|
static handle_type open_file(const std::string& path,
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "basic_mmap.hpp"
|
#include "basic_mmap.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
@ -330,6 +332,38 @@ bool basic_mmap<CharT>::is_mapped() const noexcept
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
void basic_mmap<CharT>::swap(basic_mmap<CharT>& other)
|
||||||
|
{
|
||||||
|
if(this != &other)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
swap(data_, other.data_);
|
||||||
|
swap(file_handle_, other.file_handle_);
|
||||||
|
#ifdef _WIN32
|
||||||
|
swap(file_mapping_handle_, other.file_mapping_handle_);
|
||||||
|
#endif
|
||||||
|
swap(length_, other.length_);
|
||||||
|
swap(mapped_length_, other.mapped_length_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||||
|
{
|
||||||
|
if(a.is_mapped() && b.is_mapped())
|
||||||
|
{
|
||||||
|
return (a.size() == b.size()) && std::equal(a.begin(), a.end(), b.begin());
|
||||||
|
}
|
||||||
|
return !a.is_mapped() && !b.is_mapped();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||||
|
{
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace mio
|
} // namespace mio
|
||||||
|
|
||||||
|
|||||||
@ -76,6 +76,30 @@ void basic_mmap_sink<CharT>::map(const handle_type handle, const size_type offse
|
|||||||
template<typename CharT>
|
template<typename CharT>
|
||||||
void basic_mmap_sink<CharT>::sync(std::error_code& error) { impl_.sync(error); }
|
void basic_mmap_sink<CharT>::sync(std::error_code& error) { impl_.sync(error); }
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap_source<CharT>& a, const basic_mmap_source<CharT>& b)
|
||||||
|
{
|
||||||
|
return a.impl_ == b.impl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap_source<CharT>& a, const basic_mmap_source<CharT>& b)
|
||||||
|
{
|
||||||
|
return a.impl_ != b.impl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap_sink<CharT>& a, const basic_mmap_sink<CharT>& b)
|
||||||
|
{
|
||||||
|
return a.impl_ == b.impl_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap_sink<CharT>& a, const basic_mmap_sink<CharT>& b)
|
||||||
|
{
|
||||||
|
return a.impl_ != b.impl_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mio
|
} // namespace mio
|
||||||
|
|
||||||
#endif // MIO_MMAP_IMPL
|
#endif // MIO_MMAP_IMPL
|
||||||
|
|||||||
@ -5,6 +5,18 @@
|
|||||||
|
|
||||||
namespace mio {
|
namespace mio {
|
||||||
|
|
||||||
|
template<typename CharT> class basic_mmap_source;
|
||||||
|
template<typename CharT> class basic_mmap_sink;
|
||||||
|
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap_source<CharT>& a, const basic_mmap_source<CharT>& b);
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap_source<CharT>& a, const basic_mmap_source<CharT>& b);
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator==(const basic_mmap_sink<CharT>& a, const basic_mmap_sink<CharT>& b);
|
||||||
|
template<typename CharT>
|
||||||
|
bool operator!=(const basic_mmap_sink<CharT>& a, const basic_mmap_sink<CharT>& b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When specifying a file to map, there is no need to worry about providing
|
* 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
|
* offsets that are aligned with the operating system's page granularity, this is taken
|
||||||
@ -23,9 +35,13 @@ namespace mio {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** A read-only file memory mapping. */
|
/** A read-only file memory mapping. */
|
||||||
template<typename CharT> struct basic_mmap_source
|
template<typename CharT> class basic_mmap_source
|
||||||
{
|
{
|
||||||
using impl_type = detail::basic_mmap<CharT>;
|
using impl_type = detail::basic_mmap<CharT>;
|
||||||
|
impl_type impl_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
using value_type = typename impl_type::value_type;
|
using value_type = typename impl_type::value_type;
|
||||||
using size_type = typename impl_type::size_type;
|
using size_type = typename impl_type::size_type;
|
||||||
using reference = typename impl_type::reference;
|
using reference = typename impl_type::reference;
|
||||||
@ -35,15 +51,11 @@ template<typename CharT> struct basic_mmap_source
|
|||||||
using difference_type = typename impl_type::difference_type;
|
using difference_type = typename impl_type::difference_type;
|
||||||
using iterator = typename impl_type::iterator;
|
using iterator = typename impl_type::iterator;
|
||||||
using const_iterator = typename 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 = typename impl_type::iterator_category;
|
using iterator_category = typename impl_type::iterator_category;
|
||||||
using handle_type = typename impl_type::handle_type;
|
using handle_type = typename impl_type::handle_type;
|
||||||
|
|
||||||
private:
|
|
||||||
impl_type impl_;
|
|
||||||
public:
|
|
||||||
|
|
||||||
basic_mmap_source() = default;
|
basic_mmap_source() = default;
|
||||||
basic_mmap_source(const std::string& path,
|
basic_mmap_source(const std::string& path,
|
||||||
const size_type offset, const size_type length);
|
const size_type offset, const size_type length);
|
||||||
@ -80,20 +92,33 @@ public:
|
|||||||
const_iterator end() const noexcept { return impl_.end(); }
|
const_iterator end() const noexcept { return impl_.end(); }
|
||||||
const_iterator cend() const noexcept { return impl_.cend(); }
|
const_iterator cend() const noexcept { return impl_.cend(); }
|
||||||
|
|
||||||
|
const_reverse_iterator rbegin() const noexcept { return impl_.rbegin(); }
|
||||||
|
const_reverse_iterator crbegin() const noexcept { return impl_.crbegin(); }
|
||||||
|
const_reverse_iterator rend() const noexcept { return impl_.rend(); }
|
||||||
|
const_reverse_iterator crend() const noexcept { return impl_.crend(); }
|
||||||
|
|
||||||
const_reference operator[](const size_type i) const noexcept { return impl_[i]; }
|
const_reference operator[](const size_type i) const noexcept { return impl_[i]; }
|
||||||
|
|
||||||
void map(const std::string& path, const size_type offset,
|
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);
|
||||||
void map(const handle_type handle, const size_type offset,
|
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);
|
||||||
|
|
||||||
void unmap() { impl_.unmap(); }
|
void unmap() { impl_.unmap(); }
|
||||||
|
|
||||||
|
void swap(basic_mmap_source& other) { impl_.swap(other.impl_); }
|
||||||
|
|
||||||
|
friend bool operator==<CharT>(const basic_mmap_source& a, const basic_mmap_source& b);
|
||||||
|
friend bool operator!=<CharT>(const basic_mmap_source& a, const basic_mmap_source& b);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A read-write file memory mapping. */
|
/** A read-write file memory mapping. */
|
||||||
template<typename CharT> struct basic_mmap_sink
|
template<typename CharT> class basic_mmap_sink
|
||||||
{
|
{
|
||||||
using impl_type = detail::basic_mmap<CharT>;
|
using impl_type = detail::basic_mmap<CharT>;
|
||||||
|
impl_type impl_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
using value_type = typename impl_type::value_type;
|
using value_type = typename impl_type::value_type;
|
||||||
using size_type = typename impl_type::size_type;
|
using size_type = typename impl_type::size_type;
|
||||||
using reference = typename impl_type::reference;
|
using reference = typename impl_type::reference;
|
||||||
@ -103,15 +128,11 @@ template<typename CharT> struct basic_mmap_sink
|
|||||||
using difference_type = typename impl_type::difference_type;
|
using difference_type = typename impl_type::difference_type;
|
||||||
using iterator = typename impl_type::iterator;
|
using iterator = typename impl_type::iterator;
|
||||||
using const_iterator = typename 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 = typename impl_type::iterator_category;
|
using iterator_category = typename impl_type::iterator_category;
|
||||||
using handle_type = typename impl_type::handle_type;
|
using handle_type = typename impl_type::handle_type;
|
||||||
|
|
||||||
private:
|
|
||||||
impl_type impl_;
|
|
||||||
public:
|
|
||||||
|
|
||||||
basic_mmap_sink() = default;
|
basic_mmap_sink() = default;
|
||||||
basic_mmap_sink(const std::string& path,
|
basic_mmap_sink(const std::string& path,
|
||||||
const size_type offset, const size_type length);
|
const size_type offset, const size_type length);
|
||||||
@ -144,14 +165,22 @@ public:
|
|||||||
pointer data() noexcept { return impl_.data(); }
|
pointer data() noexcept { return impl_.data(); }
|
||||||
const_pointer data() const noexcept { return impl_.data(); }
|
const_pointer data() const noexcept { return impl_.data(); }
|
||||||
|
|
||||||
iterator begin() noexcept;
|
iterator begin() noexcept { return impl_.begin(); }
|
||||||
const_iterator begin() const noexcept { return impl_.begin(); }
|
const_iterator begin() const noexcept { return impl_.begin(); }
|
||||||
const_iterator cbegin() const noexcept { return impl_.cbegin(); }
|
const_iterator cbegin() const noexcept { return impl_.cbegin(); }
|
||||||
|
|
||||||
iterator end() noexcept;
|
iterator end() noexcept { return impl_.end(); }
|
||||||
const_iterator end() const noexcept { return impl_.end(); }
|
const_iterator end() const noexcept { return impl_.end(); }
|
||||||
const_iterator cend() const noexcept { return impl_.cend(); }
|
const_iterator cend() const noexcept { return impl_.cend(); }
|
||||||
|
|
||||||
|
reverse_iterator rbegin() noexcept { return impl_.rbegin(); }
|
||||||
|
const_reverse_iterator rbegin() const noexcept { return impl_.rbegin(); }
|
||||||
|
const_reverse_iterator crbegin() const noexcept { return impl_.crbegin(); }
|
||||||
|
|
||||||
|
reverse_iterator rend() noexcept { return impl_.rend(); }
|
||||||
|
const_reverse_iterator rend() const noexcept { return impl_.rend(); }
|
||||||
|
const_reverse_iterator crend() const noexcept { return impl_.crend(); }
|
||||||
|
|
||||||
reference operator[](const size_type i) noexcept { return impl_[i]; }
|
reference operator[](const size_type i) noexcept { return impl_[i]; }
|
||||||
const_reference operator[](const size_type i) const noexcept { return impl_[i]; }
|
const_reference operator[](const size_type i) const noexcept { return impl_[i]; }
|
||||||
|
|
||||||
@ -159,11 +188,15 @@ public:
|
|||||||
const size_type length, std::error_code& error);
|
const size_type length, std::error_code& error);
|
||||||
void map(const handle_type handle, const size_type offset,
|
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);
|
||||||
|
void unmap() { impl_.unmap(); }
|
||||||
|
|
||||||
/** Flushes the memory mapped page to disk. */
|
/** Flushes the memory mapped page to disk. */
|
||||||
void sync(std::error_code& error);
|
void sync(std::error_code& error);
|
||||||
|
|
||||||
void unmap() { impl_.unmap(); }
|
void swap(basic_mmap_sink& other) { impl_.swap(other.impl_); }
|
||||||
|
|
||||||
|
friend bool operator==<CharT>(const basic_mmap_sink& a, const basic_mmap_sink& b);
|
||||||
|
friend bool operator!=<CharT>(const basic_mmap_sink& a, const basic_mmap_sink& b);
|
||||||
};
|
};
|
||||||
|
|
||||||
using mmap_sink = basic_mmap_sink<char>;
|
using mmap_sink = basic_mmap_sink<char>;
|
||||||
|
|||||||
@ -39,4 +39,7 @@ int main(int argc, char** argv)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto rit = file_view.rbegin();
|
||||||
|
auto rend = file_view.rend();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user