Skip to content

Commit 46ad6ed

Browse files
committed
splitting into separate header files, inclusion pragmas (duh)
1 parent b2f0a58 commit 46ad6ed

File tree

6 files changed

+457
-459
lines changed

6 files changed

+457
-459
lines changed

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11

22
set( unitguard_headers
33
ConstexprAlgorithms.hpp
4+
Unit.hpp
45
UnitGuard.hpp
6+
Quantity.hpp
57
)
68

79
set( unitguard_sources

src/ConstexprAlgorithms.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#pragma once
12

23
namespace UnitGuard
34
{

src/Quantity.hpp

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
#pragma once
2+
3+
#include "Unit.hpp"
4+
5+
namespace UnitGuard
6+
{
7+
8+
#if ! defined( DISABLE_UNITGUARD )
9+
template < typename T, typename U >
10+
class Quantity
11+
{
12+
public:
13+
T value;
14+
explicit Quantity( T v ) : value(v) {}
15+
16+
// Convert to raw number
17+
operator T() const { return value; }
18+
19+
// For printing
20+
operator std::string() const
21+
{
22+
return std::to_string(value);
23+
}
24+
25+
template < typename _U >
26+
Quantity< T, U > & operator=( const Quantity< T, _U > & other )
27+
{
28+
static_assert( are_same_units< U, _U >::value, "Cannot assign incompatible units" );
29+
value = other.value;
30+
return *this;
31+
}
32+
33+
template < typename _U >
34+
Quantity< T, U > & operator+=( const Quantity< T, _U > & other )
35+
{
36+
static_assert( are_same_units< U, _U >::value, "Cannot add different units" );
37+
value += other.value;
38+
return *this;
39+
}
40+
41+
template < typename _U >
42+
Quantity< T, U > & operator-=( const Quantity< T, _U > & other )
43+
{
44+
static_assert( are_same_units< U, U >::value, "Cannot subtract different units" );
45+
value -= other.value;
46+
return *this;
47+
}
48+
49+
Quantity< T, U > operator+( const Quantity & other ) const
50+
{
51+
return Quantity< T, U >( value + other.value );
52+
}
53+
54+
Quantity< T, U > operator-( const Quantity & other ) const
55+
{
56+
return Quantity< T, U >( value - other.value );
57+
}
58+
59+
// Multiply: results in new Unit with exponents added
60+
template< typename OU >
61+
auto operator*( const Quantity< T, OU > & other ) const
62+
{
63+
using ResultUnit = typename Multiply< U, OU >::type;
64+
return Quantity< T, ResultUnit >( value * other.value );
65+
}
66+
67+
// Divide: results in new Unit with exponents subtracted
68+
template< typename OU >
69+
auto operator/( const Quantity< T, OU > & other ) const
70+
{
71+
using ResultUnit = typename Divide< U, OU >::type;
72+
return Quantity< T, ResultUnit >( value / other.value );
73+
}
74+
};
75+
#else
76+
template < typename T, typename >
77+
using Quantity = T;
78+
#endif
79+
80+
// --------------------------------------------
81+
// Fundamental tags for all atomic dimensions:
82+
struct MassTag : public AtomTag {};
83+
struct LengthTag : public AtomTag {};
84+
struct TimeTag : public AtomTag {};
85+
struct CurrentTag : public AtomTag {}; // e.g. electrice current
86+
struct TemperatureTag : public AtomTag {};
87+
struct AmmountTag : public AtomTag {}; // e.g. moles
88+
struct LuminanceTag : public AtomTag {}; // e.g. candelas
89+
90+
91+
// Establish canonical ordering
92+
template < >
93+
struct CanonicalOrder< MassTag >
94+
{
95+
static constexpr int value = 0;
96+
};
97+
98+
template < >
99+
struct CanonicalOrder< LengthTag >
100+
{
101+
static constexpr int value = 1;
102+
};
103+
104+
template < >
105+
struct CanonicalOrder< TimeTag >
106+
{
107+
static constexpr int value = 2;
108+
};
109+
110+
template < >
111+
struct CanonicalOrder< CurrentTag >
112+
{
113+
static constexpr int value = 3;
114+
};
115+
116+
117+
template < >
118+
struct CanonicalOrder< TemperatureTag >
119+
{
120+
static constexpr int value = 4;
121+
};
122+
123+
template < >
124+
struct CanonicalOrder< AmmountTag >
125+
{
126+
static constexpr int value = 5;
127+
};
128+
129+
template < >
130+
struct CanonicalOrder< LuminanceTag >
131+
{
132+
static constexpr int value = 6;
133+
};
134+
135+
// --------------------------------------------
136+
// Dimensionless (no base units at all):
137+
using Dimensionless = Unit<>;
138+
139+
// --------------------------------------------
140+
// Single-base (fundamental) units:
141+
using MassDimension = Unit<Power<MassTag, 1>>;
142+
using LengthDimension = Unit<Power<LengthTag, 1>>;
143+
using TimeDimension = Unit<Power<TimeTag, 1>>;
144+
using CurrentDimension = Unit<Power<CurrentTag, 1>>;
145+
using TemperatureDimension = Unit<Power<TemperatureTag, 1>>;
146+
using AmmountDimension = Unit<Power<AmmountTag, 1>>;
147+
using LuminanceDimension = Unit<Power<LuminanceTag, 1>>;
148+
149+
// --------------------------------------------
150+
// Derived units:
151+
152+
// Frequency = Time^-1
153+
using FrequencyDimension = Unit< Power< TimeTag, -1 > >;
154+
155+
// Area = Length^2
156+
using AreaDimension = Unit< Power< LengthTag, 2 > >;
157+
158+
// Volume = Length^3
159+
using VolumeDimension = Unit< Power< LengthTag, 3 > >;
160+
161+
// Velocity = Length^1 * Time^-1
162+
using VelocityDimension = Unit<
163+
Power< LengthTag, 1 >,
164+
Power< TimeTag, -1 >
165+
>;
166+
167+
// Acceleration = Length^1 * Time^-2
168+
using AccelerationDimension = Unit<
169+
Power< LengthTag, 1 >,
170+
Power< TimeTag, -2 >
171+
>;
172+
173+
// Momentum = Mass^1 * Length^1 * Time^-1
174+
using MomentumDimension = Unit<
175+
Power< MassTag, 1 >,
176+
Power< LengthTag, 1 >,
177+
Power< TimeTag, -1 >
178+
>;
179+
180+
// Force = Mass^1 * Length^1 * Time^-2
181+
using ForceDimension = Unit<
182+
Power< MassTag, 1 >,
183+
Power< LengthTag, 1 >,
184+
Power< TimeTag, -2 >
185+
>;
186+
187+
// Pressure = Force / Area = Mass^1 * Length^-1 * Time^-2
188+
using PressureDimension = Unit<
189+
Power< MassTag, 1 >,
190+
Power< LengthTag, -1 >,
191+
Power< TimeTag, -2 >
192+
>;
193+
194+
// Energy = Force * Distance = Mass^1 * Length^2 * Time^-2
195+
using EnergyDimension = Unit<
196+
Power< MassTag, 1 >,
197+
Power< LengthTag, 2 >,
198+
Power< TimeTag, -2 >
199+
>;
200+
201+
// Power = Energy / Time = Mass^1 * Length^2 * Time^-3
202+
using PowerDimension = Unit<
203+
Power< MassTag, 1 >,
204+
Power< LengthTag, 2 >,
205+
Power< TimeTag, -3 >
206+
>;
207+
208+
// --------------------------------------------
209+
// thermodynamic-derived
210+
211+
// Entropy = Energy / Temperature = Mass^1 * Length^2 * Time^-2 * Temperature^-1
212+
using EntropyDimension = Unit<
213+
Power< MassTag, 1 >,
214+
Power< LengthTag, 2 >,
215+
Power< TimeTag, -2 >,
216+
Power< TemperatureTag, -1 >
217+
>;
218+
219+
// HeatCapacity = Energy / Temperature (identical to Entropy dimensionally)
220+
using HeatCapacityDimension = EntropyDimension;
221+
222+
// ----------------------------------------------------------------------------
223+
224+
template < typename T > using Length = Quantity< T, LengthDimension >;
225+
template < typename T > using Mass = Quantity< T, MassDimension >;
226+
template < typename T > using Time = Quantity< T, TimeDimension >;
227+
template < typename T > using Temp = Quantity< T, TemperatureDimension >;
228+
229+
// Derived:
230+
template < typename T > using Frequency = Quantity< T, FrequencyDimension >;
231+
template < typename T > using Area = Quantity< T, AreaDimension >;
232+
template < typename T > using Volume = Quantity< T, VolumeDimension >;
233+
template < typename T > using Velocity = Quantity< T, VelocityDimension >;
234+
template < typename T > using Force = Quantity< T, ForceDimension >;
235+
template < typename T > using Pressure = Quantity< T, PressureDimension >;
236+
template < typename T > using Energy = Quantity< T, EnergyDimension >;
237+
template < typename T > using Entropy = Quantity< T, EntropyDimension >;
238+
239+
// Optionally also define dimensionless (which is sometimes handy):
240+
template < typename T > using Scalar = Quantity< T, Dimensionless >;
241+
242+
}

0 commit comments

Comments
 (0)