1 module nxt.assuming;
2 
3 import std.traits : isFunctionPointer, isDelegate, functionAttributes, FunctionAttribute, SetFunctionAttributes, functionLinkage;
4 
5 /**
6    * See_Also: http://forum.dlang.org/post/nq4eol$2h34$1@digitalmars.com
7    * See_Also: https://dpaste.dzfl.pl/8c5ec90c5b39
8    */
9 void assumeNogc(alias fun, T...)(T xs) @nogc
10 {
11     static auto assumeNogcPtr(T)(T f)
12     if (isFunctionPointer!T ||
13         isDelegate!T)
14     {
15         enum attrs = functionAttributes!T | FunctionAttribute.nogc;
16         return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) f;
17     }
18     assumeNogcPtr(&fun!T)(xs);
19 }
20 
21 /** Return `T` assumed to be `pure`.
22  *
23  * Copied from: https://dlang.org/phobos/std_traits.html#SetFunctionAttributes.
24  * See_Also: https://forum.dlang.org/post/hmucolyghbomttqpsili@forum.dlang.org
25  */
26 auto assumePure(T)(T t)
27 if (isFunctionPointer!T ||
28     isDelegate!T)
29 {
30     enum attrs = functionAttributes!T | FunctionAttribute.pure_;
31     return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
32 }
33 
34 version(unittest)
35 {
36     static int f(int x)
37     {
38         return x + 1;
39     }
40 
41     static void g() pure
42     {
43         static assert(!__traits(compiles, { auto x = f(42); }));
44         auto pureF = assumePure(&f);
45         assert(pureF(42) == 43);
46     }
47 }
48 
49 auto assumePureNogc(T)(T t)
50 if (isFunctionPointer!T ||
51     isDelegate!T)
52 {
53     enum attrs = functionAttributes!T | FunctionAttribute.pure_ | FunctionAttribute.nogc;
54     return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
55 }