1 module ikod.containers.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
28 {
29     package void safe_tracef(A...)(string f, scope A args, string file = __FILE__, int line = __LINE__) @safe @nogc
30     {
31         bool osx,ldc;
32         version(OSX)
33         {
34             osx = true;
35         }
36         version(LDC)
37         {
38             ldc = true;
39         }
40         if (!osx || !ldc)
41         {
42             // this can fail on pair ldc2/osx, see https://github.com/ldc-developers/ldc/issues/3240
43             import core.thread;
44             debug (cachetools) try
45             {
46                 () @trusted @nogc {tracef("[%x] %s:%d " ~ f, Thread.getThis().id(), file, line, args);}();
47             }
48             catch(Exception e)
49             {
50                 () @trusted @nogc nothrow {try{errorf("[%x] %s:%d Exception: %s", Thread.getThis().id(), file, line, e);}catch(Throwable) {}}();
51             }
52         }
53     }
54 }
55 
56 bool UseGCRanges(T)() {
57     return hasIndirections!T;
58 }
59 
60 bool UseGCRanges(Allocator, T, bool GCRangesAllowed)()
61 {
62     import std.experimental.allocator.gc_allocator;
63     return !is(Allocator==GCAllocator) && hasIndirections!T && GCRangesAllowed;
64 }
65 
66 bool UseGCRanges(Allocator, K, V, bool GCRangesAllowed)()
67 {
68     import std.experimental.allocator.gc_allocator;
69 
70     return  !is(Allocator == GCAllocator) && (hasIndirections!K || hasIndirections!V ) && GCRangesAllowed;
71 }
72 
73 ///
74 /// Return true if it is worth to store values inline in hash table
75 /// V footprint should be small enough
76 ///
77 package bool SmallValueFootprint(V)() {
78     import std.traits;
79 
80     static if (isNumeric!V || isSomeString!V || isSomeChar!V || isPointer!V) {
81         return true;
82     }
83     else static if (is(V == struct) && V.sizeof <= (void*).sizeof) {
84         return true;
85     }
86     else static if (is(V == class) && __traits(classInstanceSize, V) <= (void*).sizeof) {
87         return true;
88     }
89     else
90         return false;
91 }