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 <vladimir@thecybershadow.net>
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 
23 struct Mapped(T)
24 {
25 	this(string fn)
26 	{
27 		if (!fn.exists)
28 			std.file.write(fn, [T.init]);
29 		__mapped_file = __mapped_makeFile(fn);
30 	}
31 
32 	private static auto __mapped_makeFile(string fn)
33 	{
34 		static if (is(typeof({T t = void; t = t;})))
35 			enum mode = MmFile.Mode.readWrite;
36 		else
37 			enum mode = MmFile.Mode.read;
38 		return scoped!MmFile(fn, mode, T.sizeof, null);
39 	}
40 
41 	typeof(__mapped_makeFile(null)) __mapped_file;
42 	@disable this(this);
43 
44 	@property ref T __mapped_data()
45 	{
46 		return *cast(T*)__mapped_file[].ptr;
47 	}
48 	alias __mapped_data this;
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 }