mio 1.1.0
Loading...
Searching...
No Matches
mmap.hpp
Go to the documentation of this file.
1/* Copyright 2017 https://github.com/mandreyel
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
4 * software and associated documentation files (the "Software"), to deal in the Software
5 * without restriction, including without limitation the rights to use, copy, modify,
6 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7 * permit persons to whom the Software is furnished to do so, subject to the following
8 * conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in all copies
11 * or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
18 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 */
20
21/*
22 * Copyright 2026 Maxtek Consulting
23 *
24 * Permission is hereby granted, free of charge, to any person obtaining a copy
25 * of this software and associated documentation files (the "Software"), to deal
26 * in the Software without restriction, including without limitation the rights
27 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 * copies of the Software, and to permit persons to whom the Software is
29 * furnished to do so, subject to the following conditions:
30 *
31 * The above copyright notice and this permission notice shall be included in all
32 * copies or substantial portions of the Software.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40 * SOFTWARE.
41 */
42
43#ifndef MIO_MMAP_HPP
44#define MIO_MMAP_HPP
45
46#include "mio/page.hpp"
47
48#include <iterator>
49#include <string>
50#include <system_error>
51#include <cstdint>
52
53#ifdef _WIN32
54#ifndef WIN32_LEAN_AND_MEAN
55#define WIN32_LEAN_AND_MEAN
56#endif
57#include <windows.h>
58#else
59#define INVALID_HANDLE_VALUE -1
60#endif
61
62namespace mio {
63
64// This value may be provided as the `length` parameter to the constructor or
65// `map`, in which case a memory mapping of the entire file is created.
66enum
67{
69};
70
71#ifdef _WIN32
72using file_handle_type = HANDLE;
73#else
74using file_handle_type = int;
75#endif
76
77// This value represents an invalid file handle type. This can be used to
78// determine whether `basic_mmap::file_handle` is valid, for example.
79const static file_handle_type invalid_handle = INVALID_HANDLE_VALUE;
80
81template <access_mode AccessMode, typename ByteT>
83{
84 using value_type = ByteT;
85 using size_type = size_t;
89 using const_pointer = const value_type*;
90 using difference_type = std::ptrdiff_t;
93 using reverse_iterator = std::reverse_iterator<iterator>;
94 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
95 using iterator_category = std::random_access_iterator_tag;
97
98 static_assert(sizeof(ByteT) == sizeof(char), "ByteT must be the same size as char.");
99
100private:
101 // Points to the first requested byte, and not to the actual start of the mapping.
102 pointer data_ = nullptr;
103
104 // Length--in bytes--requested by user (which may not be the length of the
105 // full mapping) and the length of the full mapping.
106 size_type length_ = 0;
107 size_type mapped_length_ = 0;
108
109 // Letting user map a file using both an existing file handle and a path
110 // introcudes some complexity (see `is_handle_internal_`).
111 // On POSIX, we only need a file handle to create a mapping, while on
112 // Windows systems the file handle is necessary to retrieve a file mapping
113 // handle, but any subsequent operations on the mapped region must be done
114 // through the latter.
115 handle_type file_handle_ = INVALID_HANDLE_VALUE;
116#ifdef _WIN32
118#endif
119
120 // Letting user map a file using both an existing file handle and a path
121 // introcudes some complexity in that we must not close the file handle if
122 // user provided it, but we must close it if we obtained it using the
123 // provided path. For this reason, this flag is used to determine when to
124 // close `file_handle_`.
125 bool is_handle_internal_;
126
127public:
134 : is_handle_internal_(true) {};
135
136#ifdef __cpp_exceptions
142 template <typename String>
143 explicit basic_mmap(const String& path, const size_type& offset = 0,
145 std::error_code error;
147 if(error) {
148 throw std::system_error(error);
149 }
150 }
151
157 explicit basic_mmap(const handle_type& handle, const size_type& offset = 0,
159 std::error_code error;
161 if(error) {
162 throw std::system_error(error);
163 }
164 }
165#endif // __cpp_exceptions
166
171 basic_mmap(const basic_mmap&) = delete;
173 basic_mmap& operator=(const basic_mmap&) = delete;
175
181
187 handle_type file_handle() const noexcept { return file_handle_; }
189
191 bool is_open() const noexcept { return file_handle_ != invalid_handle; }
192
198 bool empty() const noexcept { return length() == 0; }
199
202
210 size_type length() const noexcept { return length_; }
211 size_type mapped_length() const noexcept { return mapped_length_; }
212
214 size_type mapping_offset() const noexcept { return mapped_length_ - length_; }
215
220 template <access_mode A = AccessMode,
221 typename = typename std::enable_if<A == access_mode::write>::type>
223 return data_;
224 }
225 const_pointer data() const noexcept { return data_; }
226
231 template <access_mode A = AccessMode,
232 typename = typename std::enable_if<A == access_mode::write>::type>
234 return data();
235 }
238
243 template <access_mode A = AccessMode,
244 typename = typename std::enable_if<A == access_mode::write>::type>
246 return data() + length();
247 }
250
256 template <access_mode A = AccessMode,
257 typename = typename std::enable_if<A == access_mode::write>::type>
263
268 template <access_mode A = AccessMode,
269 typename = typename std::enable_if<A == access_mode::write>::type>
275
281 reference operator[](const size_type& i) noexcept { return data_[i]; }
282 const_reference operator[](const size_type& i) const noexcept { return data_[i]; }
283
304 template <typename String>
305 void map(const String& path, const size_type& offset, const size_type& length,
306 std::error_code& error);
307
320 template <typename String>
321 void map(const String& path, std::error_code& error) {
323 }
324
344 void map(const handle_type& handle, const size_type& offset, const size_type& length,
345 std::error_code& error);
346
358 void map(const handle_type& handle, std::error_code& error) {
360 }
361
371 void unmap();
372
374
376 template <access_mode A = AccessMode>
377 typename std::enable_if<A == access_mode::write, void>::type sync(std::error_code& error);
378
384private:
385 template <access_mode A = AccessMode,
386 typename = typename std::enable_if<A == access_mode::write>::type>
387 pointer get_mapping_start() noexcept {
388 return !data() ? nullptr : data() - mapping_offset();
389 }
390
391 const_pointer get_mapping_start() const noexcept {
392 return !data() ? nullptr : data() - mapping_offset();
393 }
394
401 template <access_mode A = AccessMode>
402 typename std::enable_if<A == access_mode::write, void>::type
403 conditional_sync(); // cppcheck-suppress functionStatic
404 template <access_mode A = AccessMode>
405 typename std::enable_if<A == access_mode::read, void>::type
406 conditional_sync(); // cppcheck-suppress functionStatic
407};
408
409template <access_mode AccessMode, typename ByteT>
411
412template <access_mode AccessMode, typename ByteT>
414
415template <access_mode AccessMode, typename ByteT>
417
418template <access_mode AccessMode, typename ByteT>
420
421template <access_mode AccessMode, typename ByteT>
423
424template <access_mode AccessMode, typename ByteT>
426
431template <typename ByteT>
433
438template <typename ByteT>
440
447
450
455template <typename MMap, typename MappingToken>
456MMap make_mmap(const MappingToken& token, int64_t offset, int64_t length, std::error_code& error) {
457 MMap mmap;
458 mmap.map(token, offset, length, error);
459 return mmap;
460}
461
469template <typename MappingToken>
470mmap_source make_mmap_source(const MappingToken& token, mmap_source::size_type offset,
471 mmap_source::size_type length, std::error_code& error) {
472 return make_mmap<mmap_source>(token, offset, length, error);
473}
474
475template <typename MappingToken>
476mmap_source make_mmap_source(const MappingToken& token, std::error_code& error) {
477 return make_mmap_source(token, 0, map_entire_file, error);
478}
479
487template <typename MappingToken>
488mmap_sink make_mmap_sink(const MappingToken& token, mmap_sink::size_type offset,
489 mmap_sink::size_type length, std::error_code& error) {
490 return make_mmap<mmap_sink>(token, offset, length, error);
491}
492
493template <typename MappingToken>
494mmap_sink make_mmap_sink(const MappingToken& token, std::error_code& error) {
495 return make_mmap_sink(token, 0, map_entire_file, error);
496}
497
498}; // namespace mio
499
500#include "detail/mmap.ipp"
501
502#endif // MIO_MMAP_HPP
#define INVALID_HANDLE_VALUE
Definition mmap.hpp:59
Definition string_util.hpp:48
access_mode
Definition page.hpp:59
MMap make_mmap(const MappingToken &token, int64_t offset, int64_t length, std::error_code &error)
Definition mmap.hpp:456
mmap_source make_mmap_source(const MappingToken &token, mmap_source::size_type offset, mmap_source::size_type length, std::error_code &error)
Definition mmap.hpp:470
bool operator!=(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
bool operator<(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
bool operator>(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
bool operator<=(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
bool operator==(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
@ map_entire_file
Definition mmap.hpp:68
int file_handle_type
Definition mmap.hpp:74
mmap_sink make_mmap_sink(const MappingToken &token, mmap_sink::size_type offset, mmap_sink::size_type length, std::error_code &error)
Definition mmap.hpp:488
bool operator>=(const basic_mmap< AccessMode, ByteT > &a, const basic_mmap< AccessMode, ByteT > &b)
Definition mmap.hpp:83
std::random_access_iterator_tag iterator_category
Definition mmap.hpp:95
const_iterator begin() const noexcept
Definition mmap.hpp:236
void map(const String &path, const size_type &offset, const size_type &length, std::error_code &error)
iterator end() noexcept
Definition mmap.hpp:245
pointer iterator
Definition mmap.hpp:91
const_reverse_iterator crbegin() const noexcept
Definition mmap.hpp:262
const_iterator cbegin() const noexcept
Definition mmap.hpp:237
bool empty() const noexcept
Definition mmap.hpp:198
size_t size_type
Definition mmap.hpp:85
basic_mmap()
Definition mmap.hpp:133
const_iterator cend() const noexcept
Definition mmap.hpp:249
std::enable_if< A==access_mode::write, void >::type sync(std::error_code &error)
size_type length() const noexcept
Definition mmap.hpp:210
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition mmap.hpp:94
pointer data() noexcept
Definition mmap.hpp:222
const_pointer const_iterator
Definition mmap.hpp:92
const value_type * const_pointer
Definition mmap.hpp:89
void map(const handle_type &handle, std::error_code &error)
Definition mmap.hpp:358
const_reverse_iterator rend() const noexcept
Definition mmap.hpp:273
std::reverse_iterator< iterator > reverse_iterator
Definition mmap.hpp:93
std::ptrdiff_t difference_type
Definition mmap.hpp:90
void swap(basic_mmap &other)
basic_mmap(const basic_mmap &)=delete
bool is_open() const noexcept
Definition mmap.hpp:191
const value_type & const_reference
Definition mmap.hpp:87
size_type mapping_offset() const noexcept
Definition mmap.hpp:214
const_pointer data() const noexcept
Definition mmap.hpp:225
handle_type mapping_handle() const noexcept
basic_mmap(basic_mmap &&)
const_iterator end() const noexcept
Definition mmap.hpp:248
reference operator[](const size_type &i) noexcept
Definition mmap.hpp:281
iterator begin() noexcept
Definition mmap.hpp:233
reverse_iterator rbegin() noexcept
Definition mmap.hpp:258
reverse_iterator rend() noexcept
Definition mmap.hpp:270
basic_mmap & operator=(basic_mmap &&)
const_reverse_iterator rbegin() const noexcept
Definition mmap.hpp:261
handle_type file_handle() const noexcept
Definition mmap.hpp:187
value_type * pointer
Definition mmap.hpp:88
value_type & reference
Definition mmap.hpp:86
size_type mapped_length() const noexcept
Definition mmap.hpp:211
bool is_mapped() const noexcept
void map(const handle_type &handle, const size_type &offset, const size_type &length, std::error_code &error)
size_type size() const noexcept
Definition mmap.hpp:209
file_handle_type handle_type
Definition mmap.hpp:96
const_reverse_iterator crend() const noexcept
Definition mmap.hpp:274
ByteT value_type
Definition mmap.hpp:84
const_reference operator[](const size_type &i) const noexcept
Definition mmap.hpp:282
void map(const String &path, std::error_code &error)
Definition mmap.hpp:321
basic_mmap & operator=(const basic_mmap &)=delete