1 /**
2  * ae.sys.persistence.mapped
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.sys.persistence.mapped;
15 
16 import std.file;
17 import std.mmfile;
18 import std.typecons;
19 
20 /// Map a file onto a D type.
21 /// Experimental.
22 struct Mapped(T)
23 {
24 	this(string fn)
25 	{
26 		if (!fn.exists)
27 			std.file.write(fn, [T.init]);
28 		__mapped_file = __mapped_makeFile(fn);
29 	} ///
30 
31 	private static auto __mapped_makeFile(string fn)
32 	{
33 		static if (is(typeof({T t = void; t = t;})))
34 			enum mode = MmFile.Mode.readWrite;
35 		else
36 			enum mode = MmFile.Mode.read;
37 		return scoped!MmFile(fn, mode, T.sizeof, null);
38 	}
39 
40 	typeof(__mapped_makeFile(null)) __mapped_file;
41 	@disable this(this);
42 
43 	@property ref T __mapped_data()
44 	{
45 		return *cast(T*)__mapped_file[].ptr;
46 	}
47 	alias __mapped_data this;
48 }
49 
50 ///
51 unittest
52 {
53 	static struct S
54 	{
55 		ubyte value;
56 	}
57 
58 	enum fn = "test.bin";
59 	scope(success) remove(fn);
60 	auto m = Mapped!S(fn);
61 
62 	m.value = 1;
63 	assert(read(fn) == [ubyte(1)]);
64 	version (Posix)
65 	{
66 		write(fn, [ubyte(2)]);
67 		assert(m.value == 2);
68 	}
69 }