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.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 alias allocator = Mallocator.instance;
22 alias autoFreeAllocator = Mallocator.instance;
23 
24 package alias MemoryPool = AllocatorList!((size_t n) => Region!Mallocator(max(n, size_t(1024 * 1024))), Mallocator);
25 package MemoryPool gTempAllocator;
26 
27 T[][] makeArray2D(T, A)(ref A allocator, ref XLOPER12 oper) {
28     import xlld.wrap: isMulti;
29     import std.experimental.allocator: makeMultidimensionalArray;
30     with(oper.val.array) return
31         isMulti(oper) ?
32         allocator.makeMultidimensionalArray!T(rows, columns) :
33         typeof(return).init;
34 }
35 
36 // the function called by the Excel callback
37 void autoFree(LPXLOPER12 arg) nothrow {
38     import xlld.framework: freeXLOper;
39     freeXLOper(arg, autoFreeAllocator);
40 }
41 
42 struct AllocatorContext(A) {
43 
44     A* _allocator_;
45 
46     this(ref A allocator) {
47         _allocator_ = &allocator;
48     }
49 
50     auto any(T)(auto ref T value) {
51         import xlld.any: _any = any;
52         return _any(value, *_allocator_);
53     }
54 
55     auto fromXlOper(T, U)(U oper) {
56         import xlld.wrap: wrapFromXlOper = fromXlOper;
57         return wrapFromXlOper!T(oper, _allocator_);
58     }
59 
60     auto toXlOper(T)(T val) {
61         import xlld.wrap: wrapToXlOper = toXlOper;
62         return wrapToXlOper(val, _allocator_);
63     }
64 
65     version(unittest) {
66         auto toSRef(T)(T val) {
67             import xlld.test_util: toSRef_ = toSRef;
68             return toSRef_(val, _allocator_);
69         }
70     }
71 }
72 
73 auto allocatorContext(A)(ref A allocator) {
74     return AllocatorContext!A(allocator);
75 }