1 module cachetools.internal;
2 
3 private import std.typecons;
4 private import std.traits;
5 
6 template StoredType(T)
7 {
8     static if ( is (T==immutable) || is(T==const) )
9     {
10         static if ( is(T==class) )
11         {
12             alias StoredType = Rebindable!T;
13         }
14         else
15         {
16             alias StoredType = Unqual!T;
17         }
18     }
19     else
20     {
21         alias StoredType = T;
22     }
23 }
24 
25 import std.experimental.logger;
26 
27 debug(cachetools) @safe @nogc nothrow
28 {
29     void safe_tracef(A...)(string f, scope A args, string file = __FILE__, int line = __LINE__) @safe @nogc nothrow
30     {
31         debug (cachetools) try
32         {
33             () @trusted @nogc {tracef("%s:%d " ~ f, file, line, args);}();
34         }
35         catch(Exception e)
36         {
37         }
38     }    
39 }
40 
41 bool UseGCRanges(T)() {
42     return hasIndirections!T;
43 }
44 
45 bool UseGCRanges(Allocator, T, bool GCRangesAllowed)()
46 {
47     import std.experimental.allocator.gc_allocator;
48     return !is(Allocator==GCAllocator) && hasIndirections!T && GCRangesAllowed;
49 }
50 
51 bool UseGCRanges(Allocator, K, V, bool GCRangesAllowed)()
52 {
53     import std.experimental.allocator.gc_allocator;
54 
55     return  !is(Allocator == GCAllocator) && (hasIndirections!K || hasIndirections!V ) && GCRangesAllowed;
56 }
57 
58 ///
59 /// Return true if it is worth to store values inline in hash table
60 /// V footprint should be small enough
61 ///
62 package bool SmallValueFootprint(V)() {
63     import std.traits;
64 
65     static if (isNumeric!V || isSomeString!V || isSomeChar!V || isPointer!V) {
66         return true;
67     }
68     else static if (is(V == struct) && V.sizeof <= (void*).sizeof) {
69         return true;
70     }
71     else static if (is(V == class) && __traits(classInstanceSize, V) <= (void*).sizeof) {
72         return true;
73     }
74     else
75         return false;
76 }