1 /++
2 The purpose of this small library is to perform automatic compile-time or
3 run-time dimensional checking when dealing with quantities and units.
4 
5 There is no actual distinction between units and quantities, so there are no
6 distinct quantity and unit types. All operations are actually done on
7 quantities. For example, `meter` is both the unit _meter_ and the quantity _1m_.
8 New quantities can be derived from other ones using operators or dedicated
9 functions.
10 
11 Quantities can be parsed from strings at run time and compile time.
12 
13 The main SI units and prefixes are predefined. Units with other dimensions can
14 be defined by the user.
15 
16 Copyright: Copyright 2013-2018, Nicolas Sicard.
17 License: Boost License 1.0.
18 +/
19 module quantities;
20 
21 public import quantities.compiletime;
22 public import quantities.runtime;
23 public import quantities.si;
24 
25 ///
26 @("Synopsis at compile time")
27 unittest
28 {
29     import quantities.compiletime;
30     import quantities.si;
31     import std.conv : text;
32 
33     // Define a quantity from SI units
34     auto distance = 384_400 * kilo(meter);
35 
36     // Define a quantity from a string
37     auto speed = si!"299_792_458 m/s";
38     // Define a type for a quantity
39     alias Speed = typeof(speed);
40 
41     // Calculations on quantities
42     auto calculateTime(Length d, Speed s)
43     {
44         return d / s;
45     }
46     Time time = calculateTime(distance, speed);
47 
48     // Dimensions are checked at compile time for consistency
49     static assert(!__traits(compiles, distance + speed));
50 
51     // Format a quantity with a format specification containing a unit
52     assert(time.siFormat!"%.3f s".text == "1.282 s");
53 }
54 
55 ///
56 @("Synopsis at run time")
57 unittest
58 {
59     import quantities.runtime;
60     import quantities.si;
61     import std.exception : assertThrown;
62     import std.conv : text;
63 
64     // Define a quantity from SI units (using the helper function `qVariant`)
65     auto distance = qVariant(384_400 * kilo(meter));
66 
67     // Define a quantity from a string
68     auto speed = parseSI("299_792_458 m/s");
69 
70     // Calculations on quantities (checked at compile time for consistency)
71     QVariant!double calculateTime(QVariant!double d, QVariant!double s)
72     {
73         return d / s;
74     }
75     auto time = calculateTime(distance, speed);
76 
77     // Dimensions are checked at run time for consistency
78     assertThrown!DimensionException(distance + speed);
79 
80     // Format a quantity with a format specification containing a unit
81     assert(siFormat("%.3f s", time).text == "1.282 s");
82 }