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 }