LCOV - code coverage report
Current view: top level - include/xo/unit - basis_unit.hpp (source / functions) Hit Total Coverage
Test: out3.info Lines: 7 12 58.3 %
Date: 1980-01-01 00:00:00 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /** @file basis_unit.hpp **/
       2             : 
       3             : #pragma once
       4             : 
       5             : #include "native_unit.hpp"
       6             : #include "basis_unit_abbrev.hpp"
       7             : #include "xo/ratio/ratio.hpp"
       8             : 
       9             : namespace xo {
      10             :     namespace qty {
      11             :         /** @class basis_unit2
      12             :          *  @brief A dimensionless multiple of a single natively-specified basis dimension
      13             :          *
      14             :          *  For example "3600 minutes" or "1e-6 grams"
      15             :          **/
      16             :         struct basis_unit {
      17             :         public:
      18             :             constexpr basis_unit() = default;
      19          77 :             constexpr basis_unit(dim native_dim, const scalefactor_ratio_type & scalefactor)
      20          77 :                 : native_dim_{native_dim},
      21          50 :                   scalefactor_{scalefactor}
      22             :                 {}
      23             : 
      24         107 :             constexpr dim native_dim() const { return native_dim_; }
      25         146 :             constexpr const scalefactor_ratio_type & scalefactor() const { return scalefactor_; }
      26             : 
      27          36 :             constexpr basis_unit2_abbrev_type abbrev() const {
      28          36 :                 return abbrev::basis_unit2_abbrev(native_dim_,
      29             :                                                   scalefactor_);
      30             :             }
      31             : 
      32             :             constexpr basis_unit & operator=(const basis_unit & x) = default;
      33             : 
      34             :             /** @brief identifies a native unit, e.g. time (in seconds) **/
      35             :             dim native_dim_ = dim::invalid;
      36             :             /** @brief this unit defined as multiple scalefactor times native unit **/
      37             :             scalefactor_ratio_type scalefactor_;
      38             :         };
      39             : 
      40             :         namespace bu {
      41             :             // ----- mass -----
      42             : 
      43             :             constexpr basis_unit picogram         = basis_unit(dim::mass, scalefactor_ratio_type(            1, 1000000000000));
      44             :             constexpr basis_unit nanogram         = basis_unit(dim::mass, scalefactor_ratio_type(            1,    1000000000));
      45             :             constexpr basis_unit microgram        = basis_unit(dim::mass, scalefactor_ratio_type(            1,       1000000));
      46             :             constexpr basis_unit milligram        = basis_unit(dim::mass, scalefactor_ratio_type(            1,          1000));
      47             :             constexpr basis_unit gram             = basis_unit(dim::mass, scalefactor_ratio_type(            1,             1));
      48             :             constexpr basis_unit kilogram         = basis_unit(dim::mass, scalefactor_ratio_type(         1000,             1));
      49             :             constexpr basis_unit tonne            = basis_unit(dim::mass, scalefactor_ratio_type(      1000000,             1));
      50             :             constexpr basis_unit kilotonne        = basis_unit(dim::mass, scalefactor_ratio_type(   1000000000,             1));
      51             :             constexpr basis_unit megatonne        = basis_unit(dim::mass, scalefactor_ratio_type(1000000000000,             1));
      52             : 
      53             :             // ----- distance -----
      54             : 
      55             :             /* International spelling */
      56             :             constexpr basis_unit picometre        = basis_unit(dim::distance, scalefactor_ratio_type(            1, 1000000000000));
      57             :             constexpr basis_unit nanometre        = basis_unit(dim::distance, scalefactor_ratio_type(            1,    1000000000));
      58             :             constexpr basis_unit micrometre       = basis_unit(dim::distance, scalefactor_ratio_type(            1,       1000000));
      59             :             constexpr basis_unit millimetre       = basis_unit(dim::distance, scalefactor_ratio_type(            1,          1000));
      60             :             constexpr basis_unit metre            = basis_unit(dim::distance, scalefactor_ratio_type(            1,             1));
      61             :             constexpr basis_unit kilometre        = basis_unit(dim::distance, scalefactor_ratio_type(         1000,             1));
      62             :             constexpr basis_unit megametre        = basis_unit(dim::distance, scalefactor_ratio_type(      1000000,             1));
      63             :             constexpr basis_unit gigametre        = basis_unit(dim::distance, scalefactor_ratio_type(   1000000000,             1));
      64             : 
      65             :             constexpr basis_unit lightsecond      = basis_unit(dim::distance, scalefactor_ratio_type(    299792458,             1));
      66             :             constexpr basis_unit astronomicalunit = basis_unit(dim::distance, scalefactor_ratio_type( 149597870700,             1));
      67             : 
      68             :             /* US spelling */
      69             :             constexpr basis_unit picometer        = picometre;
      70             :             constexpr basis_unit nanometer        = nanometre;
      71             :             constexpr basis_unit micrometer       = micrometre;
      72             :             constexpr basis_unit millimeter       = millimetre;
      73             :             constexpr basis_unit meter            = metre;
      74             :             constexpr basis_unit kilometer        = kilometre;
      75             : 
      76             :             // ----- time -----
      77             : 
      78             :             constexpr basis_unit picosecond       = basis_unit(dim::time,     scalefactor_ratio_type(            1, 1000000000000));
      79             :             constexpr basis_unit nanosecond       = basis_unit(dim::time,     scalefactor_ratio_type(            1,    1000000000));
      80             :             constexpr basis_unit microsecond      = basis_unit(dim::time,     scalefactor_ratio_type(            1,       1000000));
      81             :             constexpr basis_unit millisecond      = basis_unit(dim::time,     scalefactor_ratio_type(            1,          1000));
      82             :             constexpr basis_unit second           = basis_unit(dim::time,     scalefactor_ratio_type(            1,             1));
      83             :             constexpr basis_unit minute           = basis_unit(dim::time,     scalefactor_ratio_type(           60,             1));
      84             :             constexpr basis_unit hour             = basis_unit(dim::time,     scalefactor_ratio_type(         3600,             1));
      85             :             constexpr basis_unit day              = basis_unit(dim::time,     scalefactor_ratio_type(      24*3600,             1));
      86             :             constexpr basis_unit week             = basis_unit(dim::time,     scalefactor_ratio_type(    7*24*3600,             1));
      87             :             constexpr basis_unit month            = basis_unit(dim::time,     scalefactor_ratio_type(   30*24*3600,             1));
      88             :             constexpr basis_unit year             = basis_unit(dim::time,     scalefactor_ratio_type((365*24+6)*3600,           1));
      89             : 
      90             :             /* alt conventions used in finance */
      91             :             constexpr basis_unit year365          = basis_unit(dim::time,     scalefactor_ratio_type(  365*24*3600,             1));
      92             :             constexpr basis_unit year360          = basis_unit(dim::time,     scalefactor_ratio_type(  360*24*3600,             1));
      93             :             /* 250 = approx number of trading days in a calendar year */
      94             :             constexpr basis_unit year250          = basis_unit(dim::time,     scalefactor_ratio_type(  250*24*3600,             1));
      95             : 
      96             :             // ----- currency -----
      97             : 
      98             :             /* pseudounit -- placeholder for any actual currency amount */
      99             :             constexpr basis_unit currency         = basis_unit(dim::currency, scalefactor_ratio_type(            1,             1));
     100             : 
     101             :             // ----- price -----
     102             : 
     103             :             /* psuedounit -- context-dependent interpretation */
     104             :             constexpr basis_unit price            = basis_unit(dim::price,    scalefactor_ratio_type(            1,             1));
     105             :         }
     106             : 
     107             :         namespace units {
     108             :             /** for runtime work,  would like to be able to promptly find special abbreviation
     109             :              *  keyed by (native_dim, scalefactor).
     110             :              *
     111             :              *  Also want to support compile-time-only unit computation.
     112             :              *  Since constexpr unordered containers aren't obviously feasible (as of c++23).
     113             :              *
     114             :              *  Solution adopted here is to support introduction of scaled native units
     115             :              *  only at compile time,  at least for now
     116             :              **/
     117             : 
     118             :             // ----- scaled_native_unit_abbrev_helper -----
     119             : 
     120             :             /* Require: InnerScale is ratio type; InnerScale >= 1
     121             :              *
     122             :              * NOTE: clang 18 doesn't accept that scalefactor_ratio_type is a 'structural type'
     123             :              */
     124             :             template <dim BasisDim, std::int64_t InnerScaleNum = 1, std::int64_t InnerScaleDen = 1>
     125             :             struct scaled_native_unit2_abbrev;
     126             : 
     127             :             template <dim BasisDim>
     128             :             struct scaled_native_unit2_abbrev<BasisDim, 1, 1> {
     129             :                 static constexpr const basis_unit2_abbrev_type value
     130             :                 = (basis_unit2_abbrev_type::from_flatstring
     131             :                    (native_unit2_v[static_cast<uint32_t>(BasisDim)]
     132             :                     .abbrev_str()));
     133             :             };
     134             : 
     135             :             inline
     136             :             constexpr basis_unit2_abbrev_type
     137           0 :             bu_fallback_abbrev(dim basis_dim,
     138             :                                const scalefactor_ratio_type & scalefactor)
     139             :             {
     140           0 :                 return (basis_unit2_abbrev_type::from_flatstring
     141           0 :                         (flatstring_concat
     142           0 :                          (scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
     143           0 :                           native_unit2_v[static_cast<std::uint32_t>(basis_dim)].abbrev_str())));
     144             :             }
     145             : 
     146             : #ifdef NOT_USING
     147             :             template <dim BasisDim,
     148             :                       std::int64_t InnerScaleNum,
     149             :                       std::int64_t InnerScaleDen>
     150             :             struct scaled_native_unit2_abbrev {
     151             :                 /* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
     152             :                  *      of a specialization for scaled_native_unit_abbrev
     153             :                  */
     154             :                 static constexpr const basis_unit2_abbrev_type value
     155             :                 = (basis_unit2_abbrev_type::from_flatstring
     156             :                    (flatstring_concat
     157             :                     (xo::ratio::ratio<std::int64_t>(InnerScaleNum,
     158             :                                                     InnerScaleDen)
     159             :                      .to_str<basis_unit2_abbrev_type::fixed_capacity>(),
     160             :                      native_unit2_v[static_cast<std::uint32_t>(BasisDim)].abbrev_str())));
     161             : 
     162             :                 // = bu_fallback_abbrev(BasisDim,
     163             :                 //                      xo::ratio::ratio<std::int64_t>(InnerScaleNum, InnerScaleDen));
     164             :             };
     165             : 
     166             :             template <>
     167             :             struct scaled_native_unit2_abbrev<dim::mass, bu::nanogram.scalefactor().num(), bu::nanogram.scalefactor().den()> {
     168             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("ng");
     169             :             };
     170             : 
     171             :             template <>
     172             :             struct scaled_native_unit2_abbrev<dim::mass, bu::microgram.scalefactor().num(), bu::microgram.scalefactor().den()> {
     173             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("ug");
     174             :             };
     175             : 
     176             :             template <>
     177             :             struct scaled_native_unit2_abbrev<dim::mass, bu::milligram.scalefactor().num(), bu::milligram.scalefactor().den()> {
     178             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("mg");
     179             :             };
     180             : 
     181             :             template <>
     182             :             struct scaled_native_unit2_abbrev<dim::mass, 1000, 1> {
     183             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("kg");
     184             :             };
     185             : 
     186             :             template <>
     187             :             struct scaled_native_unit2_abbrev<dim::mass, 1000000, 1> {
     188             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("t");
     189             :             };
     190             : 
     191             :             template <>
     192             :             struct scaled_native_unit2_abbrev<dim::mass, 1000000000, 1> {
     193             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("kt");
     194             :             };
     195             : 
     196             :             // ----- units for dim::distance -----
     197             : 
     198             :             template <>
     199             :             struct scaled_native_unit2_abbrev<dim::distance, 1, 1000000000> {
     200             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("nm");
     201             :             };
     202             : 
     203             :             template <>
     204             :             struct scaled_native_unit2_abbrev<dim::distance, 1, 1000000> {
     205             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("um");
     206             :             };
     207             : 
     208             :             template <>
     209             :             struct scaled_native_unit2_abbrev<dim::distance, 1, 1000> {
     210             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("mm");
     211             :             };
     212             : 
     213             :             template <>
     214             :             struct scaled_native_unit2_abbrev<dim::distance, 1000, 1> {
     215             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("km");
     216             :             };
     217             : 
     218             :             // ----- units for dim::time -----
     219             : 
     220             :             template <>
     221             :             struct scaled_native_unit2_abbrev<dim::time, 1, 1000000000> {
     222             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("ns");
     223             :             };
     224             : 
     225             :             template <>
     226             :             struct scaled_native_unit2_abbrev<dim::time, 1, 1000000> {
     227             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("us");
     228             :             };
     229             : 
     230             :             template <>
     231             :             struct scaled_native_unit2_abbrev<dim::time, 1, 1000> {
     232             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("ms");
     233             :             };
     234             : 
     235             :             template <>
     236             :             struct scaled_native_unit2_abbrev<dim::time, 60, 1> {
     237             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("min");
     238             :             };
     239             : 
     240             :             template <>
     241             :             struct scaled_native_unit2_abbrev<dim::time, 3600, 1> {
     242             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("hr");
     243             :             };
     244             : 
     245             :             template <>
     246             :             struct scaled_native_unit2_abbrev<dim::time, 24*3600, 1> {
     247             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("dy");
     248             :             };
     249             : 
     250             :             template <>
     251             :             struct scaled_native_unit2_abbrev<dim::time, 250*24*3600, 1> {
     252             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("yr250");
     253             :             };
     254             : 
     255             :             template <>
     256             :             struct scaled_native_unit2_abbrev<dim::time, 360*24*3600, 1> {
     257             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("yr360");
     258             :             };
     259             : 
     260             :             template <>
     261             :             struct scaled_native_unit2_abbrev<dim::time, 365*24*3600, 1> {
     262             :                 static constexpr const basis_unit2_abbrev_type value = basis_unit2_abbrev_type::from_chars("yr365");
     263             :             };
     264             : 
     265             :             // ----- native unit abbrev api -----
     266             : 
     267             :             template <dim BasisDim, std::int64_t InnerScaleNum = 1, std::int64_t InnerScaleDen = 1>
     268             :             constexpr auto scaled_native_unit2_abbrev_v = scaled_native_unit2_abbrev<BasisDim, InnerScaleNum, InnerScaleDen>::value;
     269             : #endif
     270             :         }
     271             : 
     272             : 
     273             :     } /*namespace qty*/
     274             : } /*namespace xo*/
     275             : 
     276             : /** end basis_unit.hpp **/

Generated by: LCOV version 1.0