1 // 
2 // 
3 // 
4 
5 module dini.inivalue;
6 
7 import std.conv   : to;
8 import std.traits : isNumeric, isUnsigned;
9 
10 struct IniValue
11 {
12 public:
13     /// Constructor
14     this(string value) nothrow @nogc pure @safe
15     {
16         this._value = value;
17     }
18 
19     string toString() const nothrow @nogc pure @safe
20     {
21         return _value;
22     }
23 
24     T to(T)() const
25         if( isConstructable!T.With!IniValue )
26     {
27         return T(this);
28     }
29     T to(T)() const
30         if( !isConstructable!T.With!IniValue && isAssignable!T.With!IniValue )
31     {
32         T t;
33         t = this;
34         return t;
35     }
36     T to(T)() const
37         if( !isConstructable!T.With!IniValue && !isAssignable!T.With!IniValue )
38     {
39         return cast(T) this;
40     }
41 
42     /// Cast to a string
43     string opCast(R : string)() const @nogc pure @safe
44     {
45         return _value;
46     }
47 
48     /// Casting to integer and float types
49     auto opCast(R)() const pure @safe
50         if(isNumeric!R || isUnsigned!R)
51     {
52         return _value.to!R;
53     }
54 
55     /// Cast to a bool
56     auto opCast(R : bool) () const pure @safe
57     {
58         import std..string : toLower;
59         string v = _value.toLower();
60         return ("true" == v || "1" == v || "on" == v);
61     }
62     
63 private:
64     string _value;
65 };
66 
67 
68 private template isConstructable(T) {
69     template With(R) {
70         enum bool With = __traits(compiles, typeof(T(R.init)) );
71     }
72 }
73 
74 private template isAssignable(T) {
75     template With(R) {
76         enum bool With = __traits(compiles, typeof(T.init.opAssign(R.init)) );
77     }
78 }
79 
80 
81 
82 
83 ///////////////////////////////////////////////////////
84 // cd source 
85 // rdmd -unittest -main  dini/inivalue
86 nothrow unittest {
87 
88     struct B1 {
89         this(IniValue v) {}
90     }
91     struct B2 {
92         void opAssign(IniValue v) {}
93     }
94 
95     //pragma(msg,  "isConstructable!B1.With!IniValue");
96     //pragma(msg,  isConstructable!B1.With!IniValue);
97     static assert(isConstructable!B1.With!IniValue);
98 
99     //pragma(msg,  "isConstructable!B2.With!IniValue");
100     //pragma(msg,  isConstructable!B2.With!IniValue);
101     static assert(!isConstructable!B2.With!IniValue);
102 
103     //pragma(msg,  "isAssignable!B1.With!IniValue");
104     //pragma(msg,  isAssignable!B1.With!IniValue);
105     static assert(!isAssignable!B1.With!IniValue);
106 
107     //pragma(msg,  "isAssignable!B2.With!IniValue");
108     //pragma(msg,  isAssignable!B2.With!IniValue);
109     static assert(isAssignable!B2.With!IniValue);
110 }