1 /**
2 	MemoryManager.D
3 
4 	Ported from MemoryManager.cpp by Laeeth Isharc
5 //
6 // Platform:    Microsoft Windows
7 //
8 ///***************************************************************************
9 */
10 module xlld.memorymanager;
11 
12 import xlld.sdk.xlcall: XLOPER12, LPXLOPER12;
13 import xlld.any: Any;
14 import std.experimental.allocator.building_blocks.allocator_list: AllocatorList;
15 import std.experimental.allocator.mallocator: Mallocator;
16 import std.experimental.allocator.building_blocks.region: Region;
17 import std.algorithm.comparison: max;
18 import std.traits: isArray;
19 import std.meta: allSatisfy;
20 
21 ///
22 alias allocator = Mallocator.instance;
23 ///
24 alias autoFreeAllocator = Mallocator.instance;
25 
26 ///
27 alias MemoryPool = AllocatorList!((size_t n) => Region!Mallocator(max(n, size_t(1024 * 1024))), Mallocator);
28 ///
29 MemoryPool gTempAllocator;
30 
31 ///
32 T[][] makeArray2D(T, A)(ref A allocator, ref XLOPER12 oper) {
33     import xlld.conv.from: isMulti;
34     import std.experimental.allocator: makeMultidimensionalArray;
35     with(oper.val.array) return
36         isMulti(oper) ?
37         allocator.makeMultidimensionalArray!T(rows, columns) :
38         typeof(return).init;
39 }
40 
41 /// the function called by the Excel callback
42 void autoFree(LPXLOPER12 arg) nothrow {
43     import xlld.sdk.framework: freeXLOper;
44     freeXLOper(arg, autoFreeAllocator);
45 }
46 
47 ///
48 struct AllocatorContext(A) {
49     ///
50     A* _allocator_;
51 
52     ///
53     this(ref A allocator) {
54         _allocator_ = &allocator;
55     }
56 
57     ///
58     auto any(T)(auto ref T value, in string file = __FILE__, in size_t line = __LINE__) {
59         import xlld.any: _any = any;
60         return _any(value, *_allocator_, file, line);
61     }
62 
63     ///
64     auto fromXlOper(T, U)(U oper) {
65         import xlld.conv.from: convFromXlOper = fromXlOper;
66         return convFromXlOper!T(oper, _allocator_);
67     }
68 
69     ///
70     auto toXlOper(T)(T val) {
71         import xlld.conv: convToXlOper = toXlOper;
72         return convToXlOper(val, _allocator_);
73     }
74 
75     version(unittest) {
76         ///
77         auto toSRef(T)(T val) {
78             import xlld.test.util: toSRef_ = toSRef;
79             return toSRef_(val, _allocator_);
80         }
81     }
82 }
83 
84 ///
85 auto allocatorContext(A)(ref A allocator) {
86     return AllocatorContext!A(allocator);
87 }