1 ///
2 module stdx.allocator.building_blocks.null_allocator;
3 
4 /**
5 $(D NullAllocator) is an emphatically empty implementation of the allocator
6 interface. Although it has no direct use, it is useful as a "terminator" in
7 composite allocators.
8 */
9 struct NullAllocator
10 {
11     import stdx.allocator.internal : Ternary;
12     /**
13     $(D NullAllocator) advertises a relatively large _alignment equal to 64 KB.
14     This is because $(D NullAllocator) never actually needs to honor this
15     alignment and because composite allocators using $(D NullAllocator)
16     shouldn't be unnecessarily constrained.
17     */
18     enum uint alignment = 64 * 1024;
19     // /// Returns $(D n).
20     //size_t goodAllocSize(size_t n) shared const
21     //{ return .goodAllocSize(this, n); }
22     /// Always returns $(D null).
23     static void[] allocate()(size_t) { return null; }
24     /// Always returns $(D null).
25     static void[] alignedAllocate()(size_t, uint) { return null; }
26     /// Always returns $(D null).
27     static void[] allocateAll()() { return null; }
28     /**
29     These methods return $(D false).
30     Precondition: $(D b is null). This is because there is no other possible
31     legitimate input.
32     */
33     static bool expand()(ref void[] b, size_t s)
34     { assert(b is null); return s == 0; }
35     /// Ditto
36     static bool reallocate()(ref void[] b, size_t)
37     { assert(b is null); return false; }
38     /// Ditto
39     static bool alignedReallocate()(ref void[] b, size_t, uint)
40     { assert(b is null); return false; }
41     /// Returns $(D Ternary.no).
42     static Ternary owns()(void[]) { return Ternary.no; }
43     /**
44     Returns $(D Ternary.no).
45     */
46     static Ternary resolveInternalPointer()(const void*, ref void[])
47     { return Ternary.no; }
48     /**
49     No-op.
50     Precondition: $(D b is null)
51     */
52     static bool deallocate()(void[] b) { assert(b is null); return true; }
53     /**
54     No-op.
55     */
56     static bool deallocateAll()() { return true; }
57     /**
58     Returns $(D Ternary.yes).
59     */
60     static Ternary empty()() { return Ternary.yes; }
61     /**
62     Returns the $(D static) global instance of the $(D NullAllocator).
63     */
64     enum NullAllocator instance = NullAllocator();
65 }
66 
67 @system unittest
68 {
69     assert(NullAllocator.instance.alignedAllocate(100, 0) is null);
70     assert(NullAllocator.instance.allocateAll() is null);
71     auto b = NullAllocator.instance.allocate(100);
72     assert(b is null);
73     assert(NullAllocator.instance.expand(b, 0));
74     assert(!NullAllocator.instance.expand(b, 42));
75     assert(!NullAllocator.instance.reallocate(b, 42));
76     assert(!NullAllocator.instance.alignedReallocate(b, 42, 0));
77     NullAllocator.instance.deallocate(b);
78     assert(NullAllocator.instance.deallocateAll() == true);
79 
80     import stdx.allocator.internal : Ternary;
81     assert(NullAllocator.instance.empty() == Ternary.yes);
82     assert(NullAllocator.instance.owns(null) == Ternary.no);
83     void[] p;
84     assert(NullAllocator.instance.resolveInternalPointer(null, p) == Ternary.no);
85 }