IAP GITLAB

Skip to content
Snippets Groups Projects
Commit ad4e5558 authored by ralfulrich's avatar ralfulrich
Browse files

moved phys-units code to ThirdParty directory

parent cd627541
No related branches found
No related tags found
No related merge requests found
Showing
with 24 additions and 2011 deletions
cmake_minimum_required (VERSION 3.4.3)
project (corsika VERSION 8.0.0 DESCRIPTION "CORSIKA C++ project")
# ignore many irrelevant Up-to-date messages during install
set (CMAKE_INSTALL_MESSAGE LAZY)
# --std=c++14
set (CMAKE_CXX_STANDARD 14)
project (corsika VERSION 8.0.0 DESCRIPTION "CORSIKA C++ project")
#add_custom_target (corsika_pre_build)
#add_custom_command (TARGET corsika_pre_build PRE_BUILD COMMAND "${PROJECT_SOURCE_DIR}/pre_compile.py")
# dependencies
find_package (Boost 1.40 COMPONENTS program_options REQUIRED)
find_package (Eigen3 3.3 REQUIRED)
find_package (HDF5)
# order of subdirectories
add_subdirectory (ThirdParty)
add_subdirectory (Documentation)
add_subdirectory (Framework)
#add_subdirectory (Processes)
......
......@@ -9,6 +9,7 @@ set_target_properties (CORSIKAgeometry PROPERTIES SOVERSION 1)
set_target_properties (CORSIKAgeometry PROPERTIES PUBLIC_HEADER "${GEOMETRY_HEADERS}")
# target dependencies on other libraries (also header only)
target_link_libraries (CORSIKAgeometry CORSIKAunits)
target_include_directories (CORSIKAgeometry PRIVATE ${EIGEN3_INCLUDE_DIR})
......
......@@ -2,7 +2,7 @@
#define _include_SPHERE_H_
#include <Geometry/Point.h>
#include <Units/units/quantity.hpp>
#include <Units/PhysicalUnits.h>
class Sphere
{
......
add_library (CORSIKAunits INTERFACE)
target_include_directories (CORSIKAunits INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework>
$<INSTALL_INTERFACE:include/Framework>
)
target_include_directories (CORSIKAunits
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Framework>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/ThirdParty>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)
install (FILES PhysicalUnits.h PhysicalConstants.h
DESTINATION include/Units)
install (FILES PhysicalUnits.h DESTINATION include/Units)
install (DIRECTORY units
DESTINATION include/Units)
#ifndef _INCLUDE_PHYSICAL_CONSTANTS_H_
#define _INCLUDE_PHYSICAL_CONSTANTS_H_
#include "Units/PhysicalUnits.h"
namespace phys {
namespace units {
// electronvolt
constexpr quantity< energy_d > eV { Rep( 1.60217733e-19L ) * joule };
// elementary charge
constexpr quantity< electric_charge_d >
e { Rep( 1.602176462e-19L ) * coulomb };
// Planck constant
constexpr quantity< dimensions< 2, 1, -1 > >
h { Rep( 6.62606876e-34L ) * joule * second };
// speed of light in a vacuum
constexpr quantity< speed_d > c { Rep( 299792458L ) * meter / second };
}
}
#endif
#ifndef _include_PhysicalUnits_h_
#define _include_PhysicalUnits_h_
#include <Units/units/quantity.hpp>
#include <Units/units/io.hpp>
#include <ThirdParty/phys/units/quantity.hpp>
#include <ThirdParty/phys/units/io.hpp>
#include <ThirdParty/phys/units/physical_constants.hpp>
#include <Units/PhysicalConstants.h>
/**
/file PhysicalUnits
/**
/file PhysicalUnits
Define _XeV literals, alowing 10_GeV in the code.
*/
Define _XeV literals, alowing 10_GeV in the code.
*/
namespace phys {
namespace units {
......
/**
* \file io.hpp
*
* \brief IO for compile-time quantity library.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_IO_HPP_INCLUDED
#define PHYS_UNITS_IO_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
#include "Units/units/quantity_io_engineering.hpp"
#include "Units/units/quantity_io_symbols.hpp"
#endif // PHYS_UNITS_IO_HPP_INCLUDED
/*
* end of file
*/
/**
* \file io_output.hpp
*
* \brief IO for quantity library.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_IO_OUTPUT_HPP_INCLUDED
#define PHYS_UNITS_IO_OUTPUT_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
#endif // PHYS_UNITS_IO_OUTPUT_HPP_INCLUDED
/*
* end of file
*/
/**
* \file io_output_eng.hpp
*
* \brief Engineering IO for quantity library.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_IO_ENG_HPP_INCLUDED
#define PHYS_UNITS_IO_ENG_HPP_INCLUDED
#include "Units/units/quantity_io_engineering.hpp"
#endif // PHYS_UNITS_IO_ENG_HPP_INCLUDED
/*
* end of file
*/
/**
* \file io_symbols.hpp
*
* \brief IO for quantity library.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_IO_SYMBOLS_HPP_INCLUDED
#define PHYS_UNITS_IO_SYMBOLS_HPP_INCLUDED
#include "Units/units/quantity_io_symbols.hpp"
#endif // PHYS_UNITS_IO_SYMBOLS_HPP_INCLUDED
/*
* end of file
*/
/**
* \file other_units.hpp
*
* \brief Units not approved for use with SI.
* \author Michael S. Kenniston
* \date 16 July 2001
* \since 0.4
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
*
* Copyright (c) 2001 by Michael S. Kenniston. For the most
* recent version check www.xnet.com/~msk/quantity. Permission is granted
* to use this code without restriction so long as this copyright
* notice appears in all source files.
*
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* This file contains the definitions of units that are *NOT* approved
* for use with SI, as specified by SP811. These units should not
* be used with any new work. However, they may be needed for
* handling and converting legacy data.
*/
#ifndef PHYS_UNITS_OTHER_UNITS_HPP_INCLUDED
#define PHYS_UNITS_OTHER_UNITS_HPP_INCLUDED
#include "Units/units/quantity.hpp"
namespace phys { namespace units {
constexpr quantity< electric_current_d > abampere { Rep( 1e+1L ) * ampere };
constexpr quantity< electric_charge_d > abcoulomb { Rep( 1e+1L ) * coulomb };
constexpr quantity< capacitance_d > abfarad { Rep( 1e+9L ) * farad };
constexpr quantity< inductance_d > abhenry { Rep( 1e-9L ) * henry };
constexpr quantity< electric_conductance_d > abmho { Rep( 1e+9L ) * siemens };
constexpr quantity< electric_resistance_d > abohm { Rep( 1e-9L ) * ohm };
constexpr quantity< electric_potential_d > abvolt { Rep( 1e-8L ) * volt };
constexpr quantity< area_d > acre { Rep( 4.046873e+3L ) * square( meter ) };
constexpr quantity< volume_d > acre_foot { Rep( 1.233489e+3L ) * cube( meter ) };
constexpr quantity< length_d > astronomical_unit { Rep( 1.495979e+11L ) * meter };
constexpr quantity< pressure_d > atmosphere_std { Rep( 1.01325e+5L ) * pascal };
constexpr quantity< pressure_d > atmosphere_tech { Rep( 9.80665e+4L ) * pascal };
constexpr quantity< volume_d > barrel { Rep( 1.589873e-1L ) * cube( meter ) };
constexpr quantity< electric_current_d > biot { Rep( 1e+1L ) * ampere };
constexpr quantity< energy_d > btu { Rep( 1.05587e+3L ) * joule };
constexpr quantity< energy_d > btu_it { Rep( 1.055056e+3L ) * joule };
constexpr quantity< energy_d > btu_th { Rep( 1.054350e+3L ) * joule };
constexpr quantity< energy_d > btu_39F { Rep( 1.05967e+3L ) * joule };
constexpr quantity< energy_d > btu_59F { Rep( 1.05480e+3L ) * joule };
constexpr quantity< energy_d > btu_60F { Rep( 1.05468e+3L ) * joule };
constexpr quantity< volume_d > bushel { Rep( 3.523907e-2L ) * cube( meter ) };
constexpr quantity< energy_d > calorie { Rep( 4.19002L ) * joule };
constexpr quantity< energy_d > calorie_it { Rep( 4.1868L ) * joule };
constexpr quantity< energy_d > calorie_th { Rep( 4.184L ) * joule };
constexpr quantity< energy_d > calorie_15C { Rep( 4.18580L ) * joule };
constexpr quantity< energy_d > calorie_20C { Rep( 4.18190L ) * joule };
constexpr quantity< mass_d > carat_metric { Rep( 2e-4L ) * kilogram };
constexpr quantity< length_d > chain { Rep( 2.011684e+1L ) * meter };
constexpr quantity< thermal_insulance_d > clo { Rep( 1.55e-1L ) * square( meter ) * kelvin / watt };
constexpr quantity< pressure_d > cm_mercury { Rep( 1.333224e+3L ) * pascal };
constexpr quantity< volume_d > cord { Rep( 3.624556L ) * cube( meter ) };
constexpr quantity< volume_d > cup { Rep( 2.365882e-4L ) * cube( meter ) };
constexpr quantity< dimensions< 2, 0, 0 >> darcy { Rep( 9.869233e-13L ) * square( meter ) };
constexpr quantity< time_interval_d > day_sidereal { Rep( 8.616409e+4L ) * second };
constexpr quantity< dimensions< 1, 0, 1, 1>> debye { Rep( 3.335641e-30L ) * coulomb * meter };
constexpr quantity< thermodynamic_temperature_d > degree_fahrenheit{ Rep( 5.555556e-1L ) * kelvin };
constexpr quantity< thermodynamic_temperature_d > degree_rankine { Rep( 5.555556e-1L ) * kelvin };
constexpr quantity< dimensions< -1, 1, 0 >> denier { Rep( 1.111111e-7L ) * kilogram / meter };
constexpr quantity< force_d > dyne { Rep( 1e-5L ) * newton };
constexpr quantity< energy_d > erg { Rep( 1e-7L ) * joule };
constexpr quantity< electric_charge_d > faraday { Rep( 9.648531e+4L ) * coulomb };
constexpr quantity< length_d > fathom { Rep( 1.828804L ) * meter };
constexpr quantity< length_d > fermi { Rep( 1e-15L ) * meter };
constexpr quantity< length_d > foot { Rep( 3.048e-1L ) * meter };
constexpr quantity< energy_d > foot_pound_force { Rep( 1.355818L ) * joule };
constexpr quantity< energy_d > foot_poundal { Rep( 4.214011e-2L ) * joule };
constexpr quantity< length_d > foot_us_survey { Rep( 3.048006e-1L ) * meter };
constexpr quantity< illuminance_d > footcandle { Rep( 1.076391e+1L ) * lux };
constexpr quantity< illuminance_d > footlambert { Rep( 3.426259L ) * candela / square( meter ) };
constexpr quantity< time_interval_d > fortnight { Rep( 14 ) * day }; // from OED
constexpr quantity< electric_charge_d > franklin { Rep( 3.335641e-10L ) * coulomb };
constexpr quantity< length_d > furlong { Rep( 2.01168e+2L ) * meter }; // from OED
constexpr quantity< volume_d > gallon_imperial { Rep( 4.54609e-3L ) * cube( meter ) };
constexpr quantity< volume_d > gallon_us { Rep( 3.785412e-3L ) * cube( meter ) };
constexpr quantity< magnetic_flux_density_d > gamma { Rep( 1e-9L ) * tesla };
constexpr quantity< mass_d > gamma_mass { Rep( 1e-9L ) * kilogram };
constexpr quantity< magnetic_flux_density_d > gauss { Rep( 1e-4L ) * tesla };
constexpr quantity< electric_current_d > gilbert { Rep( 7.957747e-1L ) * ampere };
constexpr quantity< volume_d > gill_imperial { Rep( 1.420653e-4L ) * cube( meter ) };
constexpr quantity< volume_d > gill_us { Rep( 1.182941e-4L ) * cube( meter ) };
constexpr Rep gon { Rep( 9e-1L ) * degree_angle };
constexpr quantity< mass_d > grain { Rep( 6.479891e-5L ) * kilogram };
constexpr quantity< power_d > horsepower { Rep( 7.456999e+2L ) * watt };
constexpr quantity< power_d > horsepower_boiler { Rep( 9.80950e+3L ) * watt };
constexpr quantity< power_d > horsepower_electric{ Rep( 7.46e+2L ) * watt };
constexpr quantity< power_d > horsepower_metric { Rep( 7.354988e+2L ) * watt };
constexpr quantity< power_d > horsepower_uk { Rep( 7.4570e+2L ) * watt };
constexpr quantity< power_d > horsepower_water { Rep( 7.46043e+2L ) * watt };
constexpr quantity< time_interval_d > hour_sidereal { Rep( 3.590170e+3L ) * second };
constexpr quantity< mass_d > hundredweight_long { Rep( 5.080235e+1L ) * kilogram };
constexpr quantity< mass_d > hundredweight_short{ Rep( 4.535924e+1L ) * kilogram };
constexpr quantity< length_d > inch { Rep( 2.54e-2L ) * meter };
constexpr quantity< pressure_d > inches_mercury { Rep( 3.386389e+3L ) * pascal };
constexpr quantity< wave_number_d > kayser { Rep( 1e+2 ) / meter };
constexpr quantity< force_d > kilogram_force { Rep( 9.80665 ) * newton };
constexpr quantity< force_d > kilopond { Rep( 9.80665 ) * newton };
constexpr quantity< force_d > kip { Rep( 4.448222e+3L ) * newton };
constexpr quantity< volume_d > lambda_volume { Rep( 1e-9L ) * cube( meter ) };
constexpr quantity< illuminance_d > lambert { Rep( 3.183099e+3L ) * candela / square( meter ) };
constexpr quantity< heat_density_d > langley { Rep( 4.184e+4L ) * joule / square( meter ) };
constexpr quantity< length_d > light_year { Rep( 9.46073e+15L ) * meter };
constexpr quantity< magnetic_flux_d > maxwell { Rep( 1e-8L ) * weber };
constexpr quantity< electric_conductance_d > mho { siemens };
constexpr quantity< length_d > micron { micro * meter };
constexpr quantity< length_d > mil { Rep( 2.54e-5L ) * meter };
constexpr Rep mil_angle { Rep( 5.625e-2L ) * degree_angle };
constexpr quantity< area_d > mil_circular { Rep( 5.067075e-10L ) * square( meter ) };
constexpr quantity< length_d > mile { Rep( 1.609344e+3L ) * meter };
constexpr quantity< length_d > mile_us_survey { Rep( 1.609347e+3L ) * meter };
constexpr quantity< time_interval_d > minute_sidereal { Rep( 5.983617e+1L ) * second };
constexpr quantity< dimensions< -1, 0, 0, 1 > >oersted { Rep( 7.957747e+1L ) * ampere / meter };
constexpr quantity< mass_d > ounce_avdp { Rep( 2.834952e-2L ) * kilogram };
constexpr quantity< volume_d > ounce_fluid_imperial{ Rep( 2.841306e-5L ) * cube( meter ) };
constexpr quantity< volume_d > ounce_fluid_us { Rep( 2.957353e-5L ) * cube( meter ) };
constexpr quantity< force_d > ounce_force { Rep( 2.780139e-1L ) * newton };
constexpr quantity< mass_d > ounce_troy { Rep( 3.110348e-2L ) * kilogram };
constexpr quantity< length_d > parsec { Rep( 3.085678e+16L ) * meter };
constexpr quantity< volume_d > peck { Rep( 8.809768e-3L ) * cube( meter ) };
constexpr quantity< mass_d > pennyweight { Rep( 1.555174e-3L ) * kilogram };
constexpr quantity< substance_permeability_d > perm_0C { Rep( 5.72135e-11L ) * kilogram / pascal / second / square( meter ) };
constexpr quantity< substance_permeability_d > perm_23C { Rep( 5.74525e-11L ) * kilogram / pascal / second / square( meter ) };
constexpr quantity< illuminance_d > phot { Rep( 1e+4L ) * lux };
constexpr quantity< length_d > pica_computer { Rep( 4.233333e-3L ) * meter };
constexpr quantity< length_d > pica_printers { Rep( 4.217518e-3L ) * meter };
constexpr quantity< volume_d > pint_dry { Rep( 5.506105e-4L ) * cube( meter ) };
constexpr quantity< volume_d > pint_liquid { Rep( 4.731765e-4L ) * cube( meter ) };
constexpr quantity< length_d > point_computer { Rep( 3.527778e-4L ) * meter };
constexpr quantity< length_d > point_printers { Rep( 3.514598e-4L ) * meter };
constexpr quantity< dynamic_viscosity_d > poise { Rep( 1e-1L ) * pascal * second };
constexpr quantity< mass_d > pound_avdp { Rep( 4.5359237e-1L ) * kilogram };
constexpr quantity< force_d > pound_force { Rep( 4.448222L ) * newton };
constexpr quantity< mass_d > pound_troy { Rep( 3.732417e-1L ) * kilogram };
constexpr quantity< force_d > poundal { Rep( 1.382550e-1L ) * newton };
constexpr quantity< pressure_d > psi { Rep( 6.894757e+3L ) * pascal };
constexpr quantity< energy_d > quad { Rep( 1e+15L ) * btu_it };
constexpr quantity< volume_d > quart_dry { Rep( 1.101221e-3L ) * cube( meter ) };
constexpr quantity< volume_d > quart_liquid { Rep( 9.463529e-4L ) * cube( meter ) };
constexpr Rep revolution { Rep( 2 ) * pi };
constexpr quantity< dimensions< 1, -1, 1 > > rhe { Rep( 1e+1L ) / pascal / second };
constexpr quantity< length_d > rod { Rep( 5.029210L ) * meter };
constexpr quantity< angular_velocity_d > rpm { Rep( 1.047198e-1L ) / second };
constexpr quantity< time_interval_d > second_sidereal { Rep( 9.972696e-1L ) * second };
constexpr quantity< time_interval_d > shake { Rep( 1e-8L ) * second };
constexpr quantity< mass_d > slug { Rep( 1.459390e+1L ) * kilogram };
constexpr quantity< electric_current_d > statampere { Rep( 3.335641e-10L ) * ampere };
constexpr quantity< electric_charge_d > statcoulomb { Rep( 3.335641e-10L ) * coulomb };
constexpr quantity< capacitance_d > statfarad { Rep( 1.112650e-12L ) * farad };
constexpr quantity< inductance_d > stathenry { Rep( 8.987552e+11L ) * henry };
constexpr quantity< electric_conductance_d > statmho { Rep( 1.112650e-12L ) * siemens };
constexpr quantity< electric_resistance_d > statohm { Rep( 8.987552e+11L ) * ohm };
constexpr quantity< electric_potential_d > statvolt { Rep( 2.997925e+2L ) * volt };
constexpr quantity< volume_d > stere { cube( meter ) };
constexpr quantity< illuminance_d > stilb { Rep( 1e+4L ) * candela / square( meter ) };
constexpr quantity< kinematic_viscosity_d > stokes { Rep( 1e-4L ) * square( meter ) / second };
constexpr quantity< volume_d > tablespoon { Rep( 1.478676e-5L ) * cube( meter ) };
constexpr quantity< volume_d > teaspoon { Rep( 4.928922e-6L ) * cube( meter ) };
constexpr quantity< dimensions< -1, 1, 0 > > tex { Rep( 1e-6L ) * kilogram / meter };
constexpr quantity< energy_d > therm_ec { Rep( 1.05506e+8L ) * joule };
constexpr quantity< energy_d > therm_us { Rep( 1.054804e+8L ) * joule };
constexpr quantity< mass_d > ton_assay { Rep( 2.916667e-2L ) * kilogram };
constexpr quantity< force_d > ton_force { Rep( 8.896443e+3L ) * newton };
constexpr quantity< mass_d > ton_long { Rep( 1.016047e+3L ) * kilogram };
constexpr quantity< heat_flow_rate_d > ton_refrigeration { Rep( 3.516853e+3L ) * watt };
constexpr quantity< volume_d > ton_register { Rep( 2.831685L ) * cube( meter ) };
constexpr quantity< mass_d > ton_short { Rep( 9.071847e+2L ) * kilogram };
constexpr quantity< energy_d > ton_tnt { Rep( 4.184e+9L ) * joule };
constexpr quantity< pressure_d > torr { Rep( 1.333224e+2L ) * pascal };
constexpr quantity< magnetic_flux_d > unit_pole { Rep( 1.256637e-7L ) * weber };
constexpr quantity< time_interval_d > week { Rep( 604800L ) * second }; // 7 days
constexpr quantity< length_d > x_unit { Rep( 1.002e-13L ) * meter };
constexpr quantity< length_d > yard { Rep( 9.144e-1L ) * meter };
constexpr quantity< time_interval_d > year_sidereal { Rep( 3.155815e+7L ) * second };
constexpr quantity< time_interval_d > year_std { Rep( 3.1536e+7L ) * second }; // 365 days
constexpr quantity< time_interval_d > year_tropical { Rep( 3.155693e+7L ) * second };
}} // namespace phys::units
#endif // PHYS_UNITS_OTHER_UNITS_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity.hpp
*
* \brief Zero-overhead dimensional analysis and unit/quantity manipulation and conversion.
* \author Michael S. Kenniston, Martin Moene
* \date 7 September 2013
* \since 0.4
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
*
* Copyright (c) 2001 by Michael S. Kenniston. For the most
* recent version check www.xnet.com/~msk/quantity. Permission is granted
* to use this code without restriction so long as this copyright
* notice appears in all source files.
*
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* Unless otherwise specified, the definitions of all units in this
* file are from NIST Special Publication 811, found online at
* http://physics.nist.gov/Document/sp811.pdf
* Other sources: OED = Oxford English Dictionary
*/
#ifndef PHYS_UNITS_QUANTITY_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_HPP_INCLUDED
#include <cmath>
#include <cstdlib>
#include <utility> // std::declval
/// namespace phys.
namespace phys {
/// namespace units.
namespace units {
#ifdef PHYS_UNITS_REP_TYPE
using Rep = PHYS_UNITS_REP_TYPE;
#else
using Rep = double;
#endif
/*
* declare now, define later.
*/
template< typename Dims, typename T = Rep >
class quantity;
/**
* We could drag dimensions around individually, but it's much more convenient to package them.
*/
template< int D1, int D2, int D3, int D4 = 0, int D5 = 0, int D6 = 0, int D7 = 0 >
struct dimensions
{
enum
{
dim1 = D1,
dim2 = D2,
dim3 = D3,
dim4 = D4,
dim5 = D5,
dim6 = D6,
dim7 = D7,
is_all_zero =
D1 == 0 && D2 == 0 && D3 == 0 && D4 == 0 && D5 == 0 && D6 == 0 && D7 == 0,
is_base =
1 == (D1 != 0) + (D2 != 0) + (D3 != 0) + (D4 != 0) + (D5 != 0) + (D6 != 0) + (D7 != 0) &&
1 == D1 + D2 + D3 + D4 + D5 + D6 + D7,
};
template< int R1, int R2, int R3, int R4, int R5, int R6, int R7 >
constexpr bool operator==( dimensions<R1, R2, R3, R4, R5, R6, R7> const & ) const
{
return D1==R1 && D2==R2 && D3==R3 && D4==R4 && D5==R5 && D6==R6 && D7==R7;
}
template< int R1, int R2, int R3, int R4, int R5, int R6, int R7 >
constexpr bool operator!=( dimensions<R1, R2, R3, R4, R5, R6, R7> const & rhs ) const
{
return !( *this == rhs );
}
};
/// demensionless 'dimension'.
typedef dimensions< 0, 0, 0 > dimensionless_d;
/// namespace detail.
namespace detail {
/**
* \brief The "collapse" template is used to avoid quantity< dimensions< 0, 0, 0 > >,
* i.e. to make dimensionless results come out as type "Rep".
*/
template< typename D, typename T >
struct collapse
{
typedef quantity< D, T > type;
};
template< typename T >
struct collapse< dimensionless_d, T >
{
typedef T type;
};
template< typename D, typename T >
using Collapse = typename collapse<D,T>::type;
// promote types of expression to result type.
template < typename X, typename Y >
using PromoteAdd = decltype( std::declval<X>() + std::declval<Y>() );
template < typename X, typename Y >
using PromoteMul = decltype( std::declval<X>() * std::declval<Y>() );
/*
* The following batch of structs are type generators to calculate
* the correct type of the result of various operations.
*/
/**
* product type generator.
*/
template< typename DX, typename DY, typename T >
struct product
{
enum
{
d1 = DX::dim1 + DY::dim1,
d2 = DX::dim2 + DY::dim2,
d3 = DX::dim3 + DY::dim3,
d4 = DX::dim4 + DY::dim4,
d5 = DX::dim5 + DY::dim5,
d6 = DX::dim6 + DY::dim6,
d7 = DX::dim7 + DY::dim7,
};
typedef Collapse< dimensions< d1, d2, d3, d4, d5, d6, d7 >, T > type;
};
template< typename DX, typename DY, typename X, typename Y>
using Product = typename product<DX, DY, PromoteMul<X,Y>>::type;
/**
* quotient type generator.
*/
template< typename DX, typename DY, typename T >
struct quotient
{
enum
{
d1 = DX::dim1 - DY::dim1,
d2 = DX::dim2 - DY::dim2,
d3 = DX::dim3 - DY::dim3,
d4 = DX::dim4 - DY::dim4,
d5 = DX::dim5 - DY::dim5,
d6 = DX::dim6 - DY::dim6,
d7 = DX::dim7 - DY::dim7,
};
typedef Collapse< dimensions< d1, d2, d3, d4, d5, d6, d7 >, T > type;
};
template< typename DX, typename DY, typename X, typename Y>
using Quotient = typename quotient<DX, DY, PromoteMul<X,Y>>::type;
/**
* reciprocal type generator.
*/
template< typename D, typename T >
struct reciprocal
{
enum
{
d1 = - D::dim1,
d2 = - D::dim2,
d3 = - D::dim3,
d4 = - D::dim4,
d5 = - D::dim5,
d6 = - D::dim6,
d7 = - D::dim7,
};
typedef Collapse< dimensions< d1, d2, d3, d4, d5, d6, d7 >, T > type;
};
template< typename D, typename X, typename Y>
using Reciprocal = typename reciprocal<D, PromoteMul<X,Y>>::type;
/**
* power type generator.
*/
template< typename D, int N, typename T >
struct power
{
enum
{
d1 = N * D::dim1,
d2 = N * D::dim2,
d3 = N * D::dim3,
d4 = N * D::dim4,
d5 = N * D::dim5,
d6 = N * D::dim6,
d7 = N * D::dim7,
};
typedef Collapse< dimensions< d1, d2, d3, d4, d5, d6, d7 >, T > type;
};
template< typename D, int N, typename T >
using Power = typename detail::power< D, N, T >::type;
/**
* root type generator.
*/
template< typename D, int N, typename T >
struct root
{
enum
{
all_even_multiples =
D::dim1 % N == 0 &&
D::dim2 % N == 0 &&
D::dim3 % N == 0 &&
D::dim4 % N == 0 &&
D::dim5 % N == 0 &&
D::dim6 % N == 0 &&
D::dim7 % N == 0
};
enum
{
d1 = D::dim1 / N,
d2 = D::dim2 / N,
d3 = D::dim3 / N,
d4 = D::dim4 / N,
d5 = D::dim5 / N,
d6 = D::dim6 / N,
d7 = D::dim7 / N
};
typedef Collapse< dimensions< d1, d2, d3, d4, d5, d6, d7 >, T > type;
};
template< typename D, int N, typename T >
using Root = typename detail::root< D, N, T >::type;
/**
* tag to construct a quantity from a magnitude.
*/
constexpr struct magnitude_tag_t{} magnitude_tag{};
} // namespace detail
/**
* \brief class "quantity" is the heart of the library. It associates
* dimensions with a single "Rep" data member and protects it from
* dimensionally inconsistent use.
*/
template< typename Dims, typename T /*= Rep */ >
class quantity
{
public:
typedef Dims dimension_type;
typedef T value_type;
typedef quantity<Dims, T> this_type;
constexpr quantity() : m_value{} { }
/**
* public converting initializing constructor;
* requires magnitude_tag to prevent constructing a quantity from a raw magnitude.
*/
template <typename X>
constexpr explicit quantity( detail::magnitude_tag_t, X x )
: m_value( x ) { }
/**
* converting copy-assignment constructor.
*/
template <typename X >
constexpr quantity( quantity<Dims, X> const & x )
: m_value( x.magnitude() ) { }
// /**
// * convert to compatible unit, for example: (3._dm).to(meter) gives 0.3;
// */
// constexpr value_type to( quantity const & x ) const { return *this / x; }
/**
* convert to given unit, for example: (3._dm).to(meter) gives 0.3;
*/
template <typename DX, typename X>
constexpr auto to( quantity<DX,X> const & x ) const -> detail::Quotient<Dims,DX,T,X>
{
return *this / x;
}
/**
* the quantity's magnitude.
*/
constexpr value_type magnitude() const { return m_value; }
/**
* the quantity's dimensions.
*/
constexpr dimension_type dimension() const { return dimension_type{}; }
/**
* We need a "zero" of each type -- for comparisons, to initialize running
* totals, etc. Note: 0 m != 0 kg, since they are of different dimensionality.
* zero is really just defined for convenience, since
* quantity< length_d >::zero == 0 * meter, etc.
*/
static constexpr quantity zero() { return quantity{ value_type( 0.0 ) }; }
// static constexpr quantity zero = quantity{ value_type( 0.0 ) };
private:
/**
* private initializing constructor.
*/
constexpr explicit quantity( value_type x ) : m_value{ x } { }
private:
value_type m_value;
enum { has_dimension = ! Dims::is_all_zero };
static_assert( has_dimension, "quantity dimensions must not all be zero" );
private:
// friends:
// arithmetic
template <typename D, typename X, typename Y>
friend constexpr quantity<D, X> &
operator+=( quantity<D, X> & x, quantity<D, Y> const & y );
template <typename D, typename X>
friend constexpr quantity<D, X>
operator+( quantity<D, X> const & x );
template< typename D, typename X, typename Y >
friend constexpr quantity <D, detail::PromoteAdd<X,Y>>
operator+( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr quantity<D, X> &
operator-=( quantity<D, X> & x, quantity<D, Y> const & y );
template <typename D, typename X>
friend constexpr quantity<D, X>
operator-( quantity<D, X> const & x );
template< typename D, typename X, typename Y >
friend constexpr quantity <D, detail::PromoteAdd<X,Y>>
operator-( quantity<D, X> const & x, quantity<D, Y> const & y );
template< typename D, typename X, typename Y>
friend constexpr quantity<D, X> &
operator*=( quantity<D, X> & x, const Y & y );
template <typename D, typename X, typename Y>
friend constexpr quantity<D, detail::PromoteMul<X,Y>>
operator*( quantity<D, X> const & x, const Y & y );
template <typename D, typename X, typename Y>
friend constexpr quantity< D, detail::PromoteMul<X,Y> >
operator*( const X & x, quantity<D, Y> const & y );
template <typename DX, typename DY, typename X, typename Y>
friend constexpr detail::Product<DX, DY, X, Y>
operator*( quantity<DX, X> const & lhs, quantity< DY, Y > const & rhs );
template< typename D, typename X, typename Y>
friend constexpr quantity<D, X> &
operator/=( quantity<D, X> & x, const Y & y );
template <typename D, typename X, typename Y>
friend constexpr quantity<D, detail::PromoteMul<X,Y>>
operator/( quantity<D, X> const & x, const Y & y );
template <typename D, typename X, typename Y>
friend constexpr detail::Reciprocal<D, X, Y>
operator/( const X & x, quantity<D, Y> const & y );
template <typename DX, typename DY, typename X, typename Y>
friend constexpr detail::Quotient<DX, DY, X, Y>
operator/( quantity<DX, X> const & x, quantity< DY, Y > const & y );
// absolute value.
template <typename D, typename X>
friend constexpr quantity<D,X>
abs( quantity<D,X> const & x );
// powers and roots
template <int N, typename D, typename X>
friend detail::Power<D, N, X>
nth_power( quantity<D, X> const & x );
template <typename D, typename X>
friend constexpr detail::Power<D, 2, X>
square( quantity<D, X> const & x );
template <typename D, typename X>
friend constexpr detail::Power<D, 3, X>
cube( quantity<D, X> const & x );
template <int N, typename D, typename X>
friend detail::Root<D, N, X>
nth_root( quantity<D, X> const & x );
template <typename D, typename X>
friend detail::Root< D, 2, X >
sqrt( quantity<D, X> const & x );
// comparison
template <typename D, typename X, typename Y>
friend constexpr bool operator==( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr bool operator!=( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr bool operator<( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr bool operator<=( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr bool operator>( quantity<D, X> const & x, quantity<D, Y> const & y );
template <typename D, typename X, typename Y>
friend constexpr bool operator>=( quantity<D, X> const & x, quantity<D, Y> const & y );
};
// Give names to the seven fundamental dimensions of physical reality.
typedef dimensions< 1, 0, 0, 0, 0, 0, 0 > length_d;
typedef dimensions< 0, 1, 0, 0, 0, 0, 0 > mass_d;
typedef dimensions< 0, 0, 1, 0, 0, 0, 0 > time_interval_d;
typedef dimensions< 0, 0, 0, 1, 0, 0, 0 > electric_current_d;
typedef dimensions< 0, 0, 0, 0, 1, 0, 0 > thermodynamic_temperature_d;
typedef dimensions< 0, 0, 0, 0, 0, 1, 0 > amount_of_substance_d;
typedef dimensions< 0, 0, 0, 0, 0, 0, 1 > luminous_intensity_d;
// Addition operators
/// quan += quan
template <typename D, typename X, typename Y>
constexpr quantity<D, X> &
operator+=( quantity<D, X> & x, quantity<D, Y> const & y )
{
return x.m_value += y.m_value, x;
}
/// + quan
template <typename D, typename X>
constexpr quantity<D, X>
operator+( quantity<D, X> const & x )
{
return quantity<D, X >( +x.m_value );
}
/// quan + quan
template< typename D, typename X, typename Y >
constexpr quantity <D, detail::PromoteAdd<X,Y>>
operator+( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return quantity<D, detail::PromoteAdd<X,Y>>( x.m_value + y.m_value );
}
// Subtraction operators
/// quan -= quan
template <typename D, typename X, typename Y>
constexpr quantity<D, X> &
operator-=( quantity<D, X> & x, quantity<D, Y> const & y )
{
return x.m_value -= y.m_value, x;
}
/// - quan
template <typename D, typename X>
constexpr quantity<D, X>
operator-( quantity<D, X> const & x )
{
return quantity<D, X >( -x.m_value );
}
/// quan - quan
template< typename D, typename X, typename Y >
constexpr quantity <D, detail::PromoteAdd<X,Y>>
operator-( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return quantity<D, detail::PromoteAdd<X,Y>>( x.m_value - y.m_value );
}
// Multiplication operators
/// quan *= num
template< typename D, typename X, typename Y>
constexpr quantity<D, X> &
operator*=( quantity<D, X> & x, const Y & y )
{
return x.m_value *= y, x;
}
/// quan * num
template <typename D, typename X, typename Y>
constexpr quantity<D, detail::PromoteMul<X,Y>>
operator*( quantity<D, X> const & x, const Y & y )
{
return quantity<D, detail::PromoteMul<X,Y>>( x.m_value * y );
}
/// num * quan
template <typename D, typename X, typename Y>
constexpr quantity< D, detail::PromoteMul<X,Y> >
operator*( const X & x, quantity<D, Y> const & y )
{
return quantity<D, detail::PromoteMul<X,Y>>( x * y.m_value );
}
/// quan * quan:
template <typename DX, typename DY, typename X, typename Y>
constexpr detail::Product<DX, DY, X, Y>
operator*( quantity<DX, X> const & lhs, quantity< DY, Y > const & rhs )
{
return detail::Product<DX, DY, X, Y>( lhs.m_value * rhs.m_value );
}
// Division operators
/// quan /= num
template< typename D, typename X, typename Y>
constexpr quantity<D, X> &
operator/=( quantity<D, X> & x, const Y & y )
{
return x.m_value /= y, x;
}
/// quan / num
template <typename D, typename X, typename Y>
constexpr quantity<D, detail::PromoteMul<X,Y>>
operator/( quantity<D, X> const & x, const Y & y )
{
return quantity<D, detail::PromoteMul<X,Y>>( x.m_value / y );
}
/// num / quan
template <typename D, typename X, typename Y>
constexpr detail::Reciprocal<D, X, Y>
operator/( const X & x, quantity<D, Y> const & y )
{
return detail::Reciprocal<D, X, Y>( x / y.m_value );
}
/// quan / quan:
template <typename DX, typename DY, typename X, typename Y>
constexpr detail::Quotient<DX, DY, X, Y>
operator/( quantity<DX, X> const & x, quantity< DY, Y > const & y )
{
return detail::Quotient<DX, DY, X, Y>( x.m_value / y.m_value );
}
/// absolute value.
template <typename D, typename X>
constexpr quantity<D,X> abs( quantity<D,X> const & x )
{
return quantity<D,X>( std::abs( x.m_value ) );
}
// General powers
/// N-th power.
template <int N, typename D, typename X>
detail::Power<D, N, X>
nth_power( quantity<D, X> const & x )
{
return detail::Power<D, N, X>( std::pow( x.m_value, X( N ) ) );
}
// Low powers defined separately for efficiency.
/// square.
template <typename D, typename X>
constexpr detail::Power<D, 2, X>
square( quantity<D, X> const & x )
{
return x * x;
}
/// cube.
template <typename D, typename X>
constexpr detail::Power<D, 3, X>
cube( quantity<D, X> const & x )
{
return x * x * x;
}
// General root
/// n-th root.
template <int N, typename D, typename X>
detail::Root<D, N, X>
nth_root( quantity<D, X> const & x )
{
static_assert( detail::root<D, N, X>::all_even_multiples, "root result dimensions must be integral" );
return detail::Root<D, N, X>( std::pow( x.m_value, X( 1.0 ) / N ) );
}
// Low roots defined separately for convenience.
/// square root.
template <typename D, typename X>
detail::Root< D, 2, X >
sqrt( quantity<D, X> const & x )
{
static_assert(
detail::root<D, 2, X >::all_even_multiples, "root result dimensions must be integral" );
return detail::Root<D, 2, X>( std::pow( x.m_value, X( 1.0 ) / 2 ) );
}
// Comparison operators
/// equality.
template <typename D, typename X, typename Y>
constexpr bool
operator==( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value == y.m_value;
}
/// inequality.
template <typename D, typename X, typename Y>
constexpr bool
operator!=( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value != y.m_value;
}
/// less-than.
template <typename D, typename X, typename Y>
constexpr bool
operator<( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value < y.m_value;
}
/// less-equal.
template <typename D, typename X, typename Y>
constexpr bool
operator<=( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value <= y.m_value;
}
/// greater-than.
template <typename D, typename X, typename Y>
constexpr bool
operator>( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value > y.m_value;
}
/// greater-equal.
template <typename D, typename X, typename Y>
constexpr bool
operator>=( quantity<D, X> const & x, quantity<D, Y> const & y )
{
return x.m_value >= y.m_value;
}
/// quantity's dimension.
template <typename DX, typename X>
inline constexpr DX dimension( quantity<DX,X> const & q ) { return q.dimension(); }
/// quantity's magnitude.
template <typename DX, typename X>
inline constexpr X magnitude( quantity<DX,X> const & q ) { return q.magnitude(); }
// The seven SI base units. These tie our numbers to the real world.
constexpr quantity<length_d > meter { detail::magnitude_tag, 1.0 };
constexpr quantity<mass_d > kilogram{ detail::magnitude_tag, 1.0 };
constexpr quantity<time_interval_d > second { detail::magnitude_tag, 1.0 };
constexpr quantity<electric_current_d > ampere { detail::magnitude_tag, 1.0 };
constexpr quantity<thermodynamic_temperature_d> kelvin { detail::magnitude_tag, 1.0 };
constexpr quantity<amount_of_substance_d > mole { detail::magnitude_tag, 1.0 };
constexpr quantity<luminous_intensity_d > candela { detail::magnitude_tag, 1.0 };
// The standard SI prefixes.
constexpr long double yotta = 1e+24L;
constexpr long double zetta = 1e+21L;
constexpr long double exa = 1e+18L;
constexpr long double peta = 1e+15L;
constexpr long double tera = 1e+12L;
constexpr long double giga = 1e+9L;
constexpr long double mega = 1e+6L;
constexpr long double kilo = 1e+3L;
constexpr long double hecto = 1e+2L;
constexpr long double deka = 1e+1L;
constexpr long double deci = 1e-1L;
constexpr long double centi = 1e-2L;
constexpr long double milli = 1e-3L;
constexpr long double micro = 1e-6L;
constexpr long double nano = 1e-9L;
constexpr long double pico = 1e-12L;
constexpr long double femto = 1e-15L;
constexpr long double atto = 1e-18L;
constexpr long double zepto = 1e-21L;
constexpr long double yocto = 1e-24L;
// Binary prefixes, pending adoption.
constexpr long double kibi = 1024;
constexpr long double mebi = 1024 * kibi;
constexpr long double gibi = 1024 * mebi;
constexpr long double tebi = 1024 * gibi;
constexpr long double pebi = 1024 * tebi;
constexpr long double exbi = 1024 * pebi;
constexpr long double zebi = 1024 * exbi;
constexpr long double yobi = 1024 * zebi;
// The rest of the standard dimensional types, as specified in SP811.
using absorbed_dose_d = dimensions< 2, 0, -2 >;
using absorbed_dose_rate_d = dimensions< 2, 0, -3 >;
using acceleration_d = dimensions< 1, 0, -2 >;
using activity_of_a_nuclide_d = dimensions< 0, 0, -1 >;
using angular_velocity_d = dimensions< 0, 0, -1 >;
using angular_acceleration_d = dimensions< 0, 0, -2 >;
using area_d = dimensions< 2, 0, 0 >;
using capacitance_d = dimensions< -2, -1, 4, 2 >;
using concentration_d = dimensions< -3, 0, 0, 0, 0, 1 >;
using current_density_d = dimensions< -2, 0, 0, 1 >;
using dose_equivalent_d = dimensions< 2, 0, -2 >;
using dynamic_viscosity_d = dimensions< -1, 1, -1 >;
using electric_charge_d = dimensions< 0, 0, 1, 1 >;
using electric_charge_density_d = dimensions< -3, 0, 1, 1 >;
using electric_conductance_d = dimensions< -2, -1, 3, 2 >;
using electric_field_strenth_d = dimensions< 1, 1, -3, -1 >;
using electric_flux_density_d = dimensions< -2, 0, 1, 1 >;
using electric_potential_d = dimensions< 2, 1, -3, -1 >;
using electric_resistance_d = dimensions< 2, 1, -3, -2 >;
using energy_d = dimensions< 2, 1, -2 >;
using energy_density_d = dimensions< -1, 1, -2 >;
using exposure_d = dimensions< 0, -1, 1, 1 >;
using force_d = dimensions< 1, 1, -2 >;
using frequency_d = dimensions< 0, 0, -1 >;
using heat_capacity_d = dimensions< 2, 1, -2, 0, -1 >;
using heat_density_d = dimensions< 0, 1, -2 >;
using heat_density_flow_rate_d = dimensions< 0, 1, -3 >;
using heat_flow_rate_d = dimensions< 2, 1, -3 >;
using heat_flux_density_d = dimensions< 0, 1, -3 >;
using heat_transfer_coefficient_d = dimensions< 0, 1, -3, 0, -1 >;
using illuminance_d = dimensions< -2, 0, 0, 0, 0, 0, 1 >;
using inductance_d = dimensions< 2, 1, -2, -2 >;
using irradiance_d = dimensions< 0, 1, -3 >;
using kinematic_viscosity_d = dimensions< 2, 0, -1 >;
using luminance_d = dimensions< -2, 0, 0, 0, 0, 0, 1 >;
using luminous_flux_d = dimensions< 0, 0, 0, 0, 0, 0, 1 >;
using magnetic_field_strength_d = dimensions< -1, 0, 0, 1 >;
using magnetic_flux_d = dimensions< 2, 1, -2, -1 >;
using magnetic_flux_density_d = dimensions< 0, 1, -2, -1 >;
using magnetic_permeability_d = dimensions< 1, 1, -2, -2 >;
using mass_density_d = dimensions< -3, 1, 0 >;
using mass_flow_rate_d = dimensions< 0, 1, -1 >;
using molar_energy_d = dimensions< 2, 1, -2, 0, 0, -1 >;
using molar_entropy_d = dimensions< 2, 1, -2, -1, 0, -1 >;
using moment_of_force_d = dimensions< 2, 1, -2 >;
using permittivity_d = dimensions< -3, -1, 4, 2 >;
using power_d = dimensions< 2, 1, -3 >;
using pressure_d = dimensions< -1, 1, -2 >;
using radiance_d = dimensions< 0, 1, -3 >;
using radiant_intensity_d = dimensions< 2, 1, -3 >;
using speed_d = dimensions< 1, 0, -1 >;
using specific_energy_d = dimensions< 2, 0, -2 >;
using specific_heat_capacity_d = dimensions< 2, 0, -2, 0, -1 >;
using specific_volume_d = dimensions< 3, -1, 0 >;
using substance_permeability_d = dimensions< -1, 0, 1 >;
using surface_tension_d = dimensions< 0, 1, -2 >;
using thermal_conductivity_d = dimensions< 1, 1, -3, 0, -1 >;
using thermal_diffusivity_d = dimensions< 2, 0, -1 >;
using thermal_insulance_d = dimensions< 0, -1, 3, 0, 1 >;
using thermal_resistance_d = dimensions< -2, -1, 3, 0, 1 >;
using thermal_resistivity_d = dimensions< -1, -1, 3, 0, 1 >;
using torque_d = dimensions< 2, 1, -2 >;
using volume_d = dimensions< 3, 0, 0 >;
using volume_flow_rate_d = dimensions< 3, 0, -1 >;
using wave_number_d = dimensions< -1, 0, 0 >;
// Handy values.
constexpr Rep pi { Rep( 3.141592653589793238462L ) };
constexpr Rep percent { Rep( 1 ) / 100 };
//// Not approved for use alone, but needed for use with prefixes.
constexpr quantity< mass_d > gram { kilogram / 1000 };
// The derived SI units, as specified in SP811.
constexpr Rep radian { Rep( 1 ) };
constexpr Rep steradian { Rep( 1 ) };
constexpr quantity< force_d > newton { meter * kilogram / square( second ) };
constexpr quantity< pressure_d > pascal { newton / square( meter ) };
constexpr quantity< energy_d > joule { newton * meter };
constexpr quantity< power_d > watt { joule / second };
constexpr quantity< electric_charge_d > coulomb { second * ampere };
constexpr quantity< electric_potential_d > volt { watt / ampere };
constexpr quantity< capacitance_d > farad { coulomb / volt };
constexpr quantity< electric_resistance_d > ohm { volt / ampere };
constexpr quantity< electric_conductance_d > siemens { ampere / volt };
constexpr quantity< magnetic_flux_d > weber { volt * second };
constexpr quantity< magnetic_flux_density_d > tesla { weber / square( meter ) };
constexpr quantity< inductance_d > henry { weber / ampere };
constexpr quantity< thermodynamic_temperature_d > degree_celsius { kelvin };
constexpr quantity< luminous_flux_d > lumen { candela * steradian };
constexpr quantity< illuminance_d > lux { lumen / meter / meter };
constexpr quantity< activity_of_a_nuclide_d > becquerel { 1 / second };
constexpr quantity< absorbed_dose_d > gray { joule / kilogram };
constexpr quantity< dose_equivalent_d > sievert { joule / kilogram };
constexpr quantity< frequency_d > hertz { 1 / second };
// The rest of the units approved for use with SI, as specified in SP811.
// (However, use of these units is generally discouraged.)
constexpr quantity< length_d > angstrom { Rep( 1e-10L ) * meter };
constexpr quantity< area_d > are { Rep( 1e+2L ) * square( meter ) };
constexpr quantity< pressure_d > bar { Rep( 1e+5L ) * pascal };
constexpr quantity< area_d > barn { Rep( 1e-28L ) * square( meter ) };
constexpr quantity< activity_of_a_nuclide_d > curie { Rep( 3.7e+10L ) * becquerel };
constexpr quantity< time_interval_d > day { Rep( 86400L ) * second };
constexpr Rep degree_angle { pi / 180 };
constexpr quantity< acceleration_d > gal { Rep( 1e-2L ) * meter / square( second ) };
constexpr quantity< area_d > hectare { Rep( 1e+4L ) * square( meter ) };
constexpr quantity< time_interval_d > hour { Rep( 3600 ) * second };
constexpr quantity< speed_d > knot { Rep( 1852 ) / 3600 * meter / second };
constexpr quantity< volume_d > liter { Rep( 1e-3L ) * cube( meter ) };
constexpr quantity< time_interval_d > minute { Rep( 60 ) * second };
constexpr Rep minute_angle { pi / 10800 };
constexpr quantity< length_d > mile_nautical{ Rep( 1852 ) * meter };
constexpr quantity< absorbed_dose_d > rad { Rep( 1e-2L ) * gray };
constexpr quantity< dose_equivalent_d > rem { Rep( 1e-2L ) * sievert };
constexpr quantity< exposure_d > roentgen { Rep( 2.58e-4L ) * coulomb / kilogram };
constexpr Rep second_angle { pi / 648000L };
constexpr quantity< mass_d > ton_metric { Rep( 1e+3L ) * kilogram };
// Alternate (non-US) spellings:
constexpr quantity< length_d > metre { meter };
constexpr quantity< volume_d > litre { liter };
constexpr Rep deca { deka };
constexpr quantity< mass_d > tonne { ton_metric };
// cooked literals for base units;
// these could also have been created with a script.
#define QUANTITY_DEFINE_SCALING_LITERAL( sfx, dim, factor ) \
constexpr quantity<dim, long double> operator "" _ ## sfx(unsigned long long x) \
{ \
return quantity<dim, long double>( detail::magnitude_tag, factor * x ); \
} \
constexpr quantity<dim, long double> operator "" _ ## sfx(long double x) \
{ \
return quantity<dim, long double>( detail::magnitude_tag, factor * x ); \
}
#define QUANTITY_DEFINE_SCALING_LITERALS( pfx, dim, fact ) \
QUANTITY_DEFINE_SCALING_LITERAL( Y ## pfx, dim, fact * yotta ) \
QUANTITY_DEFINE_SCALING_LITERAL( Z ## pfx, dim, fact * zetta ) \
QUANTITY_DEFINE_SCALING_LITERAL( E ## pfx, dim, fact * exa ) \
QUANTITY_DEFINE_SCALING_LITERAL( P ## pfx, dim, fact * peta ) \
QUANTITY_DEFINE_SCALING_LITERAL( T ## pfx, dim, fact * tera ) \
QUANTITY_DEFINE_SCALING_LITERAL( G ## pfx, dim, fact * giga ) \
QUANTITY_DEFINE_SCALING_LITERAL( M ## pfx, dim, fact * mega ) \
QUANTITY_DEFINE_SCALING_LITERAL( k ## pfx, dim, fact * kilo ) \
QUANTITY_DEFINE_SCALING_LITERAL( h ## pfx, dim, fact * hecto ) \
QUANTITY_DEFINE_SCALING_LITERAL( da## pfx, dim, fact * deka ) \
QUANTITY_DEFINE_SCALING_LITERAL( pfx, dim, fact * 1 ) \
QUANTITY_DEFINE_SCALING_LITERAL( d ## pfx, dim, fact * deci ) \
QUANTITY_DEFINE_SCALING_LITERAL( c ## pfx, dim, fact * centi ) \
QUANTITY_DEFINE_SCALING_LITERAL( m ## pfx, dim, fact * milli ) \
QUANTITY_DEFINE_SCALING_LITERAL( u ## pfx, dim, fact * micro ) \
QUANTITY_DEFINE_SCALING_LITERAL( n ## pfx, dim, fact * nano ) \
QUANTITY_DEFINE_SCALING_LITERAL( p ## pfx, dim, fact * pico ) \
QUANTITY_DEFINE_SCALING_LITERAL( f ## pfx, dim, fact * femto ) \
QUANTITY_DEFINE_SCALING_LITERAL( a ## pfx, dim, fact * atto ) \
QUANTITY_DEFINE_SCALING_LITERAL( z ## pfx, dim, fact * zepto ) \
QUANTITY_DEFINE_SCALING_LITERAL( y ## pfx, dim, fact * yocto )
#define QUANTITY_DEFINE_LITERALS( pfx, dim ) \
QUANTITY_DEFINE_SCALING_LITERALS( pfx, dim, 1 )
/// literals
namespace literals {
QUANTITY_DEFINE_SCALING_LITERALS( g, mass_d, 1e-3 )
QUANTITY_DEFINE_LITERALS( m , length_d )
QUANTITY_DEFINE_LITERALS( s , time_interval_d )
QUANTITY_DEFINE_LITERALS( A , electric_current_d )
QUANTITY_DEFINE_LITERALS( K , thermodynamic_temperature_d )
QUANTITY_DEFINE_LITERALS( mol, amount_of_substance_d )
QUANTITY_DEFINE_LITERALS( cd , luminous_intensity_d )
} // namespace literals
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io.hpp
*
* \brief IO for quantity library.
* \author Michael S. Kenniston, Martin Moene
* \date 10 September 2013
* \since 0.4
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
*
* Copyright (c) 2001 by Michael S. Kenniston. For the most
* recent version check www.xnet.com/~msk/quantity. Permission is granted
* to use this code without restriction so long as this copyright
* notice appears in all source files.
*
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_HPP_INCLUDED
#include "Units/units/quantity.hpp"
#include <algorithm>
#include <iosfwd>
#include <map>
#include <stdexcept>
#include <string>
#include <sstream>
/// namespace phys.
namespace phys {
/// namespace units.
namespace units {
/// quantity error base class (not used by quantity itself).
struct quantity_error : public std::runtime_error
{
quantity_error( std::string const text )
: std::runtime_error( text ) { }
};
/// prefix error, e.g. when prefix is unrecognized.
struct prefix_error : public quantity_error
{
prefix_error( std::string const text )
: quantity_error( text ) { }
};
/// return factor for given prefix.
inline Rep prefix( std::string const prefix_ )
{
std::map<std::string, Rep> table
{
{ "m", milli },
{ "k", kilo },
{ "u", micro },
{ "M", mega },
{ "n", nano },
{ "G", giga },
{ "p", pico },
{ "T", tera },
{ "f", femto },
{ "P", peta },
{ "a", atto },
{ "E", exa },
{ "z", zepto },
{ "Z", zetta },
{ "y", yocto },
{ "Y", yotta },
{ "h", hecto },
{ "da", deka },
{ "d", deci },
{ "c", centi },
};
auto pos = table.find( prefix_ );
if ( pos == table.end() )
{
throw prefix_error( "quantity: unrecognized prefix '" + prefix_ + "'" );
}
return pos->second;
}
/**
* Provide SI units-and-exponents in as close to NIST-specified format as possible with plain ascii.
*
* Made presentation customizable by specialization of template.
* Adapted by Martin Moene, 21 February 2012.
*/
template <typename Dims>
struct unit_info
{
/// true if base dimension.
static bool single()
{
return Dims::is_base;
}
/// provide unit's name.
static std::string name()
{
return symbol();
}
/// provide unit's symbol.
static std::string symbol()
{
std::ostringstream os;
bool first = true;
emit_dim( os, "m", Dims::dim1, first );
emit_dim( os, "kg", Dims::dim2, first );
emit_dim( os, "s", Dims::dim3, first );
emit_dim( os, "A", Dims::dim4, first );
emit_dim( os, "K", Dims::dim5, first );
emit_dim( os, "mol", Dims::dim6, first );
emit_dim( os, "cd", Dims::dim7, first );
return os.str();
}
/// emit a single dimension.
static void emit_dim( std::ostream & os, const char * label, int exp, bool & first )
{
if( exp == 0 )
return;
if ( first )
first = false;
else
os << " ";
os << label;
if( exp > 1 )
os << "+";
if( exp != 1 )
os << exp;
}
};
}} // namespace phys::units
#include "quantity_io_meter.hpp"
#include "quantity_io_kilogram.hpp"
#include "quantity_io_second.hpp"
#include "quantity_io_ampere.hpp"
#include "quantity_io_mole.hpp"
#include "quantity_io_candela.hpp"
/*
* User must choose celsius or kelvin, either by defining
* QUANTITY_USE_CELSIUS or QUANTITY_USE_KELVIN, or by
* including the desired include file.
*/
#if defined(QUANTITY_USE_CELSIUS) && defined(QUANTITY_USE_KELVIN)
# error At most define one of QUANTITY_USE_CELSIUS, QUANTITY_USE_KELVIN
#endif
#ifdef QUANTITY_USE_CELSIUS
# include "quantity_io_celsius.hpp"
#endif
#ifdef QUANTITY_USE_KELVIN
# include "quantity_io_kelvin.hpp"
#endif
namespace phys { namespace units {
/// magnitude as string.
template< typename Dims, typename T >
std::string to_magnitude( quantity<Dims, T> const & q )
{
std::ostringstream os;
os << q.magnitude();
return os.str();
}
/// unit name.
template< typename Dims, typename T >
std::string to_unit_name( quantity<Dims, T> const & /* q */)
{
return unit_info<Dims>::name();
}
/// unit symbol.
template< typename Dims, typename T >
std::string to_unit_symbol( quantity<Dims, T> const & /* q */)
{
return unit_info<Dims>::symbol();
}
/// string representation of value.
inline std::string to_string( long double const value )
{
std::ostringstream os;
os << value;
return os.str();
}
/// namespace io.
namespace io {
/// stream quantity.
template< typename Dims, typename T >
std::ostream & operator<<( std::ostream & os, quantity<Dims, T> const & q )
{
return os << q.magnitude() << " " << to_unit_symbol( q );
}
/// quantity string representation.
template< typename Dims, typename T >
std::string to_string( quantity<Dims, T> const & q )
{
std::ostringstream os;
os << q;
return os.str();
}
} // namespace io
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_ampere.hpp
*
* \brief ampere, electrical current, a fundamental dimension.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_AMPERE_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_AMPERE_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/// electric_current_d
template<>
struct unit_info< electric_current_d >
{
static bool single() { return true; }
static std::string name() { return "ampere"; }
static std::string symbol() { return "A"; }
};
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_AMPERE_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_becquerel.hpp
*
* \brief becquerel, activity_of_a_nuclide_d
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_BECQUEREL_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_BECQUEREL_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/**
* becquerel, [Bq].
*/
template<>
struct unit_info< activity_of_a_nuclide_d >
{
static bool single() { return true; }
static std::string name() { return "becquerel"; }
static std::string symbol() { return "Bq"; }
};
namespace literals {
QUANTITY_DEFINE_LITERALS( Bq, activity_of_a_nuclide_d )
}
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_BECQUEREL_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_candela.hpp
*
* \brief candela, fundamental dimension.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_CANDELA_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_CANDELA_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/// luminous_intensity_d
template<>
struct unit_info< luminous_intensity_d >
{
static bool single() { return true; }
static std::string name() { return "candela"; }
static std::string symbol() { return "cd"; }
};
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_CANDELA_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_celsius.hpp
*
* \brief celsius, thermodynamic temperature.
* \author Martin Moene
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_CELSIUS_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_CELSIUS_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/**
* celsius, [C].
*/
template<>
struct unit_info< thermodynamic_temperature_d >
{
static bool single() { return true; }
static std::string name() { return "celsius"; }
static std::string symbol() { return "C"; }
};
namespace literals {
QUANTITY_DEFINE_LITERALS( oC, thermodynamic_temperature_d )
}
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_CELSIUS_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_coulomb.hpp
*
* \brief coulomb, electrical power.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_COULOMB_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_COULOMB_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/**
* coulomb, [C].
*/
template<>
struct unit_info< electric_charge_d >
{
static bool single() { return true; }
static std::string name() { return "coulomb"; }
static std::string symbol() { return "C"; }
};
namespace literals {
QUANTITY_DEFINE_LITERALS( C, electric_charge_d )
}
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_COULOMB_HPP_INCLUDED
/*
* end of file
*/
/**
* \file quantity_io_dimensionless.hpp
*
* \brief dimensionless.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_DIMENSIONLESS_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_DIMENSIONLESS_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
namespace phys { namespace units {
/**
* (dimensionless), [].
*/
template<>
struct unit_info< dimensionless_d >
{
static bool single() { return true; }
static std::string name() { return "(dimensionless)"; }
static std::string symbol() { return "[]"; }
};
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_DIMENSIONLESS_HPP_INCLUDED
/*
* end of file
*/
/**
* \file io_output_engineering.hpp
*
* \brief Engineering IO for quantity library.
* \author Martin Moene
* \date 7 September 2013
* \since 1.0
*
* Copyright 2013 Universiteit Leiden. All rights reserved.
*
* Based on the following question and answer on StackOverflow:
* Convert float number to string with engineering notation (with SI prefixe) in Python [closed].
* Asked by working4coins, http://stackoverflow.com/users/2051311/working4coins
* Answered by scls, http://stackoverflow.com/users/1609077/scls
* http://stackoverflow.com/questions/15733772/convert-float-number-to-string-with-engineering-notation-with-si-prefixe-in-py
*
* This code is provided as-is, with no warrantee of correctness.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef PHYS_UNITS_QUANTITY_IO_ENGINEERING_HPP_INCLUDED
#define PHYS_UNITS_QUANTITY_IO_ENGINEERING_HPP_INCLUDED
#include "Units/units/quantity_io.hpp"
#include <cmath>
#include <iomanip>
#include <limits>
#include <sstream>
/*
* Note: micro, , may not work everywhere, so you can define a glyph yourself:
*/
#ifndef ENG_FORMAT_MICRO_GLYPH
# define ENG_FORMAT_MICRO_GLYPH "u"
#endif
/// namespace phys.
namespace phys {
/// namespace units.
namespace units {
/// namespace detail.
namespace detail {
char const * const prefixes[/*exp*/][2][9] =
{
{
{ "", "m", ENG_FORMAT_MICRO_GLYPH
, "n", "p", "f", "a", "z", "y", },
{ "", "k", "M", "G", "T", "P", "E", "Z", "Y", },
},
{
{ "e0", "e-3", "e-6", "e-9", "e-12", "e-15", "e-18", "e-21", "e-24", },
{ "e0", "e3", "e6", "e9", "e12", "e15", "e18", "e21", "e24", },
},
};
template<typename T, size_t N>
constexpr size_t dimenson_of( T(&)[N] )
{
return N;
}
constexpr int prefix_count = dimenson_of( prefixes[false][false] );
inline int sign( int const value )
{
return value == 0 ? +1 : value / std::abs( value );
}
inline bool iszero( double const value )
{
return FP_ZERO == std::fpclassify( value );
}
inline long degree_of( double const value )
{
return iszero( value ) ? 0 : std::lrint( std::floor( std::log10( std::abs( value ) ) / 3) );
}
inline int precision( double const scaled, int const digits )
{
return iszero( scaled ) ? digits - 1 : digits - std::log10( std::abs( scaled ) ) - 2 * std::numeric_limits<double>::epsilon();
}
inline std::string prefix_or_exponent( bool const exponential, int const degree )
{
return std::string( exponential || 0 == degree ? "" : " " ) + prefixes[ exponential ][ sign(degree) > 0 ][ std::abs( degree ) ];
}
inline std::string exponent( int const degree )
{
std::ostringstream os;
os << "e" << 3 * degree;
return os.str();
}
inline std::string bracket( std::string const unit )
{
return std::string::npos != unit.find_first_of( "+- " ) ? "(" + unit + ")" : unit;
}
} // anonymous namespace
/**
* convert real number to prefixed or exponential notation, optionally followed by a unit.
*/
inline std::string
to_engineering_string( double const value, int const digits = 3, bool exponential = false, bool const showpos = false, std::string const unit = "" )
{
using namespace detail;
if ( std::isnan( value ) ) return "NaN";
else if ( std::isinf( value ) ) return "INFINITE";
const int degree = degree_of( value );
std::string factor;
if ( std::abs( degree ) < prefix_count )
{
factor = prefix_or_exponent( exponential, degree );
}
else
{
exponential = true;
factor = exponent( degree );
}
std::ostringstream os;
const double scaled = value * std::pow( 1000.0, -degree );
const std::string space = ( 0 == degree || exponential ) && unit.length() ? " ":"";
os << std::fixed << (showpos ? std::showpos : std::noshowpos) << std::setprecision( precision(scaled, digits) ) << scaled << factor << space << bracket( unit );
return os.str();
}
namespace io {
namespace eng {
template< typename Dims, typename T >
std::string to_string( quantity<Dims, T> const & q, int const digits = 3, bool const exponential = false, bool const showpos = false )
{
return to_engineering_string( q.magnitude(), digits, exponential, showpos, to_unit_symbol( q ) );
}
template< typename Dims, typename T >
inline std::ostream & operator<<( std::ostream & os, quantity< Dims, T > const & q )
{
return os << to_string( q );
}
} // namespace eng
} // namespace io
}} // namespace phys::units
#endif // PHYS_UNITS_QUANTITY_IO_ENGINEERING_HPP_INCLUDED
/*
* end of file
*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment