Line data Source code
1 : /** @file bpu.hpp
2 : *
3 : * Author: Roland Conybeare
4 : **/
5 :
6 : #pragma once
7 :
8 : #include "xo/indentlog/print/tag.hpp"
9 : #include "basis_unit.hpp"
10 : #include "dim_iostream.hpp"
11 :
12 : namespace xo {
13 : namespace qty {
14 : using bpu_abbrev_type = flatstring<24>;
15 :
16 : using power_ratio_type = xo::ratio::ratio<std::int64_t>;
17 :
18 : namespace abbrev {
19 : using power_abbrev_type = flatstring<16>;
20 :
21 : constexpr power_abbrev_type
22 26 : flatstring_from_exponent(std::int64_t num,
23 : std::int64_t den)
24 : {
25 26 : if (den == 1) {
26 26 : if (num == 1) {
27 16 : return power_abbrev_type::from_chars("");
28 : } else {
29 10 : return (power_abbrev_type::from_flatstring
30 10 : (flatstring_concat(flatstring("^"),
31 20 : power_abbrev_type::from_int(num))));
32 : }
33 : } else {
34 0 : return (power_abbrev_type::from_flatstring
35 0 : (flatstring_concat(flatstring("^"),
36 0 : xo::ratio::make_ratio(num, den)
37 0 : .to_str<power_abbrev_type::fixed_capacity>())));
38 : }
39 10 : }
40 :
41 : static constexpr bpu_abbrev_type
42 26 : bpu_abbrev(dim native_dim,
43 : const scalefactor_ratio_type & scalefactor,
44 : const power_ratio_type & power)
45 : {
46 26 : return (bpu_abbrev_type::from_flatstring
47 26 : (flatstring_concat
48 26 : (basis_unit2_abbrev(native_dim, scalefactor),
49 26 : flatstring_from_exponent(power.num(), power.den()))));
50 : }
51 : }
52 :
53 : /** @class native_bpu2
54 : *
55 : * @brief represent product of a compile-time scale-factor with a rational power of a native unit
56 : *
57 : * Example:
58 : * native_bpu<universal::time, ratio<1>, ratio<-1,2>> represents unit of 1/sqrt(t)
59 : **/
60 : template<typename Int>
61 : struct bpu : basis_unit {
62 : public:
63 : using ratio_int_type = Int;
64 :
65 : public:
66 : constexpr bpu() = default;
67 : constexpr bpu(const basis_unit & bu,
68 : const power_ratio_type & power)
69 : : basis_unit{bu},
70 : power_{power}
71 : {}
72 53 : constexpr bpu(dim native_dim,
73 : const scalefactor_ratio_type & scalefactor,
74 : const power_ratio_type & power)
75 : : basis_unit(native_dim, scalefactor),
76 26 : power_{power}
77 : {}
78 :
79 : static constexpr bpu<Int> unit_power(const basis_unit & bu) {
80 : return bpu<Int>(bu, power_ratio_type(1,1));
81 : }
82 :
83 121 : constexpr const power_ratio_type & power() const { return power_; }
84 :
85 : /** @brief abbreviation for this dimension
86 : *
87 : * @code
88 : * bpu2<int64_t>(dim::time,
89 : * scalefactor_ratio_type(60,1),
90 : * power_ratio_type(-2,1)).abbrev() => "min^-2"
91 : * @endcode
92 : **/
93 22 : constexpr bpu_abbrev_type abbrev() const
94 : {
95 22 : return abbrev::bpu_abbrev(native_dim_,
96 22 : scalefactor_,
97 22 : power_);
98 : }
99 :
100 : /* for bpu x, x.reciprocal() represents dimension of 1/x */
101 1 : constexpr bpu<Int> reciprocal() const {
102 1 : return bpu<Int>(native_dim(), scalefactor(), power_.negate());
103 : }
104 :
105 : template <typename Int2>
106 4 : constexpr bpu<Int2> to_repr() const {
107 : return bpu<Int2>(this->native_dim(),
108 : this->scalefactor(),
109 4 : ratio::ratio<Int2>(power_.num(), power_.den()));
110 : }
111 :
112 : /** @brief this unit represents native dimension taken to this power **/
113 : power_ratio_type power_;
114 : };
115 :
116 : template <typename Int>
117 : constexpr auto make_unit_power(const basis_unit & bu) {
118 : return bpu<Int>::unit_power(bu);
119 : }
120 :
121 : } /*namespace qty*/
122 : } /*namespace xo*/
123 :
124 : /** end bpu.hpp **/
|