Changeset 69:3f22cef1e8b5 in rrlib_si_units


Ignore:
Timestamp:
18.02.2019 08:42:40 (8 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Message:

Revises and tidies name string generation of SI units (float variants now get more readable type names; most of the implementation is now located in .cpp files which results in slightly smaller binaries and shorter compile times)

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • rtti.cpp

    r68 r69  
    3232// External includes (system with <>, local with "") 
    3333//---------------------------------------------------------------------- 
     34#ifdef _LIB_RRLIB_RTTI_PRESENT_ 
     35 
    3436#include "rrlib/si_units/si_units.h" 
    3537#include "rrlib/rtti_conversion/tStaticCastOperation.h" 
     
    6971//---------------------------------------------------------------------- 
    7072 
     73namespace 
     74{ 
     75util::tManagedConstCharPointer GetDefaultTypename(uint si_unit_id, const rtti::tType& element_type) 
     76{ 
     77  std::stringstream str; 
     78  if (si_unit_id == 0) 
     79  { 
     80    str << "rrlib.si_units." << element_type.GetName(); 
     81  } 
     82  else 
     83  { 
     84    // Fallback to legacy names 
     85    str << "rrlib.si_units.Quantity<"; 
     86    internal::WriteSIUnit(str, si_unit_id); 
     87    str << ", " << element_type.GetName() << ">"; 
     88  } 
     89  return util::tManagedConstCharPointer(str.str().c_str(), true); 
     90} 
     91} 
     92 
     93namespace internal 
     94{ 
     95 
     96util::tManagedConstCharPointer GetSIUnitsTypename(uint si_unit_id, const rtti::tType& type) 
     97{ 
     98  rtti::tType element_type = type.GetUnderlyingType(); 
     99  const char* predefined_string = nullptr; 
     100  switch (si_unit_id) 
     101  { 
     102  case tLength<>::tUnit::cID: 
     103    predefined_string = "rrlib.si_units.Length"; 
     104    break; 
     105  case tMass<>::tUnit::cID: 
     106    predefined_string = "rrlib.si_units.Mass"; 
     107    break; 
     108  case tTime<>::tUnit::cID: 
     109    predefined_string = "rrlib.si_units.Time"; 
     110    break; 
     111  case tElectricCurrent<>::tUnit::cID: 
     112    predefined_string = "rrlib.si_units.ElectricCurrent"; 
     113    break; 
     114  case tTemperature<>::tUnit::cID: 
     115    predefined_string = "rrlib.si_units.Temperature"; 
     116    break; 
     117  case tAmountOfSubstance<>::tUnit::cID: 
     118    predefined_string = "rrlib.si_units.AmountOfSubstance"; 
     119    break; 
     120  case tLuminousIntensity<>::tUnit::cID: 
     121    predefined_string = "rrlib.si_units.LuminousIntensity"; 
     122    break; 
     123 
     124  case tFrequency<>::tUnit::cID: 
     125    predefined_string = "rrlib.si_units.Frequency"; 
     126    break; 
     127  case tForce<>::tUnit::cID: 
     128    predefined_string = "rrlib.si_units.Force"; 
     129    break; 
     130  case tPressure<>::tUnit::cID: 
     131    predefined_string = "rrlib.si_units.Pressure"; 
     132    break; 
     133 
     134  case tVelocity<>::tUnit::cID: 
     135    predefined_string = "rrlib.si_units.Velocity"; 
     136    break; 
     137  case tAcceleration<>::tUnit::cID: 
     138    predefined_string = "rrlib.si_units.Acceleration"; 
     139    break; 
     140  } 
     141 
     142  if (predefined_string) 
     143  { 
     144    if (element_type == rtti::tDataType<double>()) 
     145    { 
     146      return util::tManagedConstCharPointer(predefined_string, false); 
     147    } 
     148    else 
     149    { 
     150      std::stringstream str; 
     151      str << predefined_string << "<" << element_type.GetName() << ">"; 
     152      return util::tManagedConstCharPointer(str.str().c_str(), true); 
     153    } 
     154  } 
     155  return GetDefaultTypename(si_unit_id, element_type); 
     156} 
     157 
     158util::tManagedConstCharPointer GetSIUnitsTypenameAngular(uint si_unit_id, const rtti::tType& type) 
     159{ 
     160  rtti::tType element_type = type.GetUnderlyingType(); 
     161  const char* predefined_string = nullptr; 
     162  bool default_type = false; 
     163  std::string postfix; 
     164  switch (si_unit_id) 
     165  { 
     166  case tAngularVelocity<>::tUnit::cID: 
     167    predefined_string = "rrlib.si_units.AngularVelocity"; 
     168    default_type = element_type == rtti::tDataType<tAngularVelocity<>::tValue>(); 
     169    if (element_type == rtti::tDataType<typename tAngularVelocity<float>::tValue>()) 
     170    { 
     171      postfix = "<float>"; 
     172    } 
     173    break; 
     174  case tAngularAcceleration<>::tUnit::cID: 
     175    predefined_string = "rrlib.si_units.AngularAcceleration"; 
     176    default_type = element_type == rtti::tDataType<tAngularAcceleration<>::tValue>(); 
     177    if (element_type == rtti::tDataType<typename tAngularAcceleration<float>::tValue>()) 
     178    { 
     179      postfix = "<float>"; 
     180    } 
     181    break; 
     182  } 
     183 
     184  if (predefined_string) 
     185  { 
     186    if (default_type) 
     187    { 
     188      return util::tManagedConstCharPointer(predefined_string, false); 
     189    } 
     190    else 
     191    { 
     192      std::stringstream str; 
     193      str << predefined_string; 
     194      if (postfix.length()) 
     195      { 
     196        str << postfix; 
     197      } 
     198      else 
     199      { 
     200        str << "<" << element_type.GetName() << ">"; 
     201      } 
     202      return util::tManagedConstCharPointer(str.str().c_str(), true); 
     203    } 
     204  } 
     205  return GetDefaultTypename(si_unit_id, element_type); 
     206} 
     207 
     208} 
     209 
    71210rtti::tStaticTypeRegistration init_type = rtti::tStaticTypeRegistration("rrlib_si_units"). 
    72     Add<tLength<>>("rrlib.si_units.Length", "Quantity<m, double>"). 
    73     Add<tMass<>>("rrlib.si_units.Mass", "Quantity<kg, double>"). 
    74     Add<tTime<>>("rrlib.si_units.Time", "Quantity<s, double>"). 
    75     Add<tElectricCurrent<>>("rrlib.si_units.ElectricCurrent", "Quantity<A, double>"). 
    76     Add<tTemperature<>>("rrlib.si_units.Temperature", "Quantity<K, double>"). 
    77     Add<tAmountOfSubstance<>>("rrlib.si_units.AmountOfSubstance"). 
    78     Add<tLuminousIntensity<>>("rrlib.si_units.LuminousIntensity"). 
    79  
    80     Add<tFrequency<>>("rrlib.si_units.Frequency", "Quantity<1/s, double>"). 
    81     Add<tForce<>>("rrlib.si_units.Force", "Quantity<N, double>"). 
    82     Add<tPressure<>>("rrlib.si_units.Pressure", "Quantity<Pa, double>"). 
    83  
    84     Add<tVelocity<>>("rrlib.si_units.Velocity", "Quantity<m/s, double>"). 
    85     Add<tAcceleration<>>("rrlib.si_units.Acceleration", "Quantity<m/s^2, double>"). 
    86     Add<tAngularVelocity<>>("rrlib.si_units.AngularVelocity", "Quantity<1/s, Angle>"). 
    87     Add<tAngularAcceleration<>>("rrlib.si_units.AngularAcceleration", "Quantity<1/s^2, Angle>"). 
    88  
    89     Add<tQuantity<tNoUnit, rrlib::math::tAngleRad>>("rrlib.si_units.Angle", "Quantity<, rrlib.math.Angle<double, rrlib.math.angle.Radian, rrlib.math.angle.Signed>>"); 
     211    Add<tLength<>>().AddName("Quantity<m, double>"). 
     212    Add<tMass<>>().AddName("Quantity<kg, double>"). 
     213    Add<tTime<>>().AddName("Quantity<s, double>"). 
     214    Add<tElectricCurrent<>>().AddName("Quantity<A, double>"). 
     215    Add<tTemperature<>>().AddName("Quantity<K, double>"). 
     216    Add<tAmountOfSubstance<>>(). 
     217    Add<tLuminousIntensity<>>(). 
     218 
     219    Add<tFrequency<>>().AddName("Quantity<1/s, double>"). 
     220    Add<tForce<>>().AddName("Quantity<N, double>"). 
     221    Add<tPressure<>>().AddName("Quantity<Pa, double>"). 
     222 
     223    Add<tVelocity<>>().AddName("Quantity<m/s, double>"). 
     224    Add<tAcceleration<>>().AddName("Quantity<m/s^2, double>"). 
     225    Add<tAngularVelocity<>>().AddName("Quantity<1/s, Angle>"). 
     226    Add<tAngularAcceleration<>>().AddName("Quantity<1/s^2, Angle>"). 
     227 
     228    Add<tQuantity<tNoUnit, rrlib::math::tAngleRad>>().AddName("Quantity<, rrlib.math.Angle<double, rrlib.math.angle.Radian, rrlib.math.angle.Signed>>"); 
    90229 
    91230auto& cTYPE_CASTS = rrlib::rtti::conversion::tStaticCastOperation::Register<rrlib::time::tDuration, rrlib::si_units::tTime<>, true>(); 
     
    97236} 
    98237 
     238#endif 
     239 
  • rtti.h

    r62 r69  
    3636#ifndef __rrlib__si_units__rtti_h__ 
    3737#define __rrlib__si_units__rtti_h__ 
     38#ifdef _LIB_RRLIB_RTTI_PRESENT_ 
    3839 
    3940//---------------------------------------------------------------------- 
     
    5455namespace rrlib 
    5556{ 
    56 namespace rtti 
    57 { 
    5857 
    5958//---------------------------------------------------------------------- 
     
    6160//---------------------------------------------------------------------- 
    6261 
     62namespace si_units 
     63{ 
     64namespace internal 
     65{ 
     66 
     67util::tManagedConstCharPointer GetSIUnitsTypename(uint si_unit_id, const rtti::tType& type); 
     68util::tManagedConstCharPointer GetSIUnitsTypenameAngular(uint si_unit_id, const rtti::tType& type); 
     69 
     70template <uint Tsi_unit_id, typename TValue> 
     71struct SIUnitsTypeName 
     72{ 
     73  static util::tManagedConstCharPointer Get(const rtti::tType& type) 
     74  { 
     75    return GetSIUnitsTypename(Tsi_unit_id, type); 
     76  } 
     77}; 
     78template <uint Tsi_unit_id, typename TValue> 
     79struct SIUnitsTypeNameAngular 
     80{ 
     81  static util::tManagedConstCharPointer Get(const rtti::tType& type) 
     82  { 
     83    return GetSIUnitsTypenameAngular(Tsi_unit_id, type); 
     84  } 
     85}; 
     86 
     87} 
     88} 
     89 
    6390//---------------------------------------------------------------------- 
    6491// Function declarations 
    6592//---------------------------------------------------------------------- 
    6693 
     94namespace rtti 
     95{ 
     96 
    6797template <typename TUnit, typename TValue> 
    6898struct TypeName<si_units::tQuantity<TUnit, TValue>> 
    6999{ 
    70   /*! 
    71    * \return Type name to use in rrlib_rtti for type T 
    72    */ 
    73   static util::tManagedConstCharPointer Get(const rrlib::rtti::tType& type) 
    74   { 
    75     std::stringstream str; 
    76     str << "rrlib.si_units.Quantity<" << TUnit() << ", " << rtti::tDataType<TValue>().GetName() << ">"; 
    77     return util::tManagedConstCharPointer(str.str().c_str(), true); 
    78   } 
    79  
    80   static constexpr tGetTypenameFunction value = &Get; 
     100  static constexpr tGetTypenameFunction value = &si_units::internal::SIUnitsTypeName<TUnit::cID, TValue>::Get; 
    81101}; 
    82102 
    83 // specialization for unit-less types 
    84 template <typename TValue> 
    85 struct TypeName<si_units::tQuantity<si_units::tSIUnit<0, 0, 0, 0, 0, 0, 0>, TValue>> 
     103// specialization for angles 
     104template <typename TUnit, typename TElement, typename TUnitPolicy, typename TAutoWrapPolicy> 
     105struct TypeName<si_units::tQuantity<TUnit, math::tAngle<TElement, TUnitPolicy, TAutoWrapPolicy>>> 
    86106{ 
    87   /*! 
    88    * \return Type name to use in rrlib_rtti for type T 
    89    */ 
    90   static util::tManagedConstCharPointer Get(const rrlib::rtti::tType& type) 
    91   { 
    92     std::stringstream str; 
    93     str << "rrlib.si_units." << rtti::tDataType<TValue>().GetName(); 
    94     return util::tManagedConstCharPointer(str.str().c_str(), true); 
    95   } 
    96  
    97   static constexpr tGetTypenameFunction value = &Get; 
    98 }; 
    99  
    100 // specialization for default angle class 
    101 template <typename TUnit> 
    102 struct TypeName<si_units::tQuantity<TUnit, math::tAngle<double, math::angle::Radian, math::angle::NoWrap>>> 
    103 { 
    104   /*! 
    105    * \return Type name to use in rrlib_rtti for type T 
    106    */ 
    107   static util::tManagedConstCharPointer Get(const rrlib::rtti::tType& type) 
    108   { 
    109     std::stringstream str; 
    110     str << "rrlib.si_units.Quantity<" << TUnit() << ", Angle>"; 
    111     return util::tManagedConstCharPointer(str.str().c_str(), true); 
    112   } 
    113  
    114   static constexpr tGetTypenameFunction value = &Get; 
     107  static constexpr tGetTypenameFunction value = &si_units::internal::SIUnitsTypeNameAngular<TUnit::cID, math::tAngle<TElement, TUnitPolicy, TAutoWrapPolicy>>::Get; 
    115108}; 
    116109 
     
    133126 
    134127#endif 
     128#endif 
  • tSIUnit.cpp

    r67 r69  
    167167} 
    168168 
     169void GetExponentsFromUnitId(std::array<int, cNUMBER_OF_BASIC_DIMENSIONS>& result, uint si_unit_id) 
     170{ 
     171  for (size_t i = 0; i < cNUMBER_OF_BASIC_DIMENSIONS; i++) 
     172  { 
     173    result[i] = (si_unit_id >> (24 - i * 4)) & 0xF; 
     174    result[i] -= (result[i] > 7 ? 16 : 0); 
     175  } 
     176} 
     177 
    169178} 
    170179 
     
    200209    stream.get(); 
    201210  } 
     211} 
     212 
     213void WriteSIUnit(std::ostream &stream, uint unit_id) 
     214{ 
     215  std::vector<std::string> nominator; 
     216  std::vector<std::string> denominator; 
     217  std::array<int, cNUMBER_OF_BASIC_DIMENSIONS> exponents; 
     218  GetExponentsFromUnitId(exponents, unit_id); 
     219 
     220  DetermineSymbolComponentsFromExponentList(nominator, denominator, exponents.data(), stream); 
     221 
     222  if (!nominator.empty()) 
     223  { 
     224    stream << util::Join(nominator, ""); 
     225  } 
     226  if (!denominator.empty()) 
     227  { 
     228    stream << (nominator.empty() ? "1/" : "/"); 
     229    stream << util::Join(denominator, ""); 
     230  } 
     231 
    202232} 
    203233 
  • tSIUnit.h

    r67 r69  
    6666//---------------------------------------------------------------------- 
    6767 
     68void WriteSIUnit(std::ostream &stream, uint unit_id); 
    6869void ReadSIUnit(std::istream &stream, std::ostringstream &unit_string); 
    6970} 
     
    8889  static const int cAMOUNT_OF_SUBSTANCE = Tamount_of_substance; 
    8990  static const int cLUMINOUS_INTENSITY = Tluminous_intensity; 
     91 
     92  static const uint cID = ((Tlength & 0xF) << 24) | ((Tmass & 0xF) << 20) | ((Ttime & 0xF) << 16) | ((Telectric_current & 0xF) << 12) | ((Ttemperature & 0xF) << 8) | ((Tamount_of_substance & 0xF) << 4) | (Tluminous_intensity & 0xF); 
    9093}; 
    9194 
     
    97100std::ostream &operator << (std::ostream &stream, tSIUnit<Tlength, Tmass, Ttime, Telectric_current, Ttemperature, Tamount_of_substance, Tluminous_intensity> unit) 
    98101{ 
    99   std::vector<std::string> nominator; 
    100   std::vector<std::string> denominator; 
    101   int exponents[cNUMBER_OF_BASIC_DIMENSIONS] = { Tlength, Tmass, Ttime, Telectric_current, Ttemperature, Tamount_of_substance, Tluminous_intensity }; 
    102  
    103   DetermineSymbolComponentsFromExponentList(nominator, denominator, exponents, stream); 
    104  
    105   if (!nominator.empty()) 
    106   { 
    107     stream << util::Join(nominator, ""); 
    108   } 
    109   if (!denominator.empty()) 
    110   { 
    111     stream << (nominator.empty() ? "1/" : "/"); 
    112     stream << util::Join(denominator, ""); 
    113   } 
    114  
     102  internal::WriteSIUnit(stream, tSIUnit<Tlength, Tmass, Ttime, Telectric_current, Ttemperature, Tamount_of_substance, Tluminous_intensity>::cID); 
    115103  return stream; 
    116104} 
Note: See TracChangeset for help on using the changeset viewer.