TypeSI
Units of 'Système international' Blended for C++
Loading...
Searching...
No Matches
si_prefix.hpp
Go to the documentation of this file.
1#pragma once
4#include "si_utilities.hpp"
5#include <ratio>
6#include <utility>
7namespace Si {
8namespace Internal {
12template <typename Ratio, typename Unit> class GenericPrefix {
13 using T = decltype(+std::declval<Unit>());
14 Unit _unit;
15
16public:
18 const Unit &raw() const { return _unit; }
20 explicit GenericPrefix(const T &value) : _unit(value) {}
22 template <typename AnotherUnit,
23 typename std::enable_if<std::is_same<Internal::Powers<AnotherUnit>,
25 int>::type = 0>
27 : _unit(Internal::implicit_cast<Unit>(unit.raw())) {}
30 template <
31 typename AnotherUnit,
32 typename std::enable_if<std::is_same<T, Unit>::value ||
33 std::is_same<Internal::Powers<AnotherUnit>,
35 int>::type = 0>
36#ifdef TYPE_SI_DISALLOW_IMPLICIT_PREFIX_CONVERSIONS
37 explicit
38#endif
39 GenericPrefix(const AnotherUnit &unit)
40 : _unit(Internal::implicit_cast<Unit>(unit) * static_cast<T>(Ratio::den) /
41 static_cast<T>(Ratio::num)) {
42 }
46 template <typename AnotherRatio, typename AnotherUnit,
47 typename std::enable_if<std::is_same<Internal::Powers<AnotherUnit>,
49 int>::type = 0>
50#ifdef TYPE_SI_DISALLOW_IMPLICIT_PREFIX_CONVERSIONS
51 explicit
52#endif
54 : _unit(Internal::implicit_cast<AnotherUnit>(unit.raw()) *
55 static_cast<T>(std::ratio_divide<AnotherRatio, Ratio>::num) /
56 static_cast<T>(std::ratio_divide<AnotherRatio, Ratio>::den)) {
57 }
59 T operator+() const { return +_unit; }
61 template <typename U>
62 decltype(std::declval<Unit>() == std::declval<Unit>())
63 operator==(const U &unit) const {
64 return _unit == Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
65 }
67 template <typename U>
68 decltype(std::declval<Unit>() != std::declval<Unit>())
69 operator!=(const U &unit) const {
70 return _unit != Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
71 }
73 template <typename U>
74 decltype(std::declval<Unit>() < std::declval<Unit>())
75 operator<(const U &unit) const {
76 return _unit < Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
77 }
79 template <typename U>
80 decltype(std::declval<Unit>() <= std::declval<Unit>())
81 operator<=(const U &unit) const {
82 return _unit <= Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
83 }
85 template <typename U>
86 decltype(std::declval<Unit>() > std::declval<Unit>())
87 operator>(const U &unit) const {
88 return _unit > Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
89 }
91 template <typename U>
92 decltype(std::declval<Unit>() >= std::declval<Unit>())
93 operator>=(const U &unit) const {
94 return _unit >= Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
95 }
97 template <typename U> GenericPrefix operator+(const U &unit) const {
99 +(_unit + Si::Internal::implicit_cast<GenericPrefix>(unit)._unit));
100 }
102 template <typename U> GenericPrefix operator+=(const U &unit) {
103 _unit += Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
104 return *this;
105 }
107 template <typename U> GenericPrefix operator-(const U &unit) const {
109 +(_unit - Si::Internal::implicit_cast<GenericPrefix>(unit)._unit));
110 }
112 template <typename U> GenericPrefix operator-=(const U &unit) {
113 _unit -= Si::Internal::implicit_cast<GenericPrefix>(unit)._unit;
114 return *this;
115 }
117 template <typename AnotherRatio, typename AnotherUnit>
119 decltype(std::declval<Unit>() * std::declval<AnotherUnit>())>
120 operator*(const GenericPrefix<AnotherRatio, AnotherUnit> &unit) const {
122 decltype(std::declval<Unit>() *
123 std::declval<AnotherUnit>())>(
124 +(_unit * unit.raw()));
125 }
127 template <typename AnotherUnit>
128 GenericPrefix<Ratio,
129 decltype(std::declval<Unit>() * std::declval<AnotherUnit>())>
130 operator*(const AnotherUnit &unit) const {
132 std::declval<AnotherUnit>())>(
133 +(_unit * unit));
134 }
136 GenericPrefix operator*=(const T &value) {
137 _unit *= value;
138 return *this;
139 }
141 template <typename AnotherRatio, typename AnotherUnit>
143 decltype(std::declval<Unit>() / std::declval<AnotherUnit>())>
144 operator/(const GenericPrefix<AnotherRatio, AnotherUnit> &unit) const {
146 decltype(std::declval<Unit>() /
147 std::declval<AnotherUnit>())>(
148 +(_unit / unit.raw()));
149 }
151 template <typename AnotherUnit>
152 GenericPrefix<Ratio,
153 decltype(std::declval<Unit>() * std::declval<AnotherUnit>())>
154 operator/(const AnotherUnit &unit) const {
156 std::declval<AnotherUnit>())>(
157 +(_unit / unit));
158 }
160 GenericPrefix operator/=(const T &value) {
161 _unit /= value;
162 return *this;
163 }
164};
165template <typename Ratio, typename Unit,
166 typename T = decltype(+std::declval<Unit>())>
167GenericPrefix<Ratio, Unit> applyPrefix();
168template <
169 typename Ratio, typename Unit,
170 typename T = decltype(+std::declval<typename Unit::template type<Ratio>>())>
171typename Unit::template type<Ratio> applyPrefix();
172} // namespace Internal
176template <typename Ratio, typename Unit>
177using Prefix = decltype(Internal::applyPrefix<Ratio, Unit>());
178} // namespace Si
Generic type of unit with prefix.
Definition: si_prefix.hpp:12
GenericPrefix operator-(const U &unit) const
Operator '-'.
Definition: si_prefix.hpp:107
GenericPrefix operator+=(const U &unit)
Operator '+='.
Definition: si_prefix.hpp:102
GenericPrefix(const GenericPrefix< AnotherRatio, AnotherUnit > &unit)
Explicit constructor from unit with different prefix(implicit by default, can be made explicit by TYP...
Definition: si_prefix.hpp:53
GenericPrefix operator*=(const T &value)
Operator '*=' for container type.
Definition: si_prefix.hpp:136
const Unit & raw() const
Getter for raw Unit reference without prefix applied.
Definition: si_prefix.hpp:18
GenericPrefix(const GenericPrefix< Ratio, AnotherUnit > &unit)
Implicit constructor from same units with different container type.
Definition: si_prefix.hpp:26
GenericPrefix operator+(const U &unit) const
Operator '+'.
Definition: si_prefix.hpp:97
GenericPrefix operator-=(const U &unit)
Operator '-='.
Definition: si_prefix.hpp:112
GenericPrefix operator/=(const T &value)
Operator '/=' for container type.
Definition: si_prefix.hpp:160
GenericPrefix(const T &value)
Explicit constructor from container type.
Definition: si_prefix.hpp:20
GenericPrefix(const AnotherUnit &unit)
Constructor from Unit type(implicit by default, can be made explicit by TYPE_SI_DISALLOW_IMPLICIT_PRE...
Definition: si_prefix.hpp:39
T operator+() const
Conversion to container type via unary '+'.
Definition: si_prefix.hpp:59
Generic unit type.
Definition: si_internal.hpp:22
decltype(getPowers(std::declval< U >())) Powers
Tool to get tuple of powers from unit.
Definition: si_internal.hpp:165
decltype(Internal::applyPrefix< Ratio, Unit >()) Prefix
Public interface to apply prefix to unit.
Definition: si_prefix.hpp:177
Internal instruments of the library, that does not involve core logic.