mirror of
https://github.com/vimpunk/mio.git
synced 2025-12-06 16:57:01 +08:00
removed CharTraits
This commit is contained in:
parent
54694df5f7
commit
c52e35b2e8
10
README.md
10
README.md
@ -21,11 +21,11 @@ int handle_error(const std::error_code& error)
|
||||
|
||||
int main()
|
||||
{
|
||||
// Read-only memory map the whole file by using `use_full_file_size` where the
|
||||
// Read-only memory map the whole file by using `map_entire_file` where the
|
||||
// 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::use_full_file_size, error);
|
||||
offset_type(0), length_type(mio::map_entire_file), error);
|
||||
if(error) { return handle_error(error); }
|
||||
|
||||
// Read-write memory map the beginning of some file using the `map` member function.
|
||||
@ -53,9 +53,11 @@ int main()
|
||||
return handle_error(error);
|
||||
}
|
||||
|
||||
// mio exposes an interface that abstracts away memory as a string, so it is
|
||||
// possible to create mmap objects that have custom underlying character types:
|
||||
// It's possible to change the character type of the mmap object, which is useful
|
||||
// for wide strings or reading fixed width integers (although endianness is not
|
||||
// accounted for by mio, so appropriate conversions need be done by the user).
|
||||
using wmmap_source = mio::basic_mmap_source<wchar_t>;
|
||||
using i32mmap_source = mio::basic_mmap_source<int32_t>;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
namespace mio {
|
||||
namespace detail {
|
||||
|
||||
enum { use_full_file_size = 0 };
|
||||
enum { map_entire_file = 0 };
|
||||
|
||||
enum class access_mode
|
||||
{
|
||||
@ -45,10 +45,7 @@ enum class access_mode
|
||||
read_write
|
||||
};
|
||||
|
||||
template<
|
||||
typename CharT,
|
||||
typename CharTraits = std::char_traits<CharT>
|
||||
> struct basic_mmap
|
||||
template<typename CharT> struct basic_mmap
|
||||
{
|
||||
using value_type = CharT;
|
||||
using size_type = int64_t;
|
||||
@ -77,7 +74,7 @@ private:
|
||||
// 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 latter.
|
||||
handle_type file_handle_ = INVALID_HANDLE_VALUE;
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
handle_type file_mapping_handle_ = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
|
||||
@ -108,8 +105,9 @@ public:
|
||||
bool is_mapped() const noexcept;
|
||||
bool empty() const noexcept { return length() == 0; }
|
||||
|
||||
size_type length() const noexcept { return length_ >> sizeof(CharT); }
|
||||
size_type mapped_length() const noexcept { return mapped_length_ >> sizeof(CharT); }
|
||||
size_type length() const noexcept { return length_ >> (sizeof(CharT) - 1); }
|
||||
size_type mapped_length() const noexcept
|
||||
{ return mapped_length_ >> (sizeof(CharT) - 1); }
|
||||
|
||||
pointer data() noexcept { return data_; }
|
||||
const_pointer data() const noexcept { return data_; }
|
||||
@ -153,29 +151,23 @@ private:
|
||||
const access_mode mode, std::error_code& error);
|
||||
};
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator==(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator==(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator!=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator!=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator<(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator<(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator<=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator<=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator>(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator>(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator>=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b);
|
||||
template<typename CharT>
|
||||
bool operator>=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b);
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mio
|
||||
|
||||
@ -41,7 +41,7 @@ namespace detail {
|
||||
// Generic handle type for use by free functions.
|
||||
using handle_type = basic_mmap<char>::handle_type;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
inline DWORD int64_high(int64_t n) noexcept
|
||||
{
|
||||
return n >> 32;
|
||||
@ -73,7 +73,7 @@ handle_type open_file(const Path& path, const access_mode mode, std::error_code&
|
||||
error = std::make_error_code(std::errc::invalid_argument);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
const auto handle = ::CreateFile(c_str(path),
|
||||
mode == access_mode::read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
@ -116,14 +116,14 @@ inline int64_t query_file_size(handle_type handle, std::error_code& error)
|
||||
|
||||
// -- basic_mmap --
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
basic_mmap<CharT, CharTraits>::~basic_mmap()
|
||||
template<typename CharT>
|
||||
basic_mmap<CharT>::~basic_mmap()
|
||||
{
|
||||
unmap();
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
basic_mmap<CharT, CharTraits>::basic_mmap(basic_mmap<CharT, CharTraits>&& other)
|
||||
template<typename CharT>
|
||||
basic_mmap<CharT>::basic_mmap(basic_mmap<CharT>&& other)
|
||||
: data_(std::move(other.data_))
|
||||
, length_(std::move(other.length_))
|
||||
, mapped_length_(std::move(other.mapped_length_))
|
||||
@ -141,8 +141,8 @@ basic_mmap<CharT, CharTraits>::basic_mmap(basic_mmap<CharT, CharTraits>&& other)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
basic_mmap<CharT, CharTraits>& basic_mmap<CharT, CharTraits>::operator=(basic_mmap<CharT, CharTraits>&& other)
|
||||
template<typename CharT>
|
||||
basic_mmap<CharT>& basic_mmap<CharT>::operator=(basic_mmap<CharT>&& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
@ -170,9 +170,9 @@ basic_mmap<CharT, CharTraits>& basic_mmap<CharT, CharTraits>::operator=(basic_mm
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
typename basic_mmap<CharT, CharTraits>::handle_type
|
||||
basic_mmap<CharT, CharTraits>::mapping_handle() const noexcept
|
||||
template<typename CharT>
|
||||
typename basic_mmap<CharT>::handle_type
|
||||
basic_mmap<CharT>::mapping_handle() const noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return file_mapping_handle_;
|
||||
@ -181,9 +181,9 @@ basic_mmap<CharT, CharTraits>::mapping_handle() const noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
template<typename CharT>
|
||||
template<typename String>
|
||||
void basic_mmap<CharT, CharTraits>::map(String& path, size_type offset,
|
||||
void basic_mmap<CharT>::map(String& path, size_type offset,
|
||||
size_type length, access_mode mode, std::error_code& error)
|
||||
{
|
||||
error.clear();
|
||||
@ -202,8 +202,8 @@ void basic_mmap<CharT, CharTraits>::map(String& path, size_type offset,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
void basic_mmap<CharT, CharTraits>::map(handle_type handle, size_type offset,
|
||||
template<typename CharT>
|
||||
void basic_mmap<CharT>::map(handle_type handle, size_type offset,
|
||||
size_type length, access_mode mode, std::error_code& error)
|
||||
{
|
||||
error.clear();
|
||||
@ -216,7 +216,7 @@ void basic_mmap<CharT, CharTraits>::map(handle_type handle, size_type offset,
|
||||
const auto file_size = query_file_size(handle, error);
|
||||
if(error) { return; }
|
||||
|
||||
if(length <= use_full_file_size)
|
||||
if(length <= map_entire_file)
|
||||
{
|
||||
length = file_size;
|
||||
}
|
||||
@ -231,13 +231,13 @@ void basic_mmap<CharT, CharTraits>::map(handle_type handle, size_type offset,
|
||||
map(offset, length, mode, error);
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
void basic_mmap<CharT, CharTraits>::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 size_type aligned_offset = make_offset_page_aligned(offset);
|
||||
const size_type length_to_map = offset - aligned_offset + length;
|
||||
#if defined(_WIN32)
|
||||
#ifdef _WIN32
|
||||
const size_type max_file_size = offset + length;
|
||||
file_mapping_handle_ = ::CreateFileMapping(
|
||||
file_handle_,
|
||||
@ -282,8 +282,8 @@ void basic_mmap<CharT, CharTraits>::map(const size_type offset, const size_type
|
||||
mapped_length_ = length_to_map;
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
void basic_mmap<CharT, CharTraits>::sync(std::error_code& error)
|
||||
template<typename CharT>
|
||||
void basic_mmap<CharT>::sync(std::error_code& error)
|
||||
{
|
||||
error.clear();
|
||||
if(!is_open())
|
||||
@ -313,8 +313,8 @@ void basic_mmap<CharT, CharTraits>::sync(std::error_code& error)
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
void basic_mmap<CharT, CharTraits>::unmap()
|
||||
template<typename CharT>
|
||||
void basic_mmap<CharT>::unmap()
|
||||
{
|
||||
if(!is_open()) { return; }
|
||||
// TODO do we care about errors here?
|
||||
@ -350,23 +350,23 @@ void basic_mmap<CharT, CharTraits>::unmap()
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
typename basic_mmap<CharT, CharTraits>::pointer
|
||||
basic_mmap<CharT, CharTraits>::get_mapping_start() noexcept
|
||||
template<typename CharT>
|
||||
typename basic_mmap<CharT>::pointer
|
||||
basic_mmap<CharT>::get_mapping_start() noexcept
|
||||
{
|
||||
if(!data_) { return nullptr; }
|
||||
const auto offset = mapped_length_ - length_;
|
||||
return data_ - offset;
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool basic_mmap<CharT, CharTraits>::is_open() const noexcept
|
||||
template<typename CharT>
|
||||
bool basic_mmap<CharT>::is_open() const noexcept
|
||||
{
|
||||
return file_handle_ != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool basic_mmap<CharT, CharTraits>::is_mapped() const noexcept
|
||||
template<typename CharT>
|
||||
bool basic_mmap<CharT>::is_mapped() const noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return file_mapping_handle_ != INVALID_HANDLE_VALUE;
|
||||
@ -375,8 +375,8 @@ bool basic_mmap<CharT, CharTraits>::is_mapped() const noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
void basic_mmap<CharT, CharTraits>::swap(basic_mmap<CharT, CharTraits>& other)
|
||||
template<typename CharT>
|
||||
void basic_mmap<CharT>::swap(basic_mmap<CharT>& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
@ -392,49 +392,43 @@ void basic_mmap<CharT, CharTraits>::swap(basic_mmap<CharT, CharTraits>& other)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator==(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator==(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return a.size() == b.size()
|
||||
&& CharTraits::compare(a.data(), b.data(), a.size()) == 0;
|
||||
return a.data() == b.data()
|
||||
&& a.size() == b.size();
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator!=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator!=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator<(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator<(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return CharTraits::compare(a.data(), b.data(), a.size()) < 0;
|
||||
if(a.data() == b.data()) { return a.size() < b.size(); }
|
||||
return a.data() < b.data();
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator<=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator<=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return (a == b) || (a < b);
|
||||
return !(a > b);
|
||||
}
|
||||
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator>(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator>(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return CharTraits::compare(a.data(), b.data(), a.size()) > 0;
|
||||
if(a.data() == b.data()) { return a.size() > b.size(); }
|
||||
return a.data() > b.data();
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
template<typename CharT, typename CharTraits>
|
||||
bool operator>=(const basic_mmap<CharT, CharTraits>& a,
|
||||
const basic_mmap<CharT, CharTraits>& b)
|
||||
template<typename CharT>
|
||||
bool operator>=(const basic_mmap<CharT>& a, const basic_mmap<CharT>& b)
|
||||
{
|
||||
return (a == b) || (a > b);
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@ -34,20 +34,20 @@ using detail::access_mode;
|
||||
|
||||
// This value may be provided as the `length` parameter to the constructor or
|
||||
// `map`, in which case a memory mapping of the entire file is created.
|
||||
using detail::use_full_file_size;
|
||||
using detail::map_entire_file;
|
||||
|
||||
template<
|
||||
access_mode AccessMode,
|
||||
typename CharT,
|
||||
typename CharTraits = std::char_traits<CharT>
|
||||
typename CharT
|
||||
> class basic_mmap
|
||||
{
|
||||
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<CharT, CharTraits>;
|
||||
using impl_type = detail::basic_mmap<CharT>;
|
||||
impl_type impl_;
|
||||
|
||||
public:
|
||||
|
||||
using value_type = typename impl_type::value_type;
|
||||
@ -211,8 +211,10 @@ public:
|
||||
* from the start of the file.
|
||||
*
|
||||
* `length` must be the number of bytes to map, regardless of the underlying
|
||||
* value_type's size! If it is `use_full_file_size`, a mapping of the entire file
|
||||
* is created.
|
||||
* value_type's size. That is, if CharT is a wide char, the value returned by
|
||||
* the `size` and `length` methods is not the same as this `length` value (TODO
|
||||
* this can be confusing).
|
||||
* If it is `map_entire_file`, a mapping of the entire file is created.
|
||||
*/
|
||||
template<typename String>
|
||||
void map(const String& path, const size_type offset,
|
||||
@ -237,8 +239,10 @@ public:
|
||||
* from the start of the file.
|
||||
*
|
||||
* `length` must be the number of bytes to map, regardless of the underlying
|
||||
* value_type's size! If it is `use_full_file_size`, a mapping of the entire file
|
||||
* is created.
|
||||
* value_type's size. That is, if CharT is a wide char, the value returned by
|
||||
* the `size` and `length` methods is not the same as this `length` value (TODO
|
||||
* this can be confusing).
|
||||
* If it is `map_entire_file`, a mapping of the entire file is created.
|
||||
*/
|
||||
void map(const handle_type handle, const size_type offset,
|
||||
const size_type length, std::error_code& error)
|
||||
@ -259,14 +263,16 @@ public:
|
||||
|
||||
void swap(basic_mmap& other) { impl_.swap(other.impl_); }
|
||||
|
||||
/** Flushes the memory mapped page to disk. */
|
||||
// TODO better name?
|
||||
/** Flushes the memory mapped page to disk. Errors are reported via `error`. */
|
||||
template<
|
||||
access_mode A = AccessMode,
|
||||
typename = typename std::enable_if<A == access_mode::read_write>::type
|
||||
> void sync(std::error_code& error) { impl_.sync(error); }
|
||||
|
||||
/** All operators compare two mapped areas according to CharTraits::compare. */
|
||||
/**
|
||||
* All operators compare the address of the first byte and size of the two mapped
|
||||
* regions.
|
||||
*/
|
||||
|
||||
friend bool operator==(const basic_mmap& a, const basic_mmap& b)
|
||||
{
|
||||
@ -303,21 +309,20 @@ public:
|
||||
* This is the basis for all read-only mmap objects and should be preferred over
|
||||
* directly using basic_mmap.
|
||||
*/
|
||||
template<
|
||||
typename CharT,
|
||||
typename CharTraits = std::char_traits<CharT>
|
||||
> using basic_mmap_source = basic_mmap<access_mode::read_only, CharT, CharTraits>;
|
||||
template<typename CharT>
|
||||
using basic_mmap_source = basic_mmap<access_mode::read_only, CharT>;
|
||||
|
||||
/**
|
||||
* This is the basis for all read-write mmap objects and should be preferred over
|
||||
* directly using basic_mmap.
|
||||
*/
|
||||
template<
|
||||
typename CharT,
|
||||
typename CharTraits = std::char_traits<CharT>
|
||||
> using basic_mmap_sink = basic_mmap<access_mode::read_write, CharT, CharTraits>;
|
||||
template<typename CharT>
|
||||
using basic_mmap_sink = basic_mmap<access_mode::read_write, CharT>;
|
||||
|
||||
/** These aliases should cover the most common use cases. */
|
||||
/**
|
||||
* These aliases cover the most common use cases, both representing a raw byte stream
|
||||
* (either with a char or an unsigned char/uint8_t).
|
||||
*/
|
||||
using mmap_source = basic_mmap_source<char>;
|
||||
using ummap_source = basic_mmap_source<unsigned char>;
|
||||
|
||||
|
||||
@ -6,6 +6,13 @@
|
||||
#include <cassert>
|
||||
#include <system_error>
|
||||
|
||||
int handle_error(const std::error_code& error)
|
||||
{
|
||||
const auto& errmsg = error.message();
|
||||
std::printf("error mapping file: %s, exiting...\n", errmsg.c_str());
|
||||
return error.value();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
const char* path = "test-file";
|
||||
@ -19,13 +26,8 @@ int main()
|
||||
// Map the region of the file to which buffer was written.
|
||||
std::error_code error;
|
||||
mio::mmap_source file_view = mio::make_mmap_source(
|
||||
path, 0, mio::use_full_file_size, error);
|
||||
if(error)
|
||||
{
|
||||
const auto& errmsg = error.message();
|
||||
std::printf("error mapping file: %s, exiting...\n", errmsg.c_str());
|
||||
return error.value();
|
||||
}
|
||||
path, 0, mio::map_entire_file, error);
|
||||
if(error) { return handle_error(error); }
|
||||
|
||||
assert(file_view.is_open());
|
||||
assert(file_view.size() == buffer.size());
|
||||
@ -71,5 +73,14 @@ int main()
|
||||
// Just making sure custom types compile.
|
||||
mio::ummap_source ummap;
|
||||
|
||||
const auto page_size = mio::page_size();
|
||||
|
||||
// Now check if an mmap with a wider char type reports the correct size.
|
||||
using u16mmap_source = mio::basic_mmap_source<char16_t>;
|
||||
u16mmap_source wide_mmap = mio::make_mmap<u16mmap_source>(path, 0, page_size, error);
|
||||
if(error) { return handle_error(error); }
|
||||
|
||||
assert(wide_mmap.size() == page_size / 2);
|
||||
|
||||
std::printf("all tests passed!\n");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user