units
Use physical dimensions at compile-time or run-time.
number.hpp
Go to the documentation of this file.
1 /// @file vnix/units/number.hpp
2 /// @brief Definition of vnix::units::number.
3 /// @copyright 2019 Thomas E. Vaughan; all rights reserved.
4 /// @license BSD Three-Clause; see LICENSE.
5 
6 #ifndef VNIX_UNITS_NUMBER_HPP
7 #define VNIX_UNITS_NUMBER_HPP
8 
9 #include <cstdlib>
10 
11 namespace Eigen {
12 
13 template <typename S, int R, int C, int OPT, int MR, int MC> class Matrix;
14 template <typename B, typename L, typename R> class CwiseBinaryOp;
15 template <typename L, typename R, int OPT> class Product;
16 
17 } // namespace Eigen
18 
19 
20 namespace vnix {
21 
22 namespace mv {
23 template <typename T, size_t NR, size_t NC> struct mat;
24 }
25 
26 namespace units {
27 
28 
29 /// Base-struct for wrapper to disambiguate scalar from dimval and protected
30 /// storage for numeric value associated with a physical unit.
31 ///
32 /// Specialize descendant as necessary to handle different scalar types; for
33 /// example, a matrix.
34 ///
35 /// The number is protected because it is here abstracted away from the unit,
36 /// which it needs in order to make any sense. The number is combined with the
37 /// unit in a descendant class.
38 ///
39 /// @tparam T Type of number, typically `float` or `double`.
40 template <typename T> struct basic_number {
41  T v_; ///< Numeric value that multiplies units.
42  using scalar = T; ///< Scalar type.
43  basic_number() {} ///< By default, do not initialize.
44 
45  /// Initialize numeric value and exponents of units.
46  /// @param v Numeric value that multiplies units.
47  constexpr basic_number(T const &vv) : v_(vv) {}
48 };
49 
50 
51 /// Generic template for wrapper to disambiguate scalar from dimval and
52 /// protected storage for numeric value associated with a physical unit.
53 ///
54 /// The generic template is not used. Specialize for each allowable scalar
55 /// type.
56 ///
57 /// @tparam T Type of scalar for dimval.
58 template <typename T> struct number {};
59 
60 
61 /// Specialization of scalar for int.
62 template <> struct number<int> : public basic_number<int> {
63  using basic_number<int>::basic_number; ///< Inherit constructor.
64  using test = int; ///< For SFINAE, type defined only in specialization.
65 };
66 
67 /// Specialization of scalar for float.
68 template <> struct number<float> : public basic_number<float> {
69  using basic_number<float>::basic_number; ///< Inherit constructor.
70  using test = int; ///< For SFINAE, type defined only in specialization.
71 };
72 
73 /// Specialization of scalar for double.
74 template <> struct number<double> : public basic_number<double> {
75  using basic_number<double>::basic_number; ///< Inherit constructor.
76  using test = int; ///< For SFINAE, type defined only in specialization.
77 };
78 
79 /// Specialization of scalar for long double.
80 template <> struct number<long double> : public basic_number<long double> {
81  using basic_number<long double>::basic_number; ///< Inherit constructor.
82  using test = int; ///< For SFINAE, type defined only in specialization.
83 };
84 
85 
86 /// Specialization of scalar for int.
87 template <> struct number<int &> : public basic_number<int &> {
88  using basic_number<int &>::basic_number; ///< Inherit constructor.
89  using test = int; ///< For SFINAE, type defined only in specialization.
90 };
91 
92 /// Specialization of scalar for float.
93 template <> struct number<float &> : public basic_number<float &> {
94  using basic_number<float &>::basic_number; ///< Inherit constructor.
95  using test = int; ///< For SFINAE, type defined only in specialization.
96 };
97 
98 /// Specialization of scalar for double.
99 template <> struct number<double &> : public basic_number<double &> {
100  using basic_number<double &>::basic_number; ///< Inherit constructor.
101  using test = int; ///< For SFINAE, type defined only in specialization.
102 };
103 
104 /// Specialization of scalar for long double.
105 template <> struct number<long double &> : public basic_number<long double &> {
106  using basic_number<long double &>::basic_number; ///< Inherit constructor.
107  using test = int; ///< For SFINAE, type defined only in specialization.
108 };
109 
110 
111 /// Specialization of scalar for int.
112 template <> struct number<int const &> : public basic_number<int const &> {
113  using basic_number<int const &>::basic_number; ///< Inherit constructor.
114  using test = int; ///< For SFINAE, type defined only in specialization.
115 };
116 
117 /// Specialization of scalar for float.
118 template <> struct number<float const &> : public basic_number<float const &> {
119  using basic_number<float const &>::basic_number; ///< Inherit constructor.
120  using test = int; ///< For SFINAE, type defined only in specialization.
121 };
122 
123 /// Specialization of scalar for double.
124 template <>
125 struct number<double const &> : public basic_number<double const &> {
126  using basic_number<double const &>::basic_number; ///< Inherit constructor.
127  using test = int; ///< For SFINAE, type defined only in specialization.
128 };
129 
130 /// Specialization of scalar for long double.
131 template <>
132 struct number<long double const &> : public basic_number<long double const &> {
133  /// Inherit constructor.
134  using basic_number<long double const &>::basic_number;
135  using test = int; ///< For SFINAE, type defined only in specialization.
136 };
137 
138 
139 /// Specialization of scalar for vnix::mv::mat.
140 template <typename T, size_t NR, size_t NC>
141 struct number<mv::mat<T, NR, NC>> : public basic_number<mv::mat<T, NR, NC>> {
142  /// Inherit constructor.
143  using basic_number<mv::mat<T, NR, NC>>::basic_number;
144 
145  using test = int; ///< For SFINAE, type defined only in specialization.
146 };
147 
148 /// Specialization of scalar for Eigen::Matrix.
149 template <typename S, int R, int C, int OPT, int MR, int MC>
150 struct number<Eigen::Matrix<S, R, C, OPT, MR, MC>>
151  : public basic_number<Eigen::Matrix<S, R, C, OPT, MR, MC>> {
152  /// Inherit constructor.
153  using basic_number<Eigen::Matrix<S, R, C, OPT, MR, MC>>::basic_number;
154 
155  using test = int; ///< For SFINAE, type defined only in specialization.
156 };
157 
158 /// Specialization of scalar for Eigen::CwiseBinaryOp.
159 template <typename B, typename L, typename R>
160 struct number<Eigen::CwiseBinaryOp<B, L, R>>
161  : public basic_number<Eigen::CwiseBinaryOp<B, L, R>> {
162  /// Inherit constructor.
163  using basic_number<Eigen::CwiseBinaryOp<B, L, R>>::basic_number;
164 
165  using test = int; ///< For SFINAE, type defined only in specialization.
166 };
167 
168 /// Specialization of scalar for Eigen::Product.
169 template <typename L, typename R, int OPT>
170 struct number<Eigen::Product<L, R, OPT>>
171  : public basic_number<Eigen::Product<L, R, OPT>> {
172  /// Inherit constructor.
173  using basic_number<Eigen::Product<L, R, OPT>>::basic_number;
174 
175  using test = int; ///< For SFINAE, type defined only in specialization.
176 };
177 
178 
179 } // namespace units
180 } // namespace vnix
181 
182 #endif // ndef VNIX_UNITS_NUMBER_HPP
Definition: number.hpp:11
Base-struct for wrapper to disambiguate scalar from dimval and protected storage for numeric value as...
Definition: number.hpp:40
constexpr basic_number(T const &vv)
Initialize numeric value and exponents of units.
Definition: number.hpp:47
T v_
Numeric value that multiplies units.
Definition: number.hpp:41
Thomas E. Vaughan&#39;s public software.
Definition: rational.hpp:13
Classes and functions supporting a model of physically dimensioned quantities.
Generic template for wrapper to disambiguate scalar from dimval and protected storage for numeric val...
Definition: number.hpp:58
basic_number()
By default, do not initialize.
Definition: number.hpp:43