Falaise  4.0.1
SuperNEMO Software Toolkit
quantity.h
Go to the documentation of this file.
1 //! \file quantity.h
2 //! \brief Types for configuration validation of physical quantities
3 #ifndef FALAISE_QUANTITY_H
4 #define FALAISE_QUANTITY_H
5 
6 #include <exception>
7 #include "CLHEP/Units/PhysicalConstants.h"
8 #include "CLHEP/Units/SystemOfUnits.h"
10 #include "boost/metaparse/string.hpp"
11 #include "boost/mpl/string.hpp"
12 
13 //! Register a dimension tag for use as a @ref falaise::config::quantity_t template parameter
14 /*!
15  * Expansion defines a struct for the tag, and a type alias for convenience
16  * e.g.
17  *
18  * ```cpp
19  * FALAISE_ADD_DIMENSION_TAG(length)
20  *
21  * // Expansion results in definition of:
22  * namespace falaise {
23  * namespace config {
24  * struct length {...};
25  * using length_t = quantity_t<length>;
26  * }
27  * }
28  * ```
29  * The string equivalent of the passed parameter must be registered with the
30  * @ref datatools::units::registry dimension/unit store.
31  *
32  * Client code can then use the type alias directly, e.g.
33  *
34  * ```cpp
35  * falaise::config::length_t x{3.14, "m"};
36  * ```
37  *
38  * \param Tag tag for the dimension, which must be known to @ref datatools::units::registry
39  */
40 #define FALAISE_ADD_DIMENSION_TAG(Tag) \
41  namespace falaise { \
42  namespace config { \
43  struct Tag { \
44  typedef BOOST_METAPARSE_STRING(#Tag) label; \
45  }; \
46  using Tag##_t = quantity_t<Tag>; \
47  } \
48  }
49 
50 namespace falaise {
51 namespace config {
52 //! Exception reporting wrong or incompatible dimensions
53 class wrong_dimension_error : public std::logic_error {
54  using std::logic_error::logic_error;
55 };
56 
57 //! Exception reporting unknown unit tags
58 class unknown_unit_error : public std::logic_error {
59  using std::logic_error::logic_error;
60 };
61 
62 //! Class representing a value and physical unit
63 /*!
64  * @ref quantity is a simple holder for @ref datatools::properties values
65  * that are marked with an explicit unit. In properties files, these are declared as
66  *
67  * ```ini
68  * foo : real as length = 3.14 m
69  * ```
70  *
71  * where `length` is the dimension, and `m` is the explicit unit. @ref quantity composes this value,
72  * unit, and dimension into a single object allowing these to be queried and the value directly
73  * converted to the internal CLHEP::Units numeric representation. For example:
74  *
75  * ```cpp
76  * auto x = falaise::config::quantity{3.14, "m"}; // valid
77  * auto y = falaise::config::quantity{4.13, "furlong"}; // throws, "furlong" not a known unit
78  *
79  * double forCalc = x(); // value is 3.14*CLHEP::meter, so 3140.0
80  * ```
81  *
82  * In general, you should not use @ref quantity directly, but rather the typed @ref falaise_units
83  * concrete classes for the physical quantities you need (e.g. @ref length_t for length parameters).
84  * @ref quantity only validates that the unit is known to @ref datatools::units, whereas the
85  * @ref falaise_units types provide strict dimensional correctness.
86  *
87  * \sa falaise_units
88  * \sa quantity_t
89  */
90 class quantity {
91  public:
92  //! Default constructor
93  /*!
94  * Initializes as an effectively zero value dimensionless parameter
95  */
96  quantity() = default;
97 
98  //! Construct a quantity from a value and unit
99  /*!
100  * \param[in] value Numeric value in units of unit
101  * \param[in] unit @ref datatools::units::unit tag
102  * \throws falaise::config::unknown_unit_error if unit is not supported by @ref datatools::units
103  */
104  quantity(double value, std::string const& unit);
105 
106  //! Destructor
107  virtual ~quantity() = default;
108 
109  //! Convert quantity to `double` value in the CLHEP::Units numeric scaling system
110  /*!
111  * For example:
112  *
113  * ```cpp
114  * falaise::config::quantity q{3.14, "m"};
115  * double x = q();
116  * std::cout << x << std::endl; // prints 3140.0
117  * ```
118  *
119  * \returns quantity's value multiplied by its unit's CLHEP::Units scaling factor
120  */
121  inline double operator()() const { return value_ * unit_scale; }
122 
123  //! Return the value for the quantity in its units
124  /*!
125  * For example:
126  *
127  * ```cpp
128  * falaise::config::quantity x{3.14, "m"};
129  * std::cout << x.value() << std::endl; // prints 3.14
130  * ```
131  *
132  */
133  inline double value() const { return value_; }
134 
135  //! Return value for the quantity in given units
136  /*
137  * For example:
138  *
139  * ```cpp
140  * falaise::config::quantity x{3.14, "m"};
141  * std::cout << x.value_in("mm") << std::endl; //prints 3140.0
142  *
143  * \throws bad_unit_error if supplied unit's dimension is different to
144  * that of the quantity
145  */
146  double value_in(std::string const& unit) const;
147 
148  //! Return datatools::units tag for the quantity's unit
149  inline std::string const& unit() const { return unit_name; }
150 
151  //! Return datatools::unit tag for the quantity's dimension
152  inline std::string const& dimension() const { return dimension_name; }
153 
154  private:
155  double value_{0.0};
156  std::string unit_name{""};
157  std::string dimension_name{""};
158  double unit_scale{1.0};
159 };
160 
161 //! Template class for a physical value with a strict dimension
162 /*!
163  * Provides a concrete class of @ref quantity, enforcing
164  *
165  * Dimensional correctness is enforced by requiring that the unit
166  * supplied to the constructor is:
167  *
168  * 1. Known to the @ref datatools::units system
169  * 2. Has a @ref datatools::units dimension tag identical to the value
170  * of the `Dimension` template parameter's `label` type.
171  *
172  * The template parameter must provide a public typedef `label` to
173  * a `boost::mpl::string`.
174  *
175  * Client code should prefer to use the predefined type aliases for
176  * all known @ref datatools::units dimensions (see @ref falaise_units)
177  *
178  * \tparam Dimension dimensional tag for the quantity
179  *
180  * \sa FALAISE_ADD_DIMENSION_TAG
181  * \sa falaise_units
182  * \sa quantity
183  */
184 template <typename Dimension>
185 class quantity_t : public quantity {
186  public:
187  //! Default constructor
188  /*!
189  * Initializes quantity with zero value and default units for Dimension
190  *
191  * \tparam Dimension dimension tag for this quantity_t
192  */
195  boost::mpl::c_str<typename Dimension::label>::value)) {}
196 
197  //! Construct a quantity from a value and unit
198  /*!
199  * \param[in] value Numeric value
200  * \param[in] unit @ref datatools::units::unit tag
201  * \throws falaise::config::unknown_unit_error if unit is not supported by @ref
202  * datatools::units::unit \throws falaise::config::wrong_dimension_error if unit's dimension does
203  * not match the Dimension type parameter tag
204  */
205  quantity_t(double value, std::string const& unit) : quantity(value, unit) {
206  if (boost::mpl::c_str<typename Dimension::label>::value != dimension()) {
207  throw wrong_dimension_error("dimension of unit '" + unit + "' is not '" +
208  boost::mpl::c_str<typename Dimension::label>::value + "'");
209  }
210  }
211 
212  //! Copy constructor from a raw @ref quantity
213  /*!
214  * \tparam Dimension dimension tag for this quantity_t
215  * \param[in] q quantity to copy from
216  * \throws falaise::config::wrong_dimension_error if dimension of q does not match the Dimension
217  * tag
218  */
219  quantity_t(quantity const& q) : quantity_t(q.value(), q.unit()) {}
220 
221  //! Destructor
222  virtual ~quantity_t() = default;
223 };
224 } // namespace config
225 } // namespace falaise
226 
227 /*! \defgroup falaise_units System of Units
228  * \brief System of Units used internally by Falaise
229  *
230  * Physical units in Falaise are handled by a two level system. Parameters
231  * passed as configuration via @ref datatools::properties are handled by
232  * concrete classes of @ref falaise::config::quantity_t to enforce dimensional
233  * correctness. For example:
234  *
235  * ```cpp
236  * // Throws unless the "x" property was written as "x : real as length = VALUE LENGTHUNIT"
237  * auto x = ps.get<falaise::config::length_t>("x");
238  * ```
239  *
240  * Internal C++ code in Falaise or plugins treats physical units as raw
241  * `double`s, using `CLHEP::Units` library to provide scaling
242  * factors for numerical correctness. It is up to the developer to maintain
243  * the dimensional correctness of all calculations.
244  *
245  * The concrete classes of @ref falaise::config::quantity_t listed can be
246  * converted to `double` values in the `CLHEP::Units` numeric system via
247  * the overloaded function call operator:
248  *
249  * ```cpp
250  * falaise::config::length_t l{3.14, "m"};
251  * double x{l()}; // or double x = l();
252  * std::cout << x << std::endl; // Prints "3140.0"
253  * ```
254  *
255  * It is recommended that you *only* use the @ref falaise::config::quantity_t
256  * for parameter validation, storing extracted values in `double`s for actual
257  * calculation. The concrete types do not provide any dimensional analysis
258  * functionality, so the following will not compile:
259  *
260  * ```cpp
261  * falaise::config::mass_t m{1.0,"kg"};
262  * falaise::config::acceleration_t a{1.0, "m/s2"};
263  *
264  * falaise::config::force_t fa = m*a; // compile error;
265  * falaise::config::force_t fb = m()*a(); //compile error;
266  *
267  * double fc = m()*a(); //o.k., dimensionless, but in CLHEP::Units scale
268  * ```
269  *
270  * This is intentional so as to closely map the functionality of the
271  * underlying @ref datatools::units interface as a pure numeric/scaling
272  * system. The developer must exercise care in using the extracted `double`
273  * parameters to maintain dimensional correctness, but their values are
274  * guaranteed to be valid in `CLHEP::Units` system.
275  *
276  * \sa falaise::config::quantity_t
277  * \sa falaise::config::property_set
278  */
279 
280 /*! \class falaise::config::absorbed_dose_t
281  * \ingroup falaise_units
282  * \brief quantity for values with dimension tag `absorbed_dose` ([L2][T-2])
283  *
284  * A @ref absorbed_dose_t value may be constructed using, for example
285  *
286  * ```cpp
287  * falaise::config::absorbed_dose_t x{3.14, "TAG"};
288  * ```
289  *
290  * where `TAG` is one of the following valid unit tags:
291  *
292  * - `_rad`
293  * - `gray`
294  * - `kilogray`
295  * - `microgray`
296  * - `milligray`
297  *
298  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
299  */
301 
302 /*! \class falaise::config::acceleration_t
303  * \ingroup falaise_units
304  * \brief quantity for values with dimension tag `acceleration` ([L][T-2])
305  *
306  * A @ref acceleration_t value may be constructed using, for example
307  *
308  * ```cpp
309  * falaise::config::acceleration_t x{3.14, "TAG"};
310  * ```
311  *
312  * where `TAG` is one of the following valid unit tags:
313  *
314  * - `m/s2`
315  *
316  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
317  */
318 FALAISE_ADD_DIMENSION_TAG(acceleration)
319 
320 /*! \class falaise::config::activity_t
321  * \ingroup falaise_units
322  * \brief quantity for values with dimension tag `activity` ([T-1])
323  *
324  * A @ref activity_t value may be constructed using, for example
325  *
326  * ```cpp
327  * falaise::config::activity_t x{3.14, "TAG"};
328  * ```
329  *
330  * where `TAG` is one of the following valid unit tags:
331  *
332  * - `becquerel`
333  * - `curie`
334  * - `dpm`
335  * - `gigabecquerel`
336  * - `kilobecquerel`
337  * - `kilocurie`
338  * - `megabecquerel`
339  * - `megacurie`
340  * - `microbecquerel`
341  * - `microcurie`
342  * - `millibecquerel`
343  * - `millicurie`
344  * - `nanocurie`
345  * - `picocurie`
346  *
347  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
348  */
350 
351 /*! \class falaise::config::amount_t
352  * \ingroup falaise_units
353  * \brief quantity for values with dimension tag `amount` ([N])
354  *
355  * A @ref amount_t value may be constructed using, for example
356  *
357  * ```cpp
358  * falaise::config::amount_t x{3.14, "TAG"};
359  * ```
360  *
361  * where `TAG` is one of the following valid unit tags:
362  *
363  * - `mole`
364  *
365  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
366  */
368 
369 /*! \class falaise::config::angle_t
370  * \ingroup falaise_units
371  * \brief quantity for values with dimension tag `angle` ([1])
372  *
373  * A @ref angle_t value may be constructed using, for example
374  *
375  * ```cpp
376  * falaise::config::angle_t x{3.14, "TAG"};
377  * ```
378  *
379  * where `TAG` is one of the following valid unit tags:
380  *
381  * - `arcminute`
382  * - `arcsecond`
383  * - `degree`
384  * - `grade`
385  * - `microarcsecond`
386  * - `microradian`
387  * - `milliarcsecond`
388  * - `milliradian`
389  * - `radian`
390  * - `turn`
391  *
392  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
393  */
395 
396 /*! \class falaise::config::angular_frequency_t
397  * \ingroup falaise_units
398  * \brief quantity for values with dimension tag `angular_frequency` ([T-1])
399  *
400  * A @ref angular_frequency_t value may be constructed using, for example
401  *
402  * ```cpp
403  * falaise::config::angular_frequency_t x{3.14, "TAG"};
404  * ```
405  *
406  * where `TAG` is one of the following valid unit tags:
407  *
408  * - `rad/s`
409  *
410  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
411  */
412 FALAISE_ADD_DIMENSION_TAG(angular_frequency)
413 
414 /*! \class falaise::config::capacitance_t
415  * \ingroup falaise_units
416  * \brief quantity for values with dimension tag `capacitance` ([M-1][L-2][T4][I2])
417  *
418  * A @ref capacitance_t value may be constructed using, for example
419  *
420  * ```cpp
421  * falaise::config::capacitance_t x{3.14, "TAG"};
422  * ```
423  *
424  * where `TAG` is one of the following valid unit tags:
425  *
426  * - `farad`
427  * - `femtofarad`
428  * - `microfarad`
429  * - `millifarad`
430  * - `nanofarad`
431  * - `picofarad`
432  *
433  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
434  */
435 FALAISE_ADD_DIMENSION_TAG(capacitance)
436 
437 /*! \class falaise::config::conductance_t
438  * \ingroup falaise_units
439  * \brief quantity for values with dimension tag `conductance` ([M-1][L-2][T3][I2])
440  *
441  * A @ref conductance_t value may be constructed using, for example
442  *
443  * ```cpp
444  * falaise::config::conductance_t x{3.14, "TAG"};
445  * ```
446  *
447  * where `TAG` is one of the following valid unit tags:
448  *
449  * - `siemens`
450  *
451  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
452  */
453 FALAISE_ADD_DIMENSION_TAG(conductance)
454 
455 /*! \class falaise::config::conductivity_t
456  * \ingroup falaise_units
457  * \brief quantity for values with dimension tag `conductivity` ([M-2][L-2][T3][I2])
458  *
459  * A @ref conductivity_t value may be constructed using, for example
460  *
461  * ```cpp
462  * falaise::config::conductivity_t x{3.14, "TAG"};
463  * ```
464  *
465  * where `TAG` is one of the following valid unit tags:
466  *
467  * - `S/m`
468  *
469  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
470  */
471 FALAISE_ADD_DIMENSION_TAG(conductivity)
472 
473 /*! \class falaise::config::cross_section_t
474  * \ingroup falaise_units
475  * \brief quantity for values with dimension tag `cross_section` ([L2])
476  *
477  * A @ref cross_section_t value may be constructed using, for example
478  *
479  * ```cpp
480  * falaise::config::cross_section_t x{3.14, "TAG"};
481  * ```
482  *
483  * where `TAG` is one of the following valid unit tags:
484  *
485  * - `barn`
486  * - `femtobarn`
487  * - `kilobarn`
488  * - `megabarn`
489  * - `microbarn`
490  * - `millibarn`
491  * - `nanobarn`
492  * - `picobarn`
493  *
494  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
495  */
496 FALAISE_ADD_DIMENSION_TAG(cross_section)
497 
498 /*! \class falaise::config::data_storage_t
499  * \ingroup falaise_units
500  * \brief quantity for values with dimension tag `data_storage` ([1])
501  *
502  * A @ref data_storage_t value may be constructed using, for example
503  *
504  * ```cpp
505  * falaise::config::data_storage_t x{3.14, "TAG"};
506  * ```
507  *
508  * where `TAG` is one of the following valid unit tags:
509  *
510  * - `bit`
511  * - `byte`
512  * - `exabit`
513  * - `exabyte`
514  * - `exbibit`
515  * - `exbibyte`
516  * - `gibibit`
517  * - `gibibyte`
518  * - `gigabit`
519  * - `gigabyte`
520  * - `kibibit`
521  * - `kibibyte`
522  * - `kilobit`
523  * - `kilobyte`
524  * - `mebibit`
525  * - `mebibyte`
526  * - `megabit`
527  * - `megabyte`
528  * - `pebibit`
529  * - `pebibyte`
530  * - `petabit`
531  * - `petabyte`
532  * - `tebibit`
533  * - `tebibyte`
534  * - `terabit`
535  * - `terabyte`
536  * - `yobibit`
537  * - `yobibyte`
538  * - `yottabit`
539  * - `yottabyte`
540  * - `zebibit`
541  * - `zebibyte`
542  * - `zettabit`
543  * - `zettabyte`
544  *
545  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
546  */
547 FALAISE_ADD_DIMENSION_TAG(data_storage)
548 
549 /*! \class falaise::config::data_transfer_rate_t
550  * \ingroup falaise_units
551  * \brief quantity for values with dimension tag `data_transfer_rate` ([T-1])
552  *
553  * A @ref data_transfer_rate_t value may be constructed using, for example
554  *
555  * ```cpp
556  * falaise::config::data_transfer_rate_t x{3.14, "TAG"};
557  * ```
558  *
559  * where `TAG` is one of the following valid unit tags:
560  *
561  * - `bit/s`
562  * - `byte/s`
563  * - `gibibit/s`
564  * - `gibibyte/s`
565  * - `gigabit/s`
566  * - `gigabyte/s`
567  * - `kibibit/s`
568  * - `kibibyte/s`
569  * - `kilobit/s`
570  * - `kilobyte/s`
571  * - `mebibit/s`
572  * - `mebibyte/s`
573  * - `megabit/s`
574  * - `megabyte/s`
575  * - `tebibit/s`
576  * - `tebibyte/s`
577  * - `terabit/s`
578  * - `terabyte/s`
579  *
580  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
581  */
582 FALAISE_ADD_DIMENSION_TAG(data_transfer_rate)
583 
584 /*! \class falaise::config::density_t
585  * \ingroup falaise_units
586  * \brief quantity for values with dimension tag `density` ([M][L-3])
587  *
588  * A @ref density_t value may be constructed using, for example
589  *
590  * ```cpp
591  * falaise::config::density_t x{3.14, "TAG"};
592  * ```
593  *
594  * where `TAG` is one of the following valid unit tags:
595  *
596  * - `g/cm3`
597  * - `g/mL`
598  * - `kg/L`
599  * - `kg/m3`
600  * - `mg/cm3`
601  * - `t/m3`
602  *
603  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
604  */
606 
607 /*! \class falaise::config::electric_charge_t
608  * \ingroup falaise_units
609  * \brief quantity for values with dimension tag `electric_charge` ([T][I])
610  *
611  * A @ref electric_charge_t value may be constructed using, for example
612  *
613  * ```cpp
614  * falaise::config::electric_charge_t x{3.14, "TAG"};
615  * ```
616  *
617  * where `TAG` is one of the following valid unit tags:
618  *
619  * - `coulomb`
620  * - `femtocoulomb`
621  * - `microcoulomb`
622  * - `millicoulomb`
623  * - `nanocoulomb`
624  * - `picocoulomb`
625  *
626  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
627  */
628 FALAISE_ADD_DIMENSION_TAG(electric_charge)
629 
630 /*! \class falaise::config::electric_current_t
631  * \ingroup falaise_units
632  * \brief quantity for values with dimension tag `electric_current` ([I])
633  *
634  * A @ref electric_current_t value may be constructed using, for example
635  *
636  * ```cpp
637  * falaise::config::electric_current_t x{3.14, "TAG"};
638  * ```
639  *
640  * where `TAG` is one of the following valid unit tags:
641  *
642  * - `ampere`
643  * - `femtoampere`
644  * - `kiloampere`
645  * - `megaampere`
646  * - `microampere`
647  * - `milliampere`
648  * - `nanoampere`
649  * - `picoampere`
650  *
651  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
652  */
653 FALAISE_ADD_DIMENSION_TAG(electric_current)
654 
655 /*! \class falaise::config::electric_displacement_field_t
656  * \ingroup falaise_units
657  * \brief quantity for values with dimension tag `electric_displacement_field` ([L-2][T][I])
658  *
659  * A @ref electric_displacement_field_t value may be constructed using, for example
660  *
661  * ```cpp
662  * falaise::config::electric_displacement_field_t x{3.14, "TAG"};
663  * ```
664  *
665  * where `TAG` is one of the following valid unit tags:
666  *
667  * - `C/m2`
668  *
669  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
670  */
671 FALAISE_ADD_DIMENSION_TAG(electric_displacement_field)
672 
673 /*! \class falaise::config::electric_field_t
674  * \ingroup falaise_units
675  * \brief quantity for values with dimension tag `electric_field` ([M][L][T-3][I-1])
676  *
677  * A @ref electric_field_t value may be constructed using, for example
678  *
679  * ```cpp
680  * falaise::config::electric_field_t x{3.14, "TAG"};
681  * ```
682  *
683  * where `TAG` is one of the following valid unit tags:
684  *
685  * - `V/cm`
686  * - `V/m`
687  * - `kV/cm`
688  * - `kV/m`
689  *
690  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
691  */
692 FALAISE_ADD_DIMENSION_TAG(electric_field)
693 
694 /*! \class falaise::config::electric_flux_t
695  * \ingroup falaise_units
696  * \brief quantity for values with dimension tag `electric_flux` ([M][L3][T-3][I-1])
697  *
698  * A @ref electric_flux_t value may be constructed using, for example
699  *
700  * ```cpp
701  * falaise::config::electric_flux_t x{3.14, "TAG"};
702  * ```
703  *
704  * where `TAG` is one of the following valid unit tags:
705  *
706  * - `V.m`
707  *
708  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
709  */
710 FALAISE_ADD_DIMENSION_TAG(electric_flux)
711 
712 /*! \class falaise::config::electric_potential_t
713  * \ingroup falaise_units
714  * \brief quantity for values with dimension tag `electric_potential` ([M][L2][T-3][I-1])
715  *
716  * A @ref electric_potential_t value may be constructed using, for example
717  *
718  * ```cpp
719  * falaise::config::electric_potential_t x{3.14, "TAG"};
720  * ```
721  *
722  * where `TAG` is one of the following valid unit tags:
723  *
724  * - `kilovolt`
725  * - `megavolt`
726  * - `microvolt`
727  * - `millivolt`
728  * - `volt`
729  *
730  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
731  */
732 FALAISE_ADD_DIMENSION_TAG(electric_potential)
733 
734 /*! \class falaise::config::electric_resistance_t
735  * \ingroup falaise_units
736  * \brief quantity for values with dimension tag `electric_resistance` ([M][L2][T-3][I-2])
737  *
738  * A @ref electric_resistance_t value may be constructed using, for example
739  *
740  * ```cpp
741  * falaise::config::electric_resistance_t x{3.14, "TAG"};
742  * ```
743  *
744  * where `TAG` is one of the following valid unit tags:
745  *
746  * - `kiloohm`
747  * - `megaohm`
748  * - `ohm`
749  *
750  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
751  */
752 FALAISE_ADD_DIMENSION_TAG(electric_resistance)
753 
754 /*! \class falaise::config::electric_signal_integral_t
755  * \ingroup falaise_units
756  * \brief quantity for values with dimension tag `electric_signal_integral` ([M][L2][T-2][I-1])
757  *
758  * A @ref electric_signal_integral_t value may be constructed using, for example
759  *
760  * ```cpp
761  * falaise::config::electric_signal_integral_t x{3.14, "TAG"};
762  * ```
763  *
764  * where `TAG` is one of the following valid unit tags:
765  *
766  * - `nV.s`
767  *
768  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
769  */
770 FALAISE_ADD_DIMENSION_TAG(electric_signal_integral)
771 
772 /*! \class falaise::config::energy_t
773  * \ingroup falaise_units
774  * \brief quantity for values with dimension tag `energy` ([M][L2][T-2])
775  *
776  * A @ref energy_t value may be constructed using, for example
777  *
778  * ```cpp
779  * falaise::config::energy_t x{3.14, "TAG"};
780  * ```
781  *
782  * where `TAG` is one of the following valid unit tags:
783  *
784  * - `electronvolt`
785  * - `gigaelectronvolt`
786  * - `joule`
787  * - `kiloelectronvolt`
788  * - `megaelectronvolt`
789  * - `microelectronvolt`
790  * - `millielectronvolt`
791  * - `nanoelectronvolt`
792  * - `petaelectronvolt`
793  * - `teraelectronvolt`
794  *
795  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
796  */
798 
799 /*! \class falaise::config::equivalent_dose_t
800  * \ingroup falaise_units
801  * \brief quantity for values with dimension tag `equivalent_dose` ([L2][T-2])
802  *
803  * A @ref equivalent_dose_t value may be constructed using, for example
804  *
805  * ```cpp
806  * falaise::config::equivalent_dose_t x{3.14, "TAG"};
807  * ```
808  *
809  * where `TAG` is one of the following valid unit tags:
810  *
811  * - `microsievert`
812  * - `millisievert`
813  * - `nanosievert`
814  * - `picosievert`
815  * - `rem`
816  * - `sievert`
817  *
818  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
819  */
820 FALAISE_ADD_DIMENSION_TAG(equivalent_dose)
821 
822 /*! \class falaise::config::force_t
823  * \ingroup falaise_units
824  * \brief quantity for values with dimension tag `force` ([M][L][T-2])
825  *
826  * A @ref force_t value may be constructed using, for example
827  *
828  * ```cpp
829  * falaise::config::force_t x{3.14, "TAG"};
830  * ```
831  *
832  * where `TAG` is one of the following valid unit tags:
833  *
834  * - `dyne`
835  * - `kilonewton`
836  * - `newton`
837  *
838  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
839  */
841 
842 /*! \class falaise::config::fraction_t
843  * \ingroup falaise_units
844  * \brief quantity for values with dimension tag `fraction` ([1])
845  *
846  * A @ref fraction_t value may be constructed using, for example
847  *
848  * ```cpp
849  * falaise::config::fraction_t x{3.14, "TAG"};
850  * ```
851  *
852  * where `TAG` is one of the following valid unit tags:
853  *
854  * - `percent`
855  * - `perthousand`
856  * - `ppb`
857  * - `ppm`
858  * - `ppq`
859  * - `ppt`
860  *
861  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
862  */
864 
865 /*! \class falaise::config::frequency_t
866  * \ingroup falaise_units
867  * \brief quantity for values with dimension tag `frequency` ([T-1])
868  *
869  * A @ref frequency_t value may be constructed using, for example
870  *
871  * ```cpp
872  * falaise::config::frequency_t x{3.14, "TAG"};
873  * ```
874  *
875  * where `TAG` is one of the following valid unit tags:
876  *
877  * - `cpm`
878  * - `gigahertz`
879  * - `hertz`
880  * - `kilohertz`
881  * - `megahertz`
882  * - `millihertz`
883  *
884  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
885  */
886 FALAISE_ADD_DIMENSION_TAG(frequency)
887 
888 /*! \class falaise::config::illuminance_t
889  * \ingroup falaise_units
890  * \brief quantity for values with dimension tag `illuminance` ()
891  *
892  * A @ref illuminance_t value may be constructed using, for example
893  *
894  * ```cpp
895  * falaise::config::illuminance_t x{3.14, "TAG"};
896  * ```
897  *
898  * where `TAG` is one of the following valid unit tags:
899  *
900  * - `lux`
901  *
902  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
903  */
904 FALAISE_ADD_DIMENSION_TAG(illuminance)
905 
906 /*! \class falaise::config::inductance_t
907  * \ingroup falaise_units
908  * \brief quantity for values with dimension tag `inductance` ([M][L2][T-2][I-2])
909  *
910  * A @ref inductance_t value may be constructed using, for example
911  *
912  * ```cpp
913  * falaise::config::inductance_t x{3.14, "TAG"};
914  * ```
915  *
916  * where `TAG` is one of the following valid unit tags:
917  *
918  * - `henry`
919  * - `microhenry`
920  * - `millihenry`
921  *
922  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
923  */
924 FALAISE_ADD_DIMENSION_TAG(inductance)
925 
926 /*! \class falaise::config::length_t
927  * \ingroup falaise_units
928  * \brief quantity for values with dimension tag `length` ([L])
929  *
930  * A @ref length_t value may be constructed using, for example
931  *
932  * ```cpp
933  * falaise::config::length_t x{3.14, "TAG"};
934  * ```
935  *
936  * where `TAG` is one of the following valid unit tags:
937  *
938  * - `angstrom`
939  * - `astronomical_unit`
940  * - `centimeter`
941  * - `decameter`
942  * - `decimeter`
943  * - `femtometer`
944  * - `foot`
945  * - `gigalight_year`
946  * - `gigaparsec`
947  * - `hectometer`
948  * - `inch`
949  * - `kilolight_year`
950  * - `kilometer`
951  * - `kiloparsec`
952  * - `light_year`
953  * - `megalight_year`
954  * - `megaparsec`
955  * - `meter`
956  * - `micrometer`
957  * - `mile`
958  * - `millimeter`
959  * - `nanometer`
960  * - `nautical_mile`
961  * - `parsec`
962  * - `picometer`
963  * - `yard`
964  *
965  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
966  */
968 
969 /*! \class falaise::config::level_t
970  * \ingroup falaise_units
971  * \brief quantity for values with dimension tag `level` ([1])
972  *
973  * A @ref level_t value may be constructed using, for example
974  *
975  * ```cpp
976  * falaise::config::level_t x{3.14, "TAG"};
977  * ```
978  *
979  * where `TAG` is one of the following valid unit tags:
980  *
981  * - `bel`
982  * - `decibel`
983  * - `neper`
984  *
985  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
986  */
988 
989 /*! \class falaise::config::luminance_t
990  * \ingroup falaise_units
991  * \brief quantity for values with dimension tag `luminance` ([L-2][J])
992  *
993  * A @ref luminance_t value may be constructed using, for example
994  *
995  * ```cpp
996  * falaise::config::luminance_t x{3.14, "TAG"};
997  * ```
998  *
999  * where `TAG` is one of the following valid unit tags:
1000  *
1001  * - `cd/m2`
1002  *
1003  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1004  */
1005 FALAISE_ADD_DIMENSION_TAG(luminance)
1006 
1007 /*! \class falaise::config::luminous_energy_t
1008  * \ingroup falaise_units
1009  * \brief quantity for values with dimension tag `luminous_energy` ()
1010  *
1011  * A @ref luminous_energy_t value may be constructed using, for example
1012  *
1013  * ```cpp
1014  * falaise::config::luminous_energy_t x{3.14, "TAG"};
1015  * ```
1016  *
1017  * where `TAG` is one of the following valid unit tags:
1018  *
1019  * - `lm.s`
1020  *
1021  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1022  */
1023 FALAISE_ADD_DIMENSION_TAG(luminous_energy)
1024 
1025 /*! \class falaise::config::luminous_energy_density_t
1026  * \ingroup falaise_units
1027  * \brief quantity for values with dimension tag `luminous_energy_density` ()
1028  *
1029  * A @ref luminous_energy_density_t value may be constructed using, for example
1030  *
1031  * ```cpp
1032  * falaise::config::luminous_energy_density_t x{3.14, "TAG"};
1033  * ```
1034  *
1035  * where `TAG` is one of the following valid unit tags:
1036  *
1037  * - `lx.s/m3`
1038  *
1039  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1040  */
1041 FALAISE_ADD_DIMENSION_TAG(luminous_energy_density)
1042 
1043 /*! \class falaise::config::luminous_exposure_t
1044  * \ingroup falaise_units
1045  * \brief quantity for values with dimension tag `luminous_exposure` ()
1046  *
1047  * A @ref luminous_exposure_t value may be constructed using, for example
1048  *
1049  * ```cpp
1050  * falaise::config::luminous_exposure_t x{3.14, "TAG"};
1051  * ```
1052  *
1053  * where `TAG` is one of the following valid unit tags:
1054  *
1055  * - `lx.s`
1056  *
1057  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1058  */
1059 FALAISE_ADD_DIMENSION_TAG(luminous_exposure)
1060 
1061 /*! \class falaise::config::luminous_flux_t
1062  * \ingroup falaise_units
1063  * \brief quantity for values with dimension tag `luminous_flux` ()
1064  *
1065  * A @ref luminous_flux_t value may be constructed using, for example
1066  *
1067  * ```cpp
1068  * falaise::config::luminous_flux_t x{3.14, "TAG"};
1069  * ```
1070  *
1071  * where `TAG` is one of the following valid unit tags:
1072  *
1073  * - `lumen`
1074  *
1075  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1076  */
1077 FALAISE_ADD_DIMENSION_TAG(luminous_flux)
1078 
1079 /*! \class falaise::config::luminous_intensity_t
1080  * \ingroup falaise_units
1081  * \brief quantity for values with dimension tag `luminous_intensity` ([J])
1082  *
1083  * A @ref luminous_intensity_t value may be constructed using, for example
1084  *
1085  * ```cpp
1086  * falaise::config::luminous_intensity_t x{3.14, "TAG"};
1087  * ```
1088  *
1089  * where `TAG` is one of the following valid unit tags:
1090  *
1091  * - `candela`
1092  *
1093  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1094  */
1095 FALAISE_ADD_DIMENSION_TAG(luminous_intensity)
1096 
1097 /*! \class falaise::config::magnetic_field_strength_t
1098  * \ingroup falaise_units
1099  * \brief quantity for values with dimension tag `magnetic_field_strength` ([L-1][I])
1100  *
1101  * A @ref magnetic_field_strength_t value may be constructed using, for example
1102  *
1103  * ```cpp
1104  * falaise::config::magnetic_field_strength_t x{3.14, "TAG"};
1105  * ```
1106  *
1107  * where `TAG` is one of the following valid unit tags:
1108  *
1109  * - `A/m`
1110  *
1111  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1112  */
1113 FALAISE_ADD_DIMENSION_TAG(magnetic_field_strength)
1114 
1115 /*! \class falaise::config::magnetic_flux_t
1116  * \ingroup falaise_units
1117  * \brief quantity for values with dimension tag `magnetic_flux` ([M][L2][T-2][I-1])
1118  *
1119  * A @ref magnetic_flux_t value may be constructed using, for example
1120  *
1121  * ```cpp
1122  * falaise::config::magnetic_flux_t x{3.14, "TAG"};
1123  * ```
1124  *
1125  * where `TAG` is one of the following valid unit tags:
1126  *
1127  * - `maxwell`
1128  * - `microweber`
1129  * - `milliweber`
1130  * - `nanoweber`
1131  * - `weber`
1132  *
1133  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1134  */
1135 FALAISE_ADD_DIMENSION_TAG(magnetic_flux)
1136 
1137 /*! \class falaise::config::magnetic_flux_density_t
1138  * \ingroup falaise_units
1139  * \brief quantity for values with dimension tag `magnetic_flux_density` ([M][T-2][I-1])
1140  *
1141  * A @ref magnetic_flux_density_t value may be constructed using, for example
1142  *
1143  * ```cpp
1144  * falaise::config::magnetic_flux_density_t x{3.14, "TAG"};
1145  * ```
1146  *
1147  * where `TAG` is one of the following valid unit tags:
1148  *
1149  * - `gauss`
1150  * - `kilogauss`
1151  * - `microtesla`
1152  * - `milligauss`
1153  * - `millitesla`
1154  * - `nanotesla`
1155  * - `tesla`
1156  *
1157  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1158  */
1159 FALAISE_ADD_DIMENSION_TAG(magnetic_flux_density)
1160 
1161 /*! \class falaise::config::mass_t
1162  * \ingroup falaise_units
1163  * \brief quantity for values with dimension tag `mass` ([M])
1164  *
1165  * A @ref mass_t value may be constructed using, for example
1166  *
1167  * ```cpp
1168  * falaise::config::mass_t x{3.14, "TAG"};
1169  * ```
1170  *
1171  * where `TAG` is one of the following valid unit tags:
1172  *
1173  * - `GeV/c2`
1174  * - `MeV/c2`
1175  * - `centigram`
1176  * - `dalton`
1177  * - `decagram`
1178  * - `decigram`
1179  * - `eV/c2`
1180  * - `gram`
1181  * - `hectogram`
1182  * - `kilogram`
1183  * - `microgram`
1184  * - `milligram`
1185  * - `ton`
1186  *
1187  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1188  */
1190 
1191 /*! \class falaise::config::mass_activity_t
1192  * \ingroup falaise_units
1193  * \brief quantity for values with dimension tag `mass_activity` ([M-1][T-1])
1194  *
1195  * A @ref mass_activity_t value may be constructed using, for example
1196  *
1197  * ```cpp
1198  * falaise::config::mass_activity_t x{3.14, "TAG"};
1199  * ```
1200  *
1201  * where `TAG` is one of the following valid unit tags:
1202  *
1203  * - `Bq/kg`
1204  * - `GBq/kg`
1205  * - `MBq/kg`
1206  * - `dpm/kg`
1207  * - `kBq/kg`
1208  * - `mBq/kg`
1209  * - `uBq/kg`
1210  *
1211  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1212  */
1213 FALAISE_ADD_DIMENSION_TAG(mass_activity)
1214 
1215 /*! \class falaise::config::permeability_t
1216  * \ingroup falaise_units
1217  * \brief quantity for values with dimension tag `permeability` ([M][L][T-2][I-2])
1218  *
1219  * A @ref permeability_t value may be constructed using, for example
1220  *
1221  * ```cpp
1222  * falaise::config::permeability_t x{3.14, "TAG"};
1223  * ```
1224  *
1225  * where `TAG` is one of the following valid unit tags:
1226  *
1227  * - `H/m`
1228  *
1229  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1230  */
1231 FALAISE_ADD_DIMENSION_TAG(permeability)
1232 
1233 /*! \class falaise::config::permittivity_t
1234  * \ingroup falaise_units
1235  * \brief quantity for values with dimension tag `permittivity` ([M-1][L-3][T4][I2])
1236  *
1237  * A @ref permittivity_t value may be constructed using, for example
1238  *
1239  * ```cpp
1240  * falaise::config::permittivity_t x{3.14, "TAG"};
1241  * ```
1242  *
1243  * where `TAG` is one of the following valid unit tags:
1244  *
1245  * - `F/m`
1246  *
1247  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1248  */
1249 FALAISE_ADD_DIMENSION_TAG(permittivity)
1250 
1251 /*! \class falaise::config::power_t
1252  * \ingroup falaise_units
1253  * \brief quantity for values with dimension tag `power` ([M][L2][T-3])
1254  *
1255  * A @ref power_t value may be constructed using, for example
1256  *
1257  * ```cpp
1258  * falaise::config::power_t x{3.14, "TAG"};
1259  * ```
1260  *
1261  * where `TAG` is one of the following valid unit tags:
1262  *
1263  * - `gigawatt`
1264  * - `kilowatt`
1265  * - `megawatt`
1266  * - `microwatt`
1267  * - `milliwatt`
1268  * - `nanowatt`
1269  * - `watt`
1270  *
1271  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1272  */
1274 
1275 /*! \class falaise::config::pressure_t
1276  * \ingroup falaise_units
1277  * \brief quantity for values with dimension tag `pressure` ([M][L-1][T-2])
1278  *
1279  * A @ref pressure_t value may be constructed using, for example
1280  *
1281  * ```cpp
1282  * falaise::config::pressure_t x{3.14, "TAG"};
1283  * ```
1284  *
1285  * where `TAG` is one of the following valid unit tags:
1286  *
1287  * - `atmosphere`
1288  * - `bar`
1289  * - `centibar`
1290  * - `cmHg`
1291  * - `decapascal`
1292  * - `decibar`
1293  * - `gigapascal`
1294  * - `hectopascal`
1295  * - `kilobar`
1296  * - `kilopascal`
1297  * - `megabar`
1298  * - `megapascal`
1299  * - `millibar`
1300  * - `millipascal`
1301  * - `pascal`
1302  * - `torr`
1303  *
1304  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1305  */
1306 FALAISE_ADD_DIMENSION_TAG(pressure)
1307 
1308 /*! \class falaise::config::procedure_defined_t
1309  * \ingroup falaise_units
1310  * \brief quantity for values with dimension tag `procedure_defined` ([?])
1311  *
1312  * A @ref procedure_defined_t value may be constructed using, for example
1313  *
1314  * ```cpp
1315  * falaise::config::procedure_defined_t x{3.14, "TAG"};
1316  * ```
1317  *
1318  * where `TAG` is one of the following valid unit tags:
1319  *
1320  * - `arb.unit`
1321  * - `p.d.u.`
1322  * - `pdu`
1323  *
1324  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1325  */
1326 FALAISE_ADD_DIMENSION_TAG(procedure_defined)
1327 
1328 /*! \class falaise::config::resistivity_t
1329  * \ingroup falaise_units
1330  * \brief quantity for values with dimension tag `resistivity` ([M][L3][T-3][I-2])
1331  *
1332  * A @ref resistivity_t value may be constructed using, for example
1333  *
1334  * ```cpp
1335  * falaise::config::resistivity_t x{3.14, "TAG"};
1336  * ```
1337  *
1338  * where `TAG` is one of the following valid unit tags:
1339  *
1340  * - `ohm_meter`
1341  *
1342  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1343  */
1344 FALAISE_ADD_DIMENSION_TAG(resistivity)
1345 
1346 /*! \class falaise::config::solid_angle_t
1347  * \ingroup falaise_units
1348  * \brief quantity for values with dimension tag `solid_angle` ([1])
1349  *
1350  * A @ref solid_angle_t value may be constructed using, for example
1351  *
1352  * ```cpp
1353  * falaise::config::solid_angle_t x{3.14, "TAG"};
1354  * ```
1355  *
1356  * where `TAG` is one of the following valid unit tags:
1357  *
1358  * - `centisteradian`
1359  * - `decasteradian`
1360  * - `decisteradian`
1361  * - `femtosteradian`
1362  * - `microsteradian`
1363  * - `millisteradian`
1364  * - `nanosteradian`
1365  * - `picosteradian`
1366  * - `steradian`
1367  *
1368  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1369  */
1370 FALAISE_ADD_DIMENSION_TAG(solid_angle)
1371 
1372 /*! \class falaise::config::surface_t
1373  * \ingroup falaise_units
1374  * \brief quantity for values with dimension tag `surface` ([L2])
1375  *
1376  * A @ref surface_t value may be constructed using, for example
1377  *
1378  * ```cpp
1379  * falaise::config::surface_t x{3.14, "TAG"};
1380  * ```
1381  *
1382  * where `TAG` is one of the following valid unit tags:
1383  *
1384  * - `centimeter2`
1385  * - `femtometer2`
1386  * - `foot2`
1387  * - `inch2`
1388  * - `kilometer2`
1389  * - `meter2`
1390  * - `micrometer2`
1391  * - `millimeter2`
1392  * - `yard2`
1393  *
1394  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1395  */
1397 
1398 /*! \class falaise::config::surface_activity_t
1399  * \ingroup falaise_units
1400  * \brief quantity for values with dimension tag `surface_activity` ([L-2][T-1])
1401  *
1402  * A @ref surface_activity_t value may be constructed using, for example
1403  *
1404  * ```cpp
1405  * falaise::config::surface_activity_t x{3.14, "TAG"};
1406  * ```
1407  *
1408  * where `TAG` is one of the following valid unit tags:
1409  *
1410  * - `Bq/m2`
1411  * - `GBq/m2`
1412  * - `MBq/m2`
1413  * - `dpm/m2`
1414  * - `kBq/m2`
1415  * - `mBq/m2`
1416  * - `uBq/m2`
1417  *
1418  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1419  */
1420 FALAISE_ADD_DIMENSION_TAG(surface_activity)
1421 
1422 /*! \class falaise::config::surface_density_t
1423  * \ingroup falaise_units
1424  * \brief quantity for values with dimension tag `surface_density` ([M][L-2])
1425  *
1426  * A @ref surface_density_t value may be constructed using, for example
1427  *
1428  * ```cpp
1429  * falaise::config::surface_density_t x{3.14, "TAG"};
1430  * ```
1431  *
1432  * where `TAG` is one of the following valid unit tags:
1433  *
1434  * - `g/cm2`
1435  * - `kg/m2`
1436  *
1437  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1438  */
1439 FALAISE_ADD_DIMENSION_TAG(surface_density)
1440 
1441 /*! \class falaise::config::surface_tension_t
1442  * \ingroup falaise_units
1443  * \brief quantity for values with dimension tag `surface_tension` ([M][T-2])
1444  *
1445  * A @ref surface_tension_t value may be constructed using, for example
1446  *
1447  * ```cpp
1448  * falaise::config::surface_tension_t x{3.14, "TAG"};
1449  * ```
1450  *
1451  * where `TAG` is one of the following valid unit tags:
1452  *
1453  * - `N/m`
1454  * - `dyn/cm`
1455  *
1456  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1457  */
1458 FALAISE_ADD_DIMENSION_TAG(surface_tension)
1459 
1460 /*! \class falaise::config::temperature_t
1461  * \ingroup falaise_units
1462  * \brief quantity for values with dimension tag `temperature` ([theta])
1463  *
1464  * A @ref temperature_t value may be constructed using, for example
1465  *
1466  * ```cpp
1467  * falaise::config::temperature_t x{3.14, "TAG"};
1468  * ```
1469  *
1470  * where `TAG` is one of the following valid unit tags:
1471  *
1472  * - `kelvin`
1473  * - `microkelvin`
1474  * - `millikelvin`
1475  *
1476  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1477  */
1478 FALAISE_ADD_DIMENSION_TAG(temperature)
1479 
1480 /*! \class falaise::config::time_t
1481  * \ingroup falaise_units
1482  * \brief quantity for values with dimension tag `time` ([T])
1483  *
1484  * A @ref time_t value may be constructed using, for example
1485  *
1486  * ```cpp
1487  * falaise::config::time_t x{3.14, "TAG"};
1488  * ```
1489  *
1490  * where `TAG` is one of the following valid unit tags:
1491  *
1492  * - `day`
1493  * - `femtosecond`
1494  * - `hour`
1495  * - `microsecond`
1496  * - `millisecond`
1497  * - `minute`
1498  * - `nanosecond`
1499  * - `picosecond`
1500  * - `second`
1501  * - `week`
1502  *
1503  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1504  */
1506 
1507 /*! \class falaise::config::velocity_t
1508  * \ingroup falaise_units
1509  * \brief quantity for values with dimension tag `velocity` ([L][T-1])
1510  *
1511  * A @ref velocity_t value may be constructed using, for example
1512  *
1513  * ```cpp
1514  * falaise::config::velocity_t x{3.14, "TAG"};
1515  * ```
1516  *
1517  * where `TAG` is one of the following valid unit tags:
1518  *
1519  * - `cm/h`
1520  * - `cm/ms`
1521  * - `cm/ns`
1522  * - `cm/s`
1523  * - `cm/us`
1524  * - `km/h`
1525  * - `km/s`
1526  * - `m/h`
1527  * - `m/ms`
1528  * - `m/ns`
1529  * - `m/s`
1530  * - `m/us`
1531  * - `mm/ms`
1532  * - `mm/ns`
1533  * - `mm/s`
1534  * - `mm/us`
1535  * - `mph`
1536  *
1537  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1538  */
1539 FALAISE_ADD_DIMENSION_TAG(velocity)
1540 
1541 /*! \class falaise::config::volume_t
1542  * \ingroup falaise_units
1543  * \brief quantity for values with dimension tag `volume` ([L3])
1544  *
1545  * A @ref volume_t value may be constructed using, for example
1546  *
1547  * ```cpp
1548  * falaise::config::volume_t x{3.14, "TAG"};
1549  * ```
1550  *
1551  * where `TAG` is one of the following valid unit tags:
1552  *
1553  * - `centilitre`
1554  * - `centimeter3`
1555  * - `decalitre`
1556  * - `decimeter3`
1557  * - `foot3`
1558  * - `gigalitre`
1559  * - `hectolitre`
1560  * - `imperial_gallon`
1561  * - `inch3`
1562  * - `kilolitre`
1563  * - `kilometer3`
1564  * - `litre`
1565  * - `megalitre`
1566  * - `meter3`
1567  * - `microlitre`
1568  * - `millilitre`
1569  * - `millimeter3`
1570  * - `teralitre`
1571  * - `us_gallon`
1572  *
1573  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1574  */
1576 
1577 /*! \class falaise::config::volume_activity_t
1578  * \ingroup falaise_units
1579  * \brief quantity for values with dimension tag `volume_activity` ([L-3][T-1])
1580  *
1581  * A @ref volume_activity_t value may be constructed using, for example
1582  *
1583  * ```cpp
1584  * falaise::config::volume_activity_t x{3.14, "TAG"};
1585  * ```
1586  *
1587  * where `TAG` is one of the following valid unit tags:
1588  *
1589  * - `Bq/m3`
1590  * - `GBq/m3`
1591  * - `MBq/m3`
1592  * - `dpm/m3`
1593  * - `kBq/m3`
1594  * - `mBq/m3`
1595  * - `uBq/m3`
1596  *
1597  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1598  */
1599 FALAISE_ADD_DIMENSION_TAG(volume_activity)
1600 
1601 /*! \class falaise::config::wave_number_t
1602  * \ingroup falaise_units
1603  * \brief quantity for values with dimension tag `wave_number` ([L-1])
1604  *
1605  * A @ref wave_number_t value may be constructed using, for example
1606  *
1607  * ```cpp
1608  * falaise::config::wave_number_t x{3.14, "TAG"};
1609  * ```
1610  *
1611  * where `TAG` is one of the following valid unit tags:
1612  *
1613  * - `/m`
1614  *
1615  * A @ref wrong_dimension_error will be thrown if the supplied unit tag is not in the above list
1616  */
1617 FALAISE_ADD_DIMENSION_TAG(wave_number)
1618 
1619 #endif /* FALAISE_QUANTITY_H */
double value() const
Return the value for the quantity in its units.
Definition: quantity.h:133
Class representing a value and physical unit.
Definition: quantity.h:90
std::string const & unit() const
Return datatools::units tag for the quantity's unit.
Definition: quantity.h:149
std::string get_default_unit_symbol_from_label(const std::string &unit_label_)
#define FALAISE_ADD_DIMENSION_TAG(Tag)
Register a dimension tag for use as a falaise::config::quantity_t template parameter.
Definition: quantity.h:40
Definition: metadata_utils.h:35
double operator()() const
Convert quantity to double value in the CLHEP::Units numeric scaling system.
Definition: quantity.h:121
Exception reporting wrong or incompatible dimensions.
Definition: quantity.h:53
quantity_t(quantity const &q)
Copy constructor from a raw quantity.
Definition: quantity.h:219
Template class for a physical value with a strict dimension.
Definition: quantity.h:185
Exception reporting unknown unit tags.
Definition: quantity.h:58
virtual ~quantity_t()=default
Destructor.
double value_in(std::string const &unit) const
Return value for the quantity in given units.
quantity_t()
Default constructor.
Definition: quantity.h:193
std::string const & dimension() const
Return datatools::unit tag for the quantity's dimension.
Definition: quantity.h:152
quantity_t(double value, std::string const &unit)
Construct a quantity from a value and unit.
Definition: quantity.h:205
quantity()=default
Default constructor.
virtual ~quantity()=default
Destructor.