Deduced units symbols refactoring started

This commit is contained in:
Mateusz Pusz
2019-11-04 06:45:56 +00:00
parent 7e844ef773
commit 91bcfedf1e
31 changed files with 329 additions and 128 deletions
+82 -19
View File
@@ -22,7 +22,8 @@
#pragma once
#include <units/unit.h>
#include <units/dimension.h>
#include <units/prefix.h>
#include <ostream>
#include <string_view>
@@ -61,30 +62,92 @@ namespace units {
}
}
template<typename CharT, typename Traits, typename... Es>
void print_dimensions(std::basic_ostream<CharT, Traits>& os, dimension<Es...>)
template<int Value>
requires (0 <= Value) && (Value < 10)
inline constexpr basic_fixed_string superscript_number = "\u2070";
// template<> inline constexpr basic_fixed_string superscript_number<0> = "\u2070";
template<> inline constexpr basic_fixed_string superscript_number<1> = "\u00b9";
template<> inline constexpr basic_fixed_string superscript_number<2> = "\u00b2";
template<> inline constexpr basic_fixed_string superscript_number<3> = "\u00b3";
template<> inline constexpr basic_fixed_string superscript_number<4> = "\u2074";
template<> inline constexpr basic_fixed_string superscript_number<5> = "\u2075";
template<> inline constexpr basic_fixed_string superscript_number<6> = "\u2076";
template<> inline constexpr basic_fixed_string superscript_number<7> = "\u2077";
template<> inline constexpr basic_fixed_string superscript_number<8> = "\u2078";
template<> inline constexpr basic_fixed_string superscript_number<9> = "\u2079";
template<int Value>
requires (Value >= 0)
constexpr auto superscript()
{
bool first = true;
auto ingr_printer = [&]<typename E>(E) {
if constexpr(E::num < 0) {
os << (first ? "1/" : "/");
if constexpr(Value < 10)
return superscript_number<Value>;
else
return superscript<Value / 10>() + superscript<Value % 10>();
}
template<int Value>
requires (Value >= 0)
constexpr auto regular()
{
if constexpr(Value < 10)
return basic_fixed_string(static_cast<char>('0' + Value));
else
return regular<Value / 10>() + regular<Value % 10>();
}
template<bool Divide, std::size_t Idx>
constexpr auto operator_txt()
{
if constexpr(Idx == 0) {
if constexpr(Divide) {
return basic_fixed_string("1/");
}
else {
os << (first ? "" : "⋅");
return basic_fixed_string("");
}
os << E::dimension::symbol;
if constexpr(E::den != 1) {
os << "^(" << abs(E::num) << "/" << E::den << ")";
}
else {
if constexpr(Divide) {
return basic_fixed_string("/");
}
else if constexpr(abs(E::num) != 1) {
// if constexpr(is_unicode<CharT>)
// os << superscript<abs(E::num)>;
// else
os << "^" << abs(E::num);
else {
return basic_fixed_string("⋅");
}
first = false;
};
(ingr_printer(Es{}), ...);
}
}
template<typename E, std::size_t Idx>
constexpr auto exp_txt()
{
// get calculation operator + symbol
const auto txt = operator_txt<E::num < 0, Idx>() + E::dimension::symbol;
if constexpr(E::den != 1) {
// add root part
return txt + basic_fixed_string("^(") + regular<abs(E::num)>() + basic_fixed_string("/") + regular<E::den>() + basic_fixed_string(")");
}
else if constexpr(abs(E::num) != 1) {
// add exponent part
return txt + superscript<abs(E::num)>();
}
else {
return txt;
}
}
template<typename... Es, std::size_t... Idxs>
constexpr auto symbol_text_impl(dimension<Es...>, std::index_sequence<Idxs...>)
{
return (exp_txt<Es, Idxs>() + ...);
}
template<typename... Es>
constexpr auto symbol_text(dimension<Es...> d)
{
return symbol_text_impl<>(d, std::index_sequence_for<Es...>());
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ namespace units {
template<typename T>
concept Acceleration = QuantityOf<T, acceleration>;
struct metre_per_second_sq : coherent_derived_unit<metre_per_second_sq, "m/s^2", acceleration> {};
struct metre_per_second_sq : coherent_derived_unit<metre_per_second_sq, acceleration> {};
inline namespace literals {
+5 -5
View File
@@ -31,11 +31,11 @@ namespace units {
template<typename T>
concept Area = QuantityOf<T, area>;
struct square_metre : coherent_derived_unit<square_metre, "m^2", area> {};
struct square_millimetre : deduced_derived_unit<square_millimetre, "mm^2", area, millimetre> {};
struct square_centimetre : deduced_derived_unit<square_centimetre, "cm^2", area, centimetre> {};
struct square_kilometre : deduced_derived_unit<square_kilometre, "km^2", area, kilometre> {};
struct square_foot : deduced_derived_unit<square_foot, "ft^2", area, foot> {};
struct square_metre : coherent_derived_unit<square_metre, area> {};
struct square_millimetre : deduced_derived_unit<square_millimetre, area, millimetre> {};
struct square_centimetre : deduced_derived_unit<square_centimetre, area, centimetre> {};
struct square_kilometre : deduced_derived_unit<square_kilometre, area, kilometre> {};
struct square_foot : deduced_derived_unit<square_foot, area, foot> {};
inline namespace literals {
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept Capacitance = QuantityOf<T, capacitance>;
struct farad : coherent_derived_unit<farad, "F", capacitance, si_prefix> {};
struct farad : named_coherent_derived_unit<farad, "F", capacitance, si_prefix> {};
inline namespace literals {
+1 -1
View File
@@ -32,7 +32,7 @@ namespace units {
template<typename T>
concept Current = QuantityOf<T, current>;
struct ampere : coherent_derived_unit<ampere, "A", current, si_prefix> {};
struct ampere : named_coherent_derived_unit<ampere, "A", current, si_prefix> {};
inline namespace literals {
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept ElectricCharge = QuantityOf<T, electric_charge>;
struct coulomb : coherent_derived_unit<coulomb, "C", electric_charge, si_prefix> {};
struct coulomb : named_coherent_derived_unit<coulomb, "C", electric_charge, si_prefix> {};
inline namespace literals {
+1 -1
View File
@@ -34,7 +34,7 @@ namespace units {
template<typename T>
concept Energy = QuantityOf<T, energy>;
struct joule : coherent_derived_unit<joule, "J", energy, si_prefix> {};
struct joule : named_coherent_derived_unit<joule, "J", energy, si_prefix> {};
struct millijoule : prefixed_derived_unit<millijoule, milli, joule> {};
struct kilojoule : prefixed_derived_unit<kilojoule, kilo, joule> {};
struct megajoule : prefixed_derived_unit<megajoule, mega, joule> {};
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept Force = QuantityOf<T, force>;
struct newton : coherent_derived_unit<newton, "N", force, si_prefix> {};
struct newton : named_coherent_derived_unit<newton, "N", force, si_prefix> {};
inline namespace literals {
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept Frequency = QuantityOf<T, frequency>;
struct hertz : coherent_derived_unit<hertz, "Hz", frequency, si_prefix> {};
struct hertz : named_coherent_derived_unit<hertz, "Hz", frequency, si_prefix> {};
struct millihertz : prefixed_derived_unit<millihertz, milli, hertz> {};
struct kilohertz : prefixed_derived_unit<kilohertz, kilo, hertz> {};
struct megahertz : prefixed_derived_unit<megahertz, mega, hertz> {};
+5 -5
View File
@@ -34,7 +34,7 @@ namespace units {
concept Length = QuantityOf<T, length>;
// SI units
struct metre : coherent_derived_unit<metre, "m", length, si_prefix> {};
struct metre : named_coherent_derived_unit<metre, "m", length, si_prefix> {};
struct millimetre : prefixed_derived_unit<millimetre, milli, metre> {};
struct centimetre : prefixed_derived_unit<centimetre, centi, metre> {};
struct kilometre : prefixed_derived_unit<kilometre, kilo, metre> {};
@@ -60,10 +60,10 @@ namespace units {
} // namespace literals
// US customary units
struct yard : derived_unit<yard, "yd", length, ratio<9'144, 10'000>> {};
struct foot : derived_unit<foot, "ft", length, ratio_multiply<ratio<1, 3>, yard::ratio>> {};
struct inch : derived_unit<inch, "in", length, ratio_multiply<ratio<1, 12>, foot::ratio>> {};
struct mile : derived_unit<mile, "mi", length, ratio_multiply<ratio<1'760>, yard::ratio>> {};
struct yard : named_derived_unit<yard, "yd", length, ratio<9'144, 10'000>> {};
struct foot : named_derived_unit<foot, "ft", length, ratio_multiply<ratio<1, 3>, yard::ratio>> {};
struct inch : named_derived_unit<inch, "in", length, ratio_multiply<ratio<1, 12>, foot::ratio>> {};
struct mile : named_derived_unit<mile, "mi", length, ratio_multiply<ratio<1'760>, yard::ratio>> {};
inline namespace literals {
@@ -32,7 +32,7 @@ namespace units {
template<typename T>
concept LuminousIntensity = QuantityOf<T, luminous_intensity>;
struct candela : coherent_derived_unit<candela, "cd", luminous_intensity, si_prefix> {};
struct candela : named_coherent_derived_unit<candela, "cd", luminous_intensity, si_prefix> {};
inline namespace literals {
+2 -2
View File
@@ -32,8 +32,8 @@ namespace units {
template<typename T>
concept Mass = QuantityOf<T, mass>;
struct kilogram : coherent_derived_unit<kilogram, "kg", mass> {};
struct gram : derived_unit<gram, "g", mass, ratio<1, 1000>> {};
struct gram : named_derived_unit<gram, "g", mass, ratio<1, 1000>> {};
struct kilogram : prefixed_derived_unit<kilogram, kilo, gram> {};
inline namespace literals {
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept Power = QuantityOf<T, power>;
struct watt : coherent_derived_unit<watt, "W", power, si_prefix> {};
struct watt : named_coherent_derived_unit<watt, "W", power, si_prefix> {};
struct milliwatt : prefixed_derived_unit<milliwatt, milli, watt> {};
struct kilowatt : prefixed_derived_unit<kilowatt, kilo, watt> {};
struct megawatt : prefixed_derived_unit<megawatt, mega, watt> {};
+1 -1
View File
@@ -33,7 +33,7 @@ namespace units {
template<typename T>
concept Pressure = QuantityOf<T, pressure>;
struct pascal : coherent_derived_unit<pascal, "Pa", pressure, si_prefix> {};
struct pascal : named_coherent_derived_unit<pascal, "Pa", pressure, si_prefix> {};
inline namespace literals {
+1 -1
View File
@@ -36,7 +36,7 @@ namespace units {
struct femto : prefix<femto, si_prefix, ratio<1, std::femto::den>, "f"> {};
struct pico : prefix<pico, si_prefix, ratio<1, std::pico::den>, "p"> {};
struct nano : prefix<nano, si_prefix, ratio<1, std::nano::den>, "n"> {};
struct micro : prefix<micro, si_prefix, ratio<1, std::micro::den>, "µ"> {};
struct micro : prefix<micro, si_prefix, ratio<1, std::micro::den>, "\u00b5"> {};
struct milli : prefix<milli, si_prefix, ratio<1, std::milli::den>, "m"> {};
struct centi : prefix<centi, si_prefix, ratio<1, std::centi::den>, "c"> {};
struct deci : prefix<deci, si_prefix, ratio<1, std::deci::den>, "d"> {};
+1 -1
View File
@@ -32,7 +32,7 @@ namespace units {
template<typename T>
concept Substance = QuantityOf<T, substance>;
struct mole : coherent_derived_unit<mole, "mol", substance, si_prefix> {};
struct mole : named_coherent_derived_unit<mole, "mol", substance, si_prefix> {};
inline namespace literals {
+1 -1
View File
@@ -32,7 +32,7 @@ namespace units {
template<typename T>
concept ThermodynamicTemperature = QuantityOf<T, temperature>;
struct kelvin : coherent_derived_unit<kelvin, "K", temperature> {};
struct kelvin : named_coherent_derived_unit<kelvin, "K", temperature> {};
inline namespace literals {
+3 -3
View File
@@ -33,12 +33,12 @@ namespace units {
template<typename T>
concept Time = QuantityOf<T, time>;
struct second : coherent_derived_unit<second, "s", time, si_prefix> {};
struct second : named_coherent_derived_unit<second, "s", time, si_prefix> {};
struct nanosecond : prefixed_derived_unit<nanosecond, nano, second> {};
struct microsecond : prefixed_derived_unit<microsecond, micro, second> {};
struct millisecond : prefixed_derived_unit<millisecond, milli, second> {};
struct minute : derived_unit<minute, "min", time, ratio<60>> {};
struct hour : derived_unit<hour, "h", time, ratio<3600>> {};
struct minute : named_derived_unit<minute, "min", time, ratio<60>> {};
struct hour : named_derived_unit<hour, "h", time, ratio<3600>> {};
inline namespace literals {
+3 -3
View File
@@ -32,9 +32,9 @@ namespace units {
template<typename T>
concept Velocity = QuantityOf<T, velocity>;
struct metre_per_second : coherent_derived_unit<metre_per_second, "m/s", velocity> {};
struct kilometre_per_hour : deduced_derived_unit<kilometre_per_hour, "km/h", velocity, kilometre, hour> {};
struct mile_per_hour : deduced_derived_unit<mile_per_hour, "mi/h", velocity, mile, hour> {};
struct metre_per_second : coherent_derived_unit<metre_per_second, velocity> {};
struct kilometre_per_hour : deduced_derived_unit<kilometre_per_hour, velocity, kilometre, hour> {};
struct mile_per_hour : deduced_derived_unit<mile_per_hour, velocity, mile, hour> {};
inline namespace literals {
+1 -1
View File
@@ -35,7 +35,7 @@ namespace units {
template<typename T>
concept Voltage = QuantityOf<T, voltage>;
struct volt : coherent_derived_unit<volt, "V", voltage, si_prefix> {};
struct volt : named_coherent_derived_unit<volt, "V", voltage, si_prefix> {};
inline namespace literals {
+5 -5
View File
@@ -31,11 +31,11 @@ namespace units {
template<typename T>
concept Volume = QuantityOf<T, volume>;
struct cubic_metre : coherent_derived_unit<cubic_metre, "m^3", volume> {};
struct cubic_millimetre : deduced_derived_unit<cubic_millimetre, "mm^3", volume, millimetre> {};
struct cubic_centimetre : deduced_derived_unit<cubic_centimetre, "cm^3", volume, centimetre> {};
struct cubic_kilometre : deduced_derived_unit<cubic_kilometre, "km^3", volume, kilometre, metre> {};
struct cubic_foot : deduced_derived_unit<cubic_foot, "ft^3", volume, foot> {};
struct cubic_metre : coherent_derived_unit<cubic_metre, volume> {};
struct cubic_millimetre : deduced_derived_unit<cubic_millimetre, volume, millimetre> {};
struct cubic_centimetre : deduced_derived_unit<cubic_centimetre, volume, centimetre> {};
struct cubic_kilometre : deduced_derived_unit<cubic_kilometre, volume, kilometre, metre> {};
struct cubic_foot : deduced_derived_unit<cubic_foot, volume, foot> {};
inline namespace literals {
+1
View File
@@ -25,6 +25,7 @@
#include <units/quantity.h>
#include <fmt/format.h>
template<typename U, typename Rep, typename CharT>
struct fmt::formatter<units::quantity<U, Rep>, CharT> {
template<typename ParseContext>
+65
View File
@@ -0,0 +1,65 @@
// The MIT License (MIT)
//
// Copyright (c) 2018 Mateusz Pusz
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include <units/bits/downcasting.h>
#include <units/bits/fixed_string.h>
#include <units/ratio.h>
namespace units {
namespace detail {
template<typename PrefixType, Ratio R>
struct prefix_base : downcast_base<prefix_base<PrefixType, R>> {
using prefix_type = PrefixType;
using ratio = R;
};
}
template<typename Child, typename PrefixType, Ratio R, basic_fixed_string Symbol>
struct prefix : downcast_child<Child, detail::prefix_base<PrefixType, R>> {
static constexpr auto symbol = Symbol;
};
// TODO gcc:92150
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92150
// namespace detail {
// template<typename T>
// inline constexpr bool is_prefix = false;
// template<typename PrefixType, Ratio R, basic_fixed_string Symbol>
// inline constexpr bool is_prefix<prefix<PrefixType, R, Symbol>> = true;
// } // namespace detail
template<typename T>
// concept Prefix = detail::is_prefix<T>;
concept Prefix = true;
struct no_prefix;
} // namespace units
+1 -1
View File
@@ -302,7 +302,7 @@ namespace units {
detail::print_ratio<ratio>(os);
// print coherent unit dimensions and their exponents
detail::print_dimensions(os, dim{});
os << detail::symbol_text(dim{});
}
}
return os;
+21 -35
View File
@@ -22,7 +22,9 @@
#pragma once
#include <units/bits/format_utils.h>
#include <units/dimension.h>
#include <units/prefix.h>
#include <units/ratio.h>
#include <ratio>
@@ -52,38 +54,6 @@ namespace units {
std::is_empty_v<T> &&
detail::is_unit<downcast_base_t<T>>;
namespace detail {
template<typename PrefixType, Ratio R>
struct prefix_base : downcast_base<prefix_base<PrefixType, R>> {
using prefix_type = PrefixType;
using ratio = R;
};
}
template<typename Child, typename PrefixType, Ratio R, basic_fixed_string Symbol>
struct prefix : downcast_child<Child, detail::prefix_base<PrefixType, R>> {
static constexpr auto symbol = Symbol;
};
// TODO gcc:92150
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92150
// namespace detail {
// template<typename T>
// inline constexpr bool is_prefix = false;
// template<typename PrefixType, Ratio R, basic_fixed_string Symbol>
// inline constexpr bool is_prefix<prefix<PrefixType, R, Symbol>> = true;
// } // namespace detail
template<typename T>
// concept Prefix = detail::is_prefix<T>;
concept Prefix = true;
// make_derived_unit
namespace detail {
@@ -150,16 +120,27 @@ namespace units {
struct no_prefix;
template<typename Child, basic_fixed_string Symbol, Dimension D, typename PrefixType = no_prefix>
struct coherent_derived_unit : downcast_child<Child, unit<D, ratio<1>>> {
struct named_coherent_derived_unit : downcast_child<Child, unit<D, ratio<1>>> {
static constexpr auto symbol = Symbol;
using prefix_type = PrefixType;
};
template<typename Child, Dimension D, typename PrefixType = no_prefix>
struct coherent_derived_unit : downcast_child<Child, unit<D, ratio<1>>> {
static constexpr auto symbol = detail::symbol_text(D());
using prefix_type = PrefixType;
};
template<typename Child, basic_fixed_string Symbol, Dimension D, Ratio R>
struct derived_unit : downcast_child<Child, unit<D, R>> {
struct named_derived_unit : downcast_child<Child, unit<D, R>> {
static constexpr auto symbol = Symbol;
};
template<typename Child, Dimension D, Ratio R>
struct derived_unit : downcast_child<Child, unit<D, R>> {
static constexpr auto symbol = "aaa";
};
template<typename Child, Prefix P, Unit U>
requires requires { U::symbol; }
struct prefixed_derived_unit : downcast_child<Child, unit<typename U::dimension, ratio_multiply<typename P::ratio, typename U::ratio>>> {
@@ -168,8 +149,13 @@ namespace units {
};
template<typename Child, basic_fixed_string Symbol, Dimension D, Unit U, Unit... Us>
struct deduced_derived_unit : downcast_child<Child, detail::make_derived_unit<D, U, Us...>> {
struct named_deduced_derived_unit : downcast_child<Child, detail::make_derived_unit<D, U, Us...>> {
static constexpr auto symbol = Symbol;
};
template<typename Child, Dimension D, Unit U, Unit... Us>
struct deduced_derived_unit : downcast_child<Child, detail::make_derived_unit<D, U, Us...>> {
static constexpr auto symbol = "bbb";
};
} // namespace units