99#include < type_traits>
1010#include < utility>
1111
12-
1312// define M_PI if not already defined
1413#ifndef M_PI
1514 #define M_PI 3.14159265358979323846
@@ -56,6 +55,15 @@ class Quantity {
5655 Luminosity,
5756 Moles>;
5857
58+ using Dimensionless = Quantity<std::ratio<0 >,
59+ std::ratio<0 >,
60+ std::ratio<0 >,
61+ std::ratio<0 >,
62+ std::ratio<0 >,
63+ std::ratio<0 >,
64+ std::ratio<0 >,
65+ std::ratio<0 >>;
66+
5967 /* *
6068 * @brief construct a new Quantity object
6169 *
@@ -70,8 +78,19 @@ class Quantity {
7078 * @param value the value to initialize the quantity with
7179 */
7280 explicit constexpr Quantity (double value)
81+ requires(!std::is_same_v<Self, Dimensionless>)
7382 : value(value) {}
7483
84+ constexpr Quantity (double value)
85+ requires std::is_same_v<Self, Dimensionless>
86+ : value(value) {}
87+
88+ constexpr operator double ()
89+ requires std::is_same_v<Self, Dimensionless>
90+ {
91+ return value;
92+ }
93+
7594 /* *
7695 * @brief construct a new Quantity object
7796 *
@@ -104,6 +123,12 @@ class Quantity {
104123 value += other.value ;
105124 }
106125
126+ constexpr void operator +=(double other)
127+ requires std::is_same_v<Self, Dimensionless>
128+ {
129+ value += other;
130+ }
131+
107132 /* *
108133 * @brief set the value of this quantity to its current value minus another
109134 * quantity
@@ -114,6 +139,12 @@ class Quantity {
114139 value -= other.value ;
115140 }
116141
142+ constexpr void operator -=(double other)
143+ requires std::is_same_v<Self, Dimensionless>
144+ {
145+ value -= other;
146+ }
147+
117148 /* *
118149 * @brief set the value of this quantity to its current value times a double
119150 *
@@ -123,6 +154,12 @@ class Quantity {
123154 value *= multiple;
124155 }
125156
157+ constexpr void operator *=(double other)
158+ requires std::is_same_v<Self, Dimensionless>
159+ {
160+ value *= other;
161+ }
162+
126163 /* *
127164 * @brief set the value of this quantity to its current value divided by a
128165 * double
@@ -133,6 +170,12 @@ class Quantity {
133170 value /= dividend;
134171 }
135172
173+ constexpr void operator /=(double other)
174+ requires std::is_same_v<Self, Dimensionless>
175+ {
176+ value /= other;
177+ }
178+
136179 /* *
137180 * @brief set the value of this quantity to a double, only if the quantity
138181 * is a number
@@ -165,33 +208,15 @@ class Number : public Quantity<std::ratio<0>,
165208 std::ratio<0 >,
166209 std::ratio<0 >> {
167210 public:
168- template <typename T>
169- constexpr Number (T value)
211+ constexpr Number (double number)
170212 : Quantity<std::ratio<0>,
171213 std::ratio<0>,
172214 std::ratio<0>,
173215 std::ratio<0>,
174216 std::ratio<0>,
175217 std::ratio<0>,
176218 std::ratio<0>,
177- std::ratio<0>>(double (value)) {}
178-
179- constexpr Number (Quantity<std::ratio<0 >,
180- std::ratio<0 >,
181- std::ratio<0 >,
182- std::ratio<0 >,
183- std::ratio<0 >,
184- std::ratio<0 >,
185- std::ratio<0 >,
186- std::ratio<0 >> value)
187- : Quantity<std::ratio<0>,
188- std::ratio<0>,
189- std::ratio<0>,
190- std::ratio<0>,
191- std::ratio<0>,
192- std::ratio<0>,
193- std::ratio<0>,
194- std::ratio<0>>(value) {};
219+ std::ratio<0>>(number) {}
195220};
196221
197222template <typename Q>
@@ -591,124 +616,6 @@ struct LookupName<Quantity<std::ratio<0>,
591616 using Named = Number;
592617};
593618
594- [[maybe_unused]]
595- constexpr Number num = Number(1.0 );
596-
597- constexpr Number operator " " _num(long double value) {
598- return Number (Quantity<std::ratio<0 >,
599- std::ratio<0 >,
600- std::ratio<0 >,
601- std::ratio<0 >,
602- std::ratio<0 >,
603- std::ratio<0 >,
604- std::ratio<0 >,
605- std::ratio<0 >>(static_cast <double >(value)));
606- }
607-
608- constexpr Number operator " " _num(unsigned long long value) {
609- return Number (Quantity<std::ratio<0 >,
610- std::ratio<0 >,
611- std::ratio<0 >,
612- std::ratio<0 >,
613- std::ratio<0 >,
614- std::ratio<0 >,
615- std::ratio<0 >,
616- std::ratio<0 >>(static_cast <double >(value)));
617- }
618-
619- template <>
620- struct std ::formatter<Number> : std::formatter<double > {
621- auto format (const Number& number, std::format_context& ctx) const {
622- return std::formatter<double >::format (number.internal (), ctx);
623- }
624- };
625-
626- inline std::ostream& operator <<(std::ostream& os, const Number& quantity) {
627- os << quantity.internal () << " " << num;
628- return os;
629- }
630-
631- inline constexpr Number from_num (double value) {
632- return Number (value);
633- }
634-
635- inline constexpr double to_num (Number quantity) {
636- return quantity.internal ();
637- }
638-
639- #define NEW_NUM_TO_DOUBLE_COMPARISON (op ) \
640- constexpr bool operator op (Number lhs, double rhs) { \
641- return (lhs.internal () op rhs); \
642- } \
643- constexpr bool operator op (double lhs, Number rhs) { \
644- return (lhs op rhs.internal ()); \
645- }
646-
647- namespace units_double_ops {
648- NEW_NUM_TO_DOUBLE_COMPARISON (==)
649- NEW_NUM_TO_DOUBLE_COMPARISON (!=)
650- NEW_NUM_TO_DOUBLE_COMPARISON (<=)
651- NEW_NUM_TO_DOUBLE_COMPARISON (>=)
652- NEW_NUM_TO_DOUBLE_COMPARISON (<)
653- NEW_NUM_TO_DOUBLE_COMPARISON (>)
654- } // namespace units_double_ops
655-
656- #define NEW_NUM_AND_DOUBLE_OPERATION (op ) \
657- constexpr Number operator op (Number lhs, double rhs) { \
658- return (lhs.internal () op rhs); \
659- } \
660- constexpr Number operator op (double lhs, Number rhs) { \
661- return (lhs op rhs.internal ()); \
662- }
663-
664- namespace units_double_ops {
665- NEW_NUM_AND_DOUBLE_OPERATION (+)
666- NEW_NUM_AND_DOUBLE_OPERATION (-)
667- NEW_NUM_AND_DOUBLE_OPERATION (*)
668- NEW_NUM_AND_DOUBLE_OPERATION (/)
669- } // namespace units_double_ops
670-
671- #define NEW_NUM_AND_DOUBLE_ASSIGNMENT (op ) \
672- constexpr void operator op##=(Number& lhs, double rhs) { \
673- lhs = lhs.internal () op rhs; \
674- } \
675- constexpr void operator op##=(double & lhs, Number rhs) { \
676- lhs = lhs op rhs.internal (); \
677- }
678-
679- namespace units_double_ops {
680- NEW_NUM_AND_DOUBLE_ASSIGNMENT (+)
681- NEW_NUM_AND_DOUBLE_ASSIGNMENT (-)
682- NEW_NUM_AND_DOUBLE_ASSIGNMENT (*)
683- NEW_NUM_AND_DOUBLE_ASSIGNMENT (/)
684- } // namespace units_double_ops
685-
686- namespace units_double_ops {
687- constexpr Number& operator ++(Number& lhs, int ) {
688- lhs += 1 ;
689- return lhs;
690- }
691-
692- constexpr Number operator ++(Number& lhs) {
693- Number copy = lhs;
694- lhs += 1 ;
695- return copy;
696- }
697-
698- constexpr Number& operator --(Number& lhs, int ) {
699- lhs -= 1 ;
700- return lhs;
701- }
702-
703- constexpr Number operator --(Number& lhs) {
704- Number copy = lhs;
705- lhs -= 1 ;
706- return copy;
707- }
708- } // namespace units_double_ops
709-
710- NEW_UNIT_LITERAL (Number, percent, num / 100 )
711-
712619NEW_UNIT (Mass, kg, 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
713620NEW_UNIT_LITERAL(Mass, g, kg / 1000 )
714621NEW_UNIT_LITERAL(Mass, lb, g * 453.6 )
0 commit comments