units
Use physical dimensions at compile-time or run-time.
statdim-base.hpp
Go to the documentation of this file.
1 /// @file vnix/units/statdim-base.hpp
2 /// @brief Definition of vnix::units::statdim_base.
3 /// @copyright 2019 Thomas E. Vaughan; all rights reserved.
4 /// @license BSD Three-Clause; see LICENSE.
5 
6 #ifndef VNIX_UNITS_STATDIM_BASE_HPP
7 #define VNIX_UNITS_STATDIM_BASE_HPP
8 
9 #include <vnix/units/dim.hpp>
10 
11 namespace vnix {
12 namespace units {
13 
14 
15 class dyndim_base;
16 
17 
18 /// Base-type for a dimensioned value whose dimension is specified statically
19 /// at compile-time by way of a template parameter.
20 ///
21 /// The dimension is specified as a set of exponents, one for each of the five
22 /// base dimensions (time, length, mass, charge, and temperature).
23 ///
24 /// For statdim_base, the dimension is always known statically at compile-time.
25 /// For dyndim_base, the dimension is known statically at compile-time only if
26 /// the dimension be specified to the constructor as a constant expression.
27 ///
28 /// @tparam D Encoding of dimensional exponents as a dim::word.
29 template <dim::word D> struct statdim_base {
30  /// Check for compatibility on contruction from dim.
31  /// @param dd Candidate dimension.
32  constexpr statdim_base(dim dd) {
33  if (d() != dd) {
34  throw "attempt to construct from incompatible dimension";
35  }
36  }
37 
38  constexpr statdim_base() {} ///< Allow default construction.
39 
40  /// Exponent for each unit in dimensioned quantity.
41  constexpr static dim d() { return dim(D); }
42 
43  /// Throw if dimension be non-null.
44  constexpr static void number() {
45  if (d() != nul_dim) { throw "dimensioned quantity is not a number"; }
46  }
47 
48  /// Test for comparison of dimensioned values.
49  constexpr static void comparison(statdim_base) {}
50 
51  /// Test for comparison of dimensioned values.
52  constexpr static void comparison(dyndim_base const &db);
53 
54  /// Dimension for sum of dimensioned values.
55  constexpr static auto sum(statdim_base) { return statdim_base(); }
56 
57  /// Dimension for sum of dimensioned values.
58  constexpr static dyndim_base sum(dyndim_base const &db);
59 
60  /// Dimension for difference of dimensioned values.
61  constexpr static auto diff(statdim_base) { return statdim_base(); }
62 
63  /// Dimension for difference of dimensioned values.
64  constexpr static dyndim_base diff(dyndim_base const &db);
65 
66  /// Dimension for product of dimensioned values.
67  /// @tparam OD Encoding of factor's dimension in dim::word.
68  /// @return Dimension of product.
69  template <dim::word OD> constexpr static auto prod(statdim_base<OD>) {
70  dim::word constexpr rd = (d() + dim(OD)).encode();
71  return statdim_base<rd>();
72  }
73 
74  /// Dimension for product of dimensioned values.
75  /// @param db Factor's dimension.
76  /// @return Dimension of product.
77  constexpr static dyndim_base prod(dyndim_base const &db);
78 
79  /// Dimension for quotient of dimensioned values.
80  /// @tparam D Encoding of divisor's dimension in dim::word.
81  /// @return Dimension of quotient.
82  template <dim::word OD> constexpr static auto quot(statdim_base<OD>) {
83  dim::word constexpr rd = (d() - dim(OD)).encode();
84  return statdim_base<rd>();
85  }
86 
87  /// Dimension for quotient of dimensioned values.
88  /// @param db Divisor's dimension.
89  /// @return Dimension of quotient.
90  constexpr static dyndim_base quot(dyndim_base const &db);
91 
92  /// Dimensions corresponding to reciprocal of dimensioned quantity.
93  constexpr static auto recip_dim = nul_dim - d();
94 
95  /// Base-dimension-type corresponding to reciprocal of dimensioned quantity.
96  using recip_basedim = statdim_base<recip_dim.encode()>;
97 
98  /// Dimension for reciprocal of dimensioned value.
99  /// @return Dimension of reciprocal.
100  constexpr static recip_basedim recip() { return recip_basedim(); }
101 
102  /// Dimension for rational power of dimensioned value.
103  /// @tparam PN Numerator of power.
104  /// @tparam PD Denominator of power.
105  /// @return Dimension of result.
106  template <int64_t PN, int64_t PD = 1> constexpr static auto pow() {
107  dim::word constexpr rd = (d() * dim::rat(PN, PD)).encode();
108  return statdim_base<rd>();
109  }
110 
111  /// Dimension for rational power of dimensioned value.
112  /// @param p Rational power.
113  /// @return Dimension of result.
114  constexpr static dyndim_base pow(dim::rat p);
115 
116  /// Dimension for square-root of dimensioned value.
117  /// @return Dimension of square-root.
118  constexpr static auto sqrt() {
119  dim::word constexpr rd = (d() / dim::rat(2)).encode();
120  return statdim_base<rd>();
121  }
122 };
123 
124 
125 } // namespace units
126 } // namespace vnix
127 
128 
129 #include <vnix/units/dyndim-base.hpp>
130 
131 
132 namespace vnix {
133 namespace units {
134 
135 
136 // Test for comparison of dimensioned values.
137 template <dim::word D>
138 constexpr void statdim_base<D>::comparison(dyndim_base const &db) {
139  if (d() != db.d()) { throw "incompatible dimensions for comparison"; }
140 }
141 
142 
143 // Dimension for sum of dimensioned values.
144 template <dim::word D>
145 constexpr dyndim_base statdim_base<D>::sum(dyndim_base const &db) {
146  if (d() != db.d()) { throw "incompatible dimensions for addition"; }
147  return d();
148 }
149 
150 
151 // Dimension for difference of dimensioned values.
152 template <dim::word D>
153 constexpr dyndim_base statdim_base<D>::diff(dyndim_base const &db) {
154  if (d() != db.d()) { throw "incompatible dimensions for subtraction"; }
155  return d();
156 }
157 
158 
159 // Dimension for product of dimensioned values.
160 template <dim::word D>
161 constexpr dyndim_base statdim_base<D>::prod(dyndim_base const &db) {
162  return d() + db.d();
163 }
164 
165 
166 // Dimension for quotient of dimensioned values.
167 template <dim::word D>
168 constexpr dyndim_base statdim_base<D>::quot(dyndim_base const &db) {
169  return d() - db.d();
170 }
171 
172 
173 // Dimension for rational power of dimensioned value.
174 template <dim::word D> constexpr dyndim_base statdim_base<D>::pow(dim::rat p) {
175  return d() * p;
176 }
177 
178 
179 } // namespace units
180 } // namespace vnix
181 
182 #endif // ndef VNIX_UNITS_STATDIM_BASE_HPP
static constexpr dim d()
Exponent for each unit in dimensioned quantity.
constexpr word encode() const
Encode data for this dim into a word.
Definition: dim.hpp:104
static constexpr dyndim_base prod(dyndim_base const &db)
Dimension for product of dimensioned values.
static constexpr auto diff(statdim_base)
Dimension for difference of dimensioned values.
constexpr statdim_base()
Allow default construction.
Base-type for a dimensioned value whose dimension is specified, perhaps dynamically at run-time...
Definition: dyndim-base.hpp:24
constexpr basic_dim operator+(basic_dim const &a) const
Add corresponding exponents.
Definition: dim.hpp:194
constexpr dim d() const
Exponent for each unit in dimensioned quantity.
Definition: dyndim-base.hpp:33
static constexpr dyndim_base quot(dyndim_base const &db)
Dimension for quotient of dimensioned values.
static constexpr auto pow()
Dimension for rational power of dimensioned value.
static constexpr dyndim_base sum(dyndim_base const &db)
Dimension for sum of dimensioned values.
static constexpr recip_basedim recip()
Dimension for reciprocal of dimensioned value.
constexpr rational(stype n=0, stype d=1)
Initialize from numerator and denominator.
Definition: rational.hpp:47
constexpr basic_dim operator-(basic_dim const &s) const
Subtract corresponding exponents.
Definition: dim.hpp:203
static constexpr auto prod(statdim_base< OD >)
Dimension for product of dimensioned values.
static constexpr auto quot(statdim_base< OD >)
Dimension for quotient of dimensioned values.
static constexpr dim nul_dim
Null dimension.
Definition: dim.hpp:263
static constexpr void comparison(statdim_base)
Test for comparison of dimensioned values.
static constexpr dyndim_base pow(dim::rat p)
Dimension for rational power of dimensioned value.
static constexpr auto sum(statdim_base)
Dimension for sum of dimensioned values.
static constexpr void number()
Throw if dimension be non-null.
static constexpr dyndim_base diff(dyndim_base const &db)
Dimension for difference of dimensioned values.
Base-type for a dimensioned value whose dimension is specified statically at compile-time by way of a...
constexpr basic_dim operator*(rat f) const
Multiply exponents by rational factor.
Definition: dim.hpp:211
Thomas E. Vaughan&#39;s public software.
Definition: rational.hpp:13
constexpr statdim_base(dim dd)
Check for compatibility on contruction from dim.
static constexpr auto sqrt()
Dimension for square-root of dimensioned value.
Classes and functions supporting a model of physically dimensioned quantities.
static constexpr auto recip_dim
Dimensions corresponding to reciprocal of dimensioned quantity.
constexpr bool operator!=(basic_dim const &d) const
Definition: dim.hpp:229
static constexpr void comparison(dyndim_base const &db)
Test for comparison of dimensioned values.
constexpr basic_dim operator/(rat f) const
Divide exponents by rational factor.
Definition: dim.hpp:217