1 module quantities.compiletime;
2 
3 public import quantities.compiletime.quantity;
4 
5 ///
6 unittest
7 {
8     import quantities.compiletime;
9     import quantities.si;
10     
11     // Introductory example
12     {
13         // Use the predefined quantity types (in module quantities.si)
14         Volume volume;
15         Concentration concentration;
16         Mass mass;
17 
18         // Define a new quantity type
19         alias MolarMass = typeof(kilogram/mole);
20 
21         // I have to make a new solution at the concentration of 5 mmol/L
22         concentration = 5.0 * milli(mole)/liter;
23 
24         // The final volume is 100 ml.
25         volume = 100.0 * milli(liter);
26 
27         // The molar mass of my compound is 118.9 g/mol
28         MolarMass mm = 118.9 * gram/mole;
29 
30         // What mass should I weigh?
31         mass = concentration * volume * mm;
32         writefln("Weigh %s of substance", mass); 
33         // prints: Weigh 5.945e-05 [M] of substance
34         // Wait! That's not really useful!
35         writefln("Weigh %s of substance", mass.siFormat!"%.1f mg");
36         // prints: Weigh 59.5 mg of substance
37     }
38 
39     // Working with predefined units
40     {
41         auto distance = 384_400 * kilo(meter);
42         auto speed = 299_792_458  * meter/second;
43         auto time = distance / speed;
44         writefln("Travel time of light from the moon: %s", time.siFormat!"%.3f s");
45     }
46 
47     // Dimensional correctness is check at compile-time
48     {
49         Mass mass;
50         static assert(!__traits(compiles, mass = 15 * meter));
51         static assert(!__traits(compiles, mass = 1.2));
52     }
53 
54     // Calculations can be done at compile-time
55     {
56         enum distance = 384_400 * kilo(meter);
57         enum speed = 299_792_458  * meter/second;
58         enum time = distance / speed;
59         writefln("Travel time of light from the moon: %s", time.siFormat!"%.3f s");
60     }
61 
62     // Create a new unit from the predefined ones
63     {
64         enum inch = 2.54 * centi(meter);
65         enum mile = 1609 * meter;
66         writefln("There are %s inches in a mile", mile.value(inch));
67         // NB. Cannot use siFormat, because inches are not SI units
68     }
69 
70     // Create a new unit with new dimensions
71     {
72         // Create a new base unit of currency
73         enum euro = unit!(double, "C"); // C is the chosen dimension symol (for currency...)
74 
75         auto dollar = euro / 1.35;
76         auto price = 2000 * dollar;
77         writefln("This computer costs €%.2f", price.value(euro));
78     }
79 
80     // Compile-time parsing
81     {
82         enum distance = si!"384_400 km";
83         enum speed = si!"299_792_458 m/s";
84         enum time = distance / speed;
85         writefln("Travel time of light from the moon: %s", time.siFormat!"%.3f s");
86 
87         static assert(is(typeof(distance) == Length));
88         static assert(is(typeof(speed) == Speed));
89     }
90 
91     // Run-time parsing
92     {
93         auto data = [
94             "distance-to-the-moon": "384_400 km",
95             "speed-of-light": "299_792_458 m/s"
96         ];
97         auto distance = parseSI!Length(data["distance-to-the-moon"]);
98         auto speed = parseSI!Speed(data["speed-of-light"]);
99         auto time = distance / speed;
100         writefln("Travel time of light from the moon: %s", time.siFormat!"%.3f s");
101     }
102 }
103 
104 version (unittest)
105 {
106     version (QuantitiesPrintTests)
107         import std.stdio : writefln;
108     else
109         private void writefln(T...)(T args) {}
110 }