style: all files refromatted with clang-format

This commit is contained in:
Mateusz Pusz
2022-03-17 23:59:48 +01:00
parent cc90985958
commit 144f6951c0
143 changed files with 5845 additions and 3563 deletions

View File

@ -1,9 +1,13 @@
########################################################################################
# NOTE: At least clang-format-15 is needed to format the code of this project correctly
########################################################################################
---
BasedOnStyle: Google
---
Language: Cpp
AccessModifierOffset: -2
# AlignAfterOpenBracket: Align
# AlignArrayOfStructures: None
# AlignConsecutiveMacros: None
# AlignConsecutiveAssignments: None
# AlignConsecutiveBitFields: None
@ -12,7 +16,6 @@ AccessModifierOffset: -2
# AlignOperands: Align
# AlignTrailingComments: true
# AllowAllArgumentsOnNextLine: true
# AllowAllConstructorInitializersOnNextLine: true
# AllowAllParametersOfDeclarationOnNextLine: true
# AllowShortEnumsOnASingleLine: true
# AllowShortBlocksOnASingleLine: Never
@ -49,7 +52,7 @@ BraceWrapping:
SplitEmptyRecord: false
# SplitEmptyNamespace: true
# BreakBeforeBinaryOperators: None
# BreakBeforeConceptDeclarations: true
# BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Custom
# BreakBeforeInheritanceComma: false
BreakInheritanceList: AfterColon
@ -60,27 +63,28 @@ BreakConstructorInitializers: AfterColon
# BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ NOLINT'
# CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Left
# CompactNamespaces: false
# ConstructorInitializerAllOnOneLineOrOnePerLine: true
# ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 2
# Cpp11BracedListStyle: true
DeriveLineEnding: false
DerivePointerAlignment: false
# DisableFormat: false
# EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Leave
# ExperimentalAutoDetectBinPacking: false
# PackConstructorInitializers: NextLine
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
# AllowAllConstructorInitializersOnNextLine: true
# FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
- SECTION
- GIVEN
- WHEN
- THEN
# StatementAttributeLikeMacros:
# - Q_EMIT
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IfMacros:
# - KJ_IF_MAYBE
IncludeBlocks: Merge
IncludeCategories:
- Regex: '^".*'
@ -95,18 +99,21 @@ IncludeCategories:
Priority: 5
# IncludeIsMainRegex: '([-_](test|unittest))?$'
# IncludeIsMainSourceRegex: ''
# IndentAccessModifiers: false
# IndentCaseLabels: true
# IndentCaseBlocks: false
# IndentGotoLabels: true
# IndentPPDirectives: None
# IndentExternBlock: AfterExternBlock
IndentRequires: true
# IndentRequiresClause: true
# IndentWidth: 2
# IndentWrappedFunctionNames: false
# InsertBraces: false
# InsertTrailingCommas: None
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtTheStartOfBlocks: false
# LambdaBodyIndentation: Signature
# MacroBlockBegin: ''
# MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
@ -120,12 +127,14 @@ MaxEmptyLinesToKeep: 2
# PenaltyBreakBeforeFirstCallParameter: 1
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakOpenParenthesis: 0
# PenaltyBreakString: 1000
# PenaltyBreakTemplateDeclaration: 10
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 200
# PenaltyIndentedWhitespace: 0
# PointerAlignment: Left
# PPIndentWidth: -1
# RawStringFormats:
# - Language: Cpp
# Delimiters:
@ -154,10 +163,15 @@ MaxEmptyLinesToKeep: 2
# - ParseTextProtoOrDie
# - ParseTestProto
# - ParsePartialTestProto
# CanonicalDelimiter: ''
# CanonicalDelimiter: pb
# BasedOnStyle: google
# ReferenceAlignment: Pointer
# ReflowComments: true
# SortIncludes: true
# RemoveBracesLLVM: false
# RequiresClausePosition: OwnLine
# SeparateDefinitionBlocks: Leave
# ShortNamespaceLines: 1
# SortIncludes: CaseSensitive
# SortJavaStaticImport: Before
# SortUsingDeclarations: true
# SpaceAfterCStyleCast: false
@ -169,20 +183,35 @@ SpaceAfterTemplateKeyword: false
# SpaceBeforeCtorInitializerColon: true
# SpaceBeforeInheritanceColon: true
# SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
# AfterControlStatements: true
# AfterForeachMacros: true
# AfterFunctionDefinitionName: false
# AfterFunctionDeclarationName: false
# AfterIfMacros: true
# AfterOverloadedOperator: false
AfterRequiresInClause: true
# AfterRequiresInExpression: false
# BeforeNonEmptyParentheses: false
# SpaceAroundPointerQualifiers: Default
# SpaceBeforeRangeBasedForLoopColon: true
# SpaceInEmptyBlock: false
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 2
# SpacesInAngles: false
# SpacesInAngles: Never
# SpacesInConditionalStatement: false
# SpacesInContainerLiterals: true
# SpacesInCStyleCastParentheses: false
# SpacesInLineCommentPrefix:
# Minimum: 1
# Maximum: -1
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
# SpaceBeforeSquareBrackets: false
# BitFieldColonSpacing: Both
Standard: Latest
# StatementAttributeLikeMacros:
# - Q_EMIT
# StatementMacros:
# - Q_UNUSED
# - QT_REQUIRE_VERSION

View File

@ -86,7 +86,10 @@ template<std::integral Char>
template<typename Char>
requires std::is_enum_v<Char>
[[nodiscard]] constexpr auto to_ascii(Char value) -> std::underlying_type_t<Char> { return value; }
[[nodiscard]] constexpr auto to_ascii(Char value) -> std::underlying_type_t<Char>
{
return value;
}
struct width_checker {
template<typename T>
@ -442,7 +445,8 @@ public:
constexpr dynamic_specs_handler(dynamic_format_specs<char_type>& specs, ParseContext& ctx) :
specs_setter<char_type>(specs), specs_(specs), context_(ctx)
{}
{
}
template<typename T>
constexpr void on_dynamic_width(T t)

View File

@ -176,7 +176,7 @@ constexpr It parse_units_format(It begin, S end, Handler&& handler)
}
default:
constexpr auto units_types = std::string_view{"Qq"};
auto const new_end = std::find_first_of(begin, end, units_types.begin(), units_types.end());
const auto new_end = std::find_first_of(begin, end, units_types.begin(), units_types.end());
if (new_end == end) throw STD_FMT::format_error("invalid format");
if (*new_end == 'Q') {
handler.on_quantity_value(begin, new_end); // Edit `on_quantity_value` to add rep modifiers
@ -274,7 +274,8 @@ struct quantity_formatter {
explicit quantity_formatter(OutputIt o, quantity<Dimension, Unit, Rep> q, const quantity_format_specs<CharT>& fspecs,
Locale lc) :
out(o), val(std::move(q).number()), specs(fspecs), loc(std::move(lc))
{}
{
}
template<std::input_iterator It, std::sentinel_for<It> S>
void on_text(It begin, S end)
@ -357,7 +358,9 @@ private:
}
template<std::input_iterator It, std::sentinel_for<It> S>
constexpr void on_text(It, S) {}
constexpr void on_text(It, S)
{
}
template<std::input_iterator It, std::sentinel_for<It> S>
constexpr void on_quantity_value(It begin, S end)
@ -365,7 +368,7 @@ private:
if (begin != end) units::detail::parse_units_rep(begin, end, *this, units::treat_as_floating_point<Rep>);
f.quantity_value = true;
}
constexpr void on_quantity_unit(CharT mod)
{
if (mod != 'q') on_unit_modifier(mod);
@ -427,7 +430,7 @@ public:
[[nodiscard]] constexpr auto parse(STD_FMT::basic_format_parse_context<CharT>& ctx)
{
auto range = do_parse(ctx);
if(range.first != range.second)
if (range.first != range.second)
format_str = std::basic_string_view<CharT>(&*range.first, static_cast<size_t>(range.second - range.first));
return range.second;
}

View File

@ -28,7 +28,8 @@
namespace units {
template<typename CharT, class Traits, std::size_t N>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const basic_fixed_string<CharT, N>& txt)
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
const basic_fixed_string<CharT, N>& txt)
{
return os << txt.c_str();
}

View File

@ -45,13 +45,13 @@ void to_stream(std::basic_ostream<CharT, Traits>& os, const quantity<D, U, Rep>&
}
}
} // namespace detail
} // namespace detail
template<typename CharT, typename Traits, typename D, typename U, typename Rep>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const quantity<D, U, Rep>& q)
requires requires { os << q.number(); }
{
if(os.width()) {
if (os.width()) {
// std::setw() applies to the whole quantity output so it has to be first put into std::string
std::basic_ostringstream<CharT, Traits> s;
s.flags(os.flags());

View File

@ -23,8 +23,8 @@
#pragma once
// IWYU pragma: begin_exports
#include <units/bits/external/fixed_string.h>
#include <units/bits/basic_concepts.h>
#include <units/bits/external/fixed_string.h>
// IWYU pragma: end_exports
#include <type_traits>
@ -38,7 +38,7 @@ namespace units {
* in the subset can be expressed in terms of the other quantities within that subset. They are referred to as
* being mutually independent since a base quantity cannot be expressed as a product of powers of the other base
* quantities.
*
*
* Base unit is a measurement unit that is adopted by convention for a base quantity in a specific system of units.
*
* Pair of Symbol and Unit template parameters form an unique identifier of the base dimension. The same identifiers can
@ -61,7 +61,6 @@ struct base_dimension {
template<BaseDimension D1, BaseDimension D2>
struct base_dimension_less :
std::bool_constant<(D1::symbol < D2::symbol) ||
(D1::symbol == D2::symbol && D1::base_unit::symbol < D1::base_unit::symbol)> {
};
(D1::symbol == D2::symbol && D1::base_unit::symbol < D1::base_unit::symbol)> {};
} // namespace units

View File

@ -29,11 +29,12 @@
namespace units::detail {
template<Exponent E>
requires (E::den == 1 || E::den == 2) // TODO provide support for any den
requires(E::den == 1 || E::den == 2) // TODO provide support for any den
constexpr ratio exp_ratio()
{
const ratio base_ratio = E::dimension::base_unit::ratio;
const ratio positive_ratio = E::num * E::den < 0 ? ratio(base_ratio.den, base_ratio.num, -base_ratio.exp) : base_ratio;
const ratio positive_ratio =
E::num * E::den < 0 ? ratio(base_ratio.den, base_ratio.num, -base_ratio.exp) : base_ratio;
const std::intmax_t N = E::num * E::den < 0 ? -E::num : E::num;
const ratio ratio_pow = pow<N>(positive_ratio);
return E::den == 2 ? sqrt(ratio_pow) : ratio_pow;

View File

@ -26,9 +26,9 @@
// IWYU pragma: begin_exports
#include <units/bits/external/fixed_string.h>
#include <units/bits/external/type_traits.h>
#include <units/customization_points.h>
#include <units/ratio.h>
#include <units/bits/external/type_traits.h>
// IWYU pragma: end_exports
#include <cstdint>
@ -73,7 +73,7 @@ concept Prefix = requires(T* t) { detail::to_prefix_base(t); };
* Satisfied by all ratio values for which `R.num > 0` and `R.den > 0`.
*/
template<ratio R>
concept UnitRatio = R.num > 0 && R.den > 0;
concept UnitRatio = (R.num > 0) && (R.den > 0);
// Unit
template<ratio R, typename U>
@ -136,10 +136,10 @@ concept Exponent = detail::is_exponent<T>;
namespace detail {
template<Exponent... Es>
requires (BaseDimension<typename Es::dimension> && ...)
requires(BaseDimension<typename Es::dimension> && ...)
struct derived_dimension_base;
} // namespace detail
} // namespace detail
/**
* @brief A concept matching all derived dimensions in the library.
@ -170,7 +170,7 @@ auto default_unit()
return typename D::coherent_unit{};
}
} // namespace detail
} // namespace detail
/**
* @brief Returns a 'default' unit of the dimension
@ -200,10 +200,7 @@ using dimension_unit = decltype(detail::default_unit<D>());
* @tparam D Dimension type to use for verification.
*/
template<typename U, typename D>
concept UnitOf =
Unit<U> &&
Dimension<D> &&
std::same_as<typename U::reference, typename dimension_unit<D>::reference>;
concept UnitOf = Unit<U> && Dimension<D> && std::same_as<typename U::reference, typename dimension_unit<D>::reference>;
// PointOrigin
@ -217,13 +214,13 @@ struct point_origin;
*/
template<typename T>
concept PointOrigin = is_derived_from_specialization_of<T, point_origin> &&
requires {
typename T::dimension;
requires Dimension<typename T::dimension>;
typename T::point_origin;
requires std::same_as<typename T::point_origin, point_origin<typename T::dimension>>;
requires !std::same_as<T, point_origin<typename T::dimension>>;
};
requires {
typename T::dimension;
requires Dimension<typename T::dimension>;
typename T::point_origin;
requires std::same_as<typename T::point_origin, point_origin<typename T::dimension>>;
requires !std::same_as<T, point_origin<typename T::dimension>>;
};
// RebindablePointOriginFor
@ -247,8 +244,7 @@ using rebind_point_origin_dimension = typename conditional<is_same_v<typename O:
*/
template<typename T, typename D>
concept RebindablePointOriginFor =
requires { typename rebind_point_origin_dimension<T, D>; } &&
PointOrigin<rebind_point_origin_dimension<T, D>> &&
requires { typename rebind_point_origin_dimension<T, D>; } && PointOrigin<rebind_point_origin_dimension<T, D>> &&
std::same_as<D, typename rebind_point_origin_dimension<T, D>::dimension>;
// Kind
@ -260,13 +256,11 @@ struct _kind_base;
} // namespace detail
template<typename T, template<typename...> typename Base>
concept kind_impl_ =
is_derived_from_specialization_of<T, Base> &&
requires {
typename T::base_kind;
typename T::dimension;
requires Dimension<typename T::dimension>;
};
concept kind_impl_ = is_derived_from_specialization_of<T, Base> && requires {
typename T::base_kind;
typename T::dimension;
requires Dimension<typename T::dimension>;
};
/**
* @brief A concept matching all kind types
@ -274,10 +268,8 @@ concept kind_impl_ =
* Satisfied by all kind types derived from an specialization of @c kind.
*/
template<typename T>
concept Kind =
kind_impl_<T, detail::_kind_base> &&
kind_impl_<typename T::base_kind, detail::_kind_base> &&
std::same_as<typename T::base_kind, typename T::base_kind::base_kind>;
concept Kind = kind_impl_<T, detail::_kind_base> && kind_impl_<typename T::base_kind, detail::_kind_base> &&
std::same_as<typename T::base_kind, typename T::base_kind::base_kind>;
// PointKind
namespace detail {
@ -294,9 +286,7 @@ struct _point_kind_base;
*/
template<typename T>
concept PointKind =
kind_impl_<T, detail::_point_kind_base> &&
requires { typename T::origin; } &&
PointOrigin<typename T::origin> &&
kind_impl_<T, detail::_point_kind_base> && requires { typename T::origin; } && PointOrigin<typename T::origin> &&
std::same_as<typename T::dimension, typename T::base_kind::dimension> &&
std::same_as<typename T::dimension, typename T::origin::dimension>;
@ -394,30 +384,26 @@ concept QuantityPointLike = detail::is_quantity_point_like<T>;
// Representation
template<typename T, typename U>
concept common_type_with_ = // exposition only
std::same_as<std::common_type_t<T, U>, std::common_type_t<U, T>> &&
std::constructible_from<std::common_type_t<T, U>, T> &&
std::constructible_from<std::common_type_t<T, U>, U>;
concept common_type_with_ = // exposition only
(std::same_as<std::common_type_t<T, U>, std::common_type_t<U, T>>) &&
(std::constructible_from<std::common_type_t<T, U>, T>) && (std::constructible_from<std::common_type_t<T, U>, U>);
template<typename T, typename U = T>
concept scalable_number_ = // exposition only
std::regular_invocable<std::multiplies<>, T, U> &&
std::regular_invocable<std::divides<>, T, U>;
concept scalable_number_ = // exposition only
(std::regular_invocable<std::multiplies<>, T, U>) && (std::regular_invocable<std::divides<>, T, U>);
template<typename T>
concept castable_number_ = // exposition only
common_type_with_<T, std::intmax_t> &&
scalable_number_<std::common_type_t<T, std::intmax_t>>;
concept castable_number_ = // exposition only
common_type_with_<T, std::intmax_t> && scalable_number_<std::common_type_t<T, std::intmax_t>>;
template<typename T>
concept scalable_ = // exposition only
castable_number_<T> ||
(requires { typename T::value_type; } && castable_number_<typename T::value_type> && scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>);
concept scalable_ = // exposition only
castable_number_<T> || (requires { typename T::value_type; } && castable_number_<typename T::value_type> &&
scalable_number_<T, std::common_type_t<typename T::value_type, std::intmax_t>>);
template<typename T, typename U>
concept scalable_with_ = // exposition only
common_type_with_<T, U> &&
scalable_<std::common_type_t<T, U>>;
concept scalable_with_ = // exposition only
common_type_with_<T, U> && scalable_<std::common_type_t<T, U>>;
// WrappedQuantity
namespace detail {
@ -427,7 +413,9 @@ inline constexpr bool is_wrapped_quantity = false;
template<typename T>
requires requires { typename T::value_type; }
inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::value_type> || QuantityLike<typename T::value_type> || is_wrapped_quantity<typename T::value_type>;
inline constexpr bool is_wrapped_quantity<T> =
Quantity<typename T::value_type> || QuantityLike<typename T::value_type> ||
is_wrapped_quantity<typename T::value_type>;
template<typename T>
requires requires { typename T::quantity_type; }
@ -442,7 +430,7 @@ inline constexpr bool is_wrapped_quantity<T> = Quantity<typename T::quantity_typ
* recursively (i.e. `std::optional<si::length<si::metre>>`).
*/
template<typename T>
concept wrapped_quantity_ = // exposition only
concept wrapped_quantity_ = // exposition only
detail::is_wrapped_quantity<T>;
/**
@ -451,39 +439,39 @@ concept wrapped_quantity_ = // exposition only
* Satisfied by types that satisfy `(!Quantity<T>) && (!WrappedQuantity<T>) && std::regular<T>`.
*/
template<typename T>
concept Representation =
(!Quantity<T>) &&
(!QuantityLike<T>) &&
(!wrapped_quantity_<T>) &&
std::regular<T> &&
scalable_<T>;
concept Representation = (!Quantity<T>) && (!QuantityLike<T>) &&
(!wrapped_quantity_<T>) && std::regular<T> && scalable_<T>;
namespace detail {
template<typename T>
requires requires(T q) {
typename quantity_like_traits<T>::dimension;
typename quantity_like_traits<T>::unit;
typename quantity_like_traits<T>::rep;
requires Dimension<typename quantity_like_traits<T>::dimension>;
requires Unit<typename quantity_like_traits<T>::unit>;
requires Representation<typename quantity_like_traits<T>::rep>;
{ quantity_like_traits<T>::number(q) } -> std::convertible_to<typename quantity_like_traits<T>::rep>;
}
typename quantity_like_traits<T>::dimension;
typename quantity_like_traits<T>::unit;
typename quantity_like_traits<T>::rep;
requires Dimension<typename quantity_like_traits<T>::dimension>;
requires Unit<typename quantity_like_traits<T>::unit>;
requires Representation<typename quantity_like_traits<T>::rep>;
{
quantity_like_traits<T>::number(q)
} -> std::convertible_to<typename quantity_like_traits<T>::rep>;
}
inline constexpr bool is_quantity_like<T> = true;
template<typename T>
requires requires(T q) {
typename quantity_point_like_traits<T>::dimension;
typename quantity_point_like_traits<T>::unit;
typename quantity_point_like_traits<T>::rep;
requires Dimension<typename quantity_point_like_traits<T>::dimension>;
requires Unit<typename quantity_point_like_traits<T>::unit>;
requires Representation<typename quantity_point_like_traits<T>::rep>;
{ quantity_point_like_traits<T>::relative(q) } -> QuantityLike;
}
typename quantity_point_like_traits<T>::dimension;
typename quantity_point_like_traits<T>::unit;
typename quantity_point_like_traits<T>::rep;
requires Dimension<typename quantity_point_like_traits<T>::dimension>;
requires Unit<typename quantity_point_like_traits<T>::unit>;
requires Representation<typename quantity_point_like_traits<T>::rep>;
{
quantity_point_like_traits<T>::relative(q)
} -> QuantityLike;
}
inline constexpr bool is_quantity_point_like<T> = true;
} // namespace detail
} // namespace detail
} // namespace units

View File

@ -59,7 +59,7 @@ struct common_quantity_reference_impl<reference<D, U1>, reference<D, U2>> {
};
template<typename D1, typename U1, typename D2, typename U2>
requires same_unit_reference<dimension_unit<D1>, dimension_unit<D2>>::value
requires(same_unit_reference<dimension_unit<D1>, dimension_unit<D2>>::value)
struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
using type = reference<D1, downcast_unit<D1, common_ratio(U1::ratio, U2::ratio)>>;
};
@ -77,8 +77,8 @@ struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
using common_quantity_reference =
TYPENAME detail::common_quantity_reference_impl <
std::remove_const_t<decltype(Q1::reference)>, std::remove_const_t<decltype(Q2::reference)>>::type;
TYPENAME detail::common_quantity_reference_impl<std::remove_const_t<decltype(Q1::reference)>,
std::remove_const_t<decltype(Q2::reference)>>::type;
} // namespace detail
} // namespace units
@ -91,33 +91,37 @@ struct common_type<Q1, Q2> {
private:
using ref = units::detail::common_quantity_reference<Q1, Q2>;
public:
using type = units::quantity<typename ref::dimension, typename ref::unit, common_type_t<typename Q1::rep, typename Q2::rep>>;
using type =
units::quantity<typename ref::dimension, typename ref::unit, common_type_t<typename Q1::rep, typename Q2::rep>>;
};
template<units::QuantityPoint QP1, units::QuantityPointEquivalentTo<QP1> QP2>
requires requires { typename common_type_t<typename QP1::rep, typename QP2::rep>; }
struct common_type<QP1, QP2> {
using type = units::quantity_point<
units::rebind_point_origin_dimension<typename QP1::origin,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::dimension>,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::unit,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::rep>;
using type =
units::quantity_point<units::rebind_point_origin_dimension<
typename QP1::origin, typename common_type_t<typename QP1::quantity_type,
typename QP2::quantity_type>::dimension>,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::unit,
typename common_type_t<typename QP1::quantity_type, typename QP2::quantity_type>::rep>;
};
template<units::QuantityKind QK1, units::QuantityKindEquivalentTo<QK1> QK2>
requires requires { typename common_type_t<typename QK1::rep, typename QK2::rep>; }
struct common_type<QK1, QK2> {
using type = units::quantity_kind<typename QK1::kind_type,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::unit,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::rep>;
using type =
units::quantity_kind<typename QK1::kind_type,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::unit,
typename common_type_t<typename QK1::quantity_type, typename QK2::quantity_type>::rep>;
};
template<units::QuantityPointKind QPK1, units::QuantityPointKindEquivalentTo<QPK1> QPK2>
requires requires { typename common_type_t<typename QPK1::rep, typename QPK2::rep>; }
struct common_type<QPK1, QPK2> {
using type = units::quantity_point_kind<typename QPK1::point_kind_type,
using type = units::quantity_point_kind<
typename QPK1::point_kind_type,
typename common_type_t<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>::unit,
typename common_type_t<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>::rep>;
};
}
} // namespace std

View File

@ -76,105 +76,105 @@ struct decimal_fp {
// >>> for i in range(1, 100):
// ... print(f"/* log({i:>2d}) = */ {math.log(i):.16f},")
constexpr std::array<double, 99> log_table{
/* log( 1) = */ 0.0000000000000000,
/* log( 2) = */ 0.6931471805599453,
/* log( 3) = */ 1.0986122886681098,
/* log( 4) = */ 1.3862943611198906,
/* log( 5) = */ 1.6094379124341003,
/* log( 6) = */ 1.7917594692280550,
/* log( 7) = */ 1.9459101490553132,
/* log( 8) = */ 2.0794415416798357,
/* log( 9) = */ 2.1972245773362196,
/* log(10) = */ 2.3025850929940459,
/* log(11) = */ 2.3978952727983707,
/* log(12) = */ 2.4849066497880004,
/* log(13) = */ 2.5649493574615367,
/* log(14) = */ 2.6390573296152584,
/* log(15) = */ 2.7080502011022101,
/* log(16) = */ 2.7725887222397811,
/* log(17) = */ 2.8332133440562162,
/* log(18) = */ 2.8903717578961645,
/* log(19) = */ 2.9444389791664403,
/* log(20) = */ 2.9957322735539909,
/* log(21) = */ 3.0445224377234230,
/* log(22) = */ 3.0910424533583161,
/* log(23) = */ 3.1354942159291497,
/* log(24) = */ 3.1780538303479458,
/* log(25) = */ 3.2188758248682006,
/* log(26) = */ 3.2580965380214821,
/* log(27) = */ 3.2958368660043291,
/* log(28) = */ 3.3322045101752038,
/* log(29) = */ 3.3672958299864741,
/* log(30) = */ 3.4011973816621555,
/* log(31) = */ 3.4339872044851463,
/* log(32) = */ 3.4657359027997265,
/* log(33) = */ 3.4965075614664802,
/* log(34) = */ 3.5263605246161616,
/* log(35) = */ 3.5553480614894135,
/* log(36) = */ 3.5835189384561099,
/* log(37) = */ 3.6109179126442243,
/* log(38) = */ 3.6375861597263857,
/* log(39) = */ 3.6635616461296463,
/* log(40) = */ 3.6888794541139363,
/* log(41) = */ 3.7135720667043080,
/* log(42) = */ 3.7376696182833684,
/* log(43) = */ 3.7612001156935624,
/* log(44) = */ 3.7841896339182610,
/* log(45) = */ 3.8066624897703196,
/* log(46) = */ 3.8286413964890951,
/* log(47) = */ 3.8501476017100584,
/* log(48) = */ 3.8712010109078911,
/* log(49) = */ 3.8918202981106265,
/* log(50) = */ 3.9120230054281460,
/* log(51) = */ 3.9318256327243257,
/* log(52) = */ 3.9512437185814275,
/* log(53) = */ 3.9702919135521220,
/* log(54) = */ 3.9889840465642745,
/* log(55) = */ 4.0073331852324712,
/* log(56) = */ 4.0253516907351496,
/* log(57) = */ 4.0430512678345503,
/* log(58) = */ 4.0604430105464191,
/* log(59) = */ 4.0775374439057197,
/* log(60) = */ 4.0943445622221004,
/* log(61) = */ 4.1108738641733114,
/* log(62) = */ 4.1271343850450917,
/* log(63) = */ 4.1431347263915326,
/* log(64) = */ 4.1588830833596715,
/* log(65) = */ 4.1743872698956368,
/* log(66) = */ 4.1896547420264252,
/* log(67) = */ 4.2046926193909657,
/* log(68) = */ 4.2195077051761070,
/* log(69) = */ 4.2341065045972597,
/* log(70) = */ 4.2484952420493594,
/* log(71) = */ 4.2626798770413155,
/* log(72) = */ 4.2766661190160553,
/* log(73) = */ 4.2904594411483910,
/* log(74) = */ 4.3040650932041702,
/* log(75) = */ 4.3174881135363101,
/* log(76) = */ 4.3307333402863311,
/* log(77) = */ 4.3438054218536841,
/* log(78) = */ 4.3567088266895917,
/* log(79) = */ 4.3694478524670215,
/* log(80) = */ 4.3820266346738812,
/* log(81) = */ 4.3944491546724391,
/* log(82) = */ 4.4067192472642533,
/* log(83) = */ 4.4188406077965983,
/* log(84) = */ 4.4308167988433134,
/* log(85) = */ 4.4426512564903167,
/* log(86) = */ 4.4543472962535073,
/* log(87) = */ 4.4659081186545837,
/* log(88) = */ 4.4773368144782069,
/* log(89) = */ 4.4886363697321396,
/* log(90) = */ 4.4998096703302650,
/* log(91) = */ 4.5108595065168497,
/* log(92) = */ 4.5217885770490405,
/* log(93) = */ 4.5325994931532563,
/* log(94) = */ 4.5432947822700038,
/* log(95) = */ 4.5538768916005408,
/* log(96) = */ 4.5643481914678361,
/* log(97) = */ 4.5747109785033828,
/* log(98) = */ 4.5849674786705723,
/* log(99) = */ 4.5951198501345898,
/* log( 1) = */ 0.0000000000000000,
/* log( 2) = */ 0.6931471805599453,
/* log( 3) = */ 1.0986122886681098,
/* log( 4) = */ 1.3862943611198906,
/* log( 5) = */ 1.6094379124341003,
/* log( 6) = */ 1.7917594692280550,
/* log( 7) = */ 1.9459101490553132,
/* log( 8) = */ 2.0794415416798357,
/* log( 9) = */ 2.1972245773362196,
/* log(10) = */ 2.3025850929940459,
/* log(11) = */ 2.3978952727983707,
/* log(12) = */ 2.4849066497880004,
/* log(13) = */ 2.5649493574615367,
/* log(14) = */ 2.6390573296152584,
/* log(15) = */ 2.7080502011022101,
/* log(16) = */ 2.7725887222397811,
/* log(17) = */ 2.8332133440562162,
/* log(18) = */ 2.8903717578961645,
/* log(19) = */ 2.9444389791664403,
/* log(20) = */ 2.9957322735539909,
/* log(21) = */ 3.0445224377234230,
/* log(22) = */ 3.0910424533583161,
/* log(23) = */ 3.1354942159291497,
/* log(24) = */ 3.1780538303479458,
/* log(25) = */ 3.2188758248682006,
/* log(26) = */ 3.2580965380214821,
/* log(27) = */ 3.2958368660043291,
/* log(28) = */ 3.3322045101752038,
/* log(29) = */ 3.3672958299864741,
/* log(30) = */ 3.4011973816621555,
/* log(31) = */ 3.4339872044851463,
/* log(32) = */ 3.4657359027997265,
/* log(33) = */ 3.4965075614664802,
/* log(34) = */ 3.5263605246161616,
/* log(35) = */ 3.5553480614894135,
/* log(36) = */ 3.5835189384561099,
/* log(37) = */ 3.6109179126442243,
/* log(38) = */ 3.6375861597263857,
/* log(39) = */ 3.6635616461296463,
/* log(40) = */ 3.6888794541139363,
/* log(41) = */ 3.7135720667043080,
/* log(42) = */ 3.7376696182833684,
/* log(43) = */ 3.7612001156935624,
/* log(44) = */ 3.7841896339182610,
/* log(45) = */ 3.8066624897703196,
/* log(46) = */ 3.8286413964890951,
/* log(47) = */ 3.8501476017100584,
/* log(48) = */ 3.8712010109078911,
/* log(49) = */ 3.8918202981106265,
/* log(50) = */ 3.9120230054281460,
/* log(51) = */ 3.9318256327243257,
/* log(52) = */ 3.9512437185814275,
/* log(53) = */ 3.9702919135521220,
/* log(54) = */ 3.9889840465642745,
/* log(55) = */ 4.0073331852324712,
/* log(56) = */ 4.0253516907351496,
/* log(57) = */ 4.0430512678345503,
/* log(58) = */ 4.0604430105464191,
/* log(59) = */ 4.0775374439057197,
/* log(60) = */ 4.0943445622221004,
/* log(61) = */ 4.1108738641733114,
/* log(62) = */ 4.1271343850450917,
/* log(63) = */ 4.1431347263915326,
/* log(64) = */ 4.1588830833596715,
/* log(65) = */ 4.1743872698956368,
/* log(66) = */ 4.1896547420264252,
/* log(67) = */ 4.2046926193909657,
/* log(68) = */ 4.2195077051761070,
/* log(69) = */ 4.2341065045972597,
/* log(70) = */ 4.2484952420493594,
/* log(71) = */ 4.2626798770413155,
/* log(72) = */ 4.2766661190160553,
/* log(73) = */ 4.2904594411483910,
/* log(74) = */ 4.3040650932041702,
/* log(75) = */ 4.3174881135363101,
/* log(76) = */ 4.3307333402863311,
/* log(77) = */ 4.3438054218536841,
/* log(78) = */ 4.3567088266895917,
/* log(79) = */ 4.3694478524670215,
/* log(80) = */ 4.3820266346738812,
/* log(81) = */ 4.3944491546724391,
/* log(82) = */ 4.4067192472642533,
/* log(83) = */ 4.4188406077965983,
/* log(84) = */ 4.4308167988433134,
/* log(85) = */ 4.4426512564903167,
/* log(86) = */ 4.4543472962535073,
/* log(87) = */ 4.4659081186545837,
/* log(88) = */ 4.4773368144782069,
/* log(89) = */ 4.4886363697321396,
/* log(90) = */ 4.4998096703302650,
/* log(91) = */ 4.5108595065168497,
/* log(92) = */ 4.5217885770490405,
/* log(93) = */ 4.5325994931532563,
/* log(94) = */ 4.5432947822700038,
/* log(95) = */ 4.5538768916005408,
/* log(96) = */ 4.5643481914678361,
/* log(97) = */ 4.5747109785033828,
/* log(98) = */ 4.5849674786705723,
/* log(99) = */ 4.5951198501345898,
};
decimal_fp x = to_decimal(v);

View File

@ -34,17 +34,17 @@ namespace units::detail {
* Expression of the dependence of a quantity on the base quantities (and their base dimensions) of a system of
* quantities as a product of powers of factors corresponding to the base quantities, omitting any numerical factors.
* A power of a factor is the factor raised to an exponent.
*
* A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent<L, 1>, exponent<T, -1>").
* It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just
*
* A derived dimension can be formed from multiple exponents (i.e. speed is represented as "exponent<L, 1>, exponent<T,
* -1>"). It is also possible to form a derived dimension with only one exponent (i.e. frequency is represented as just
* "exponent<T, -1>").
*
*
* @note This class template is used by the library engine and should not be directly instantiated by the user.
*
*
* @tparam Es zero or more exponents of a derived dimension
*/
template<Exponent... Es>
requires (BaseDimension<typename Es::dimension> && ...)
requires(BaseDimension<typename Es::dimension> && ...)
struct derived_dimension_base : downcast_base<derived_dimension_base<Es...>> {
using exponents = exponent_list<Es...>;
};

View File

@ -32,19 +32,16 @@ namespace units::detail {
template<bool Divide, std::size_t NegativeExpCount, std::size_t Idx>
constexpr auto operator_text()
{
if constexpr(Idx == 0) {
if constexpr(Divide && NegativeExpCount == 1) {
if constexpr (Idx == 0) {
if constexpr (Divide && NegativeExpCount == 1) {
return basic_fixed_string("1/");
}
else {
} else {
return basic_fixed_string("");
}
}
else {
if constexpr(Divide && NegativeExpCount == 1) {
} else {
if constexpr (Divide && NegativeExpCount == 1) {
return basic_fixed_string("/");
}
else {
} else {
return basic_symbol_text("", " ");
}
}
@ -54,24 +51,21 @@ template<typename E, basic_symbol_text Symbol, std::size_t NegativeExpCount, std
constexpr auto exp_text()
{
// get calculation operator + symbol
const auto txt = operator_text<E::num < 0, NegativeExpCount, Idx>() + Symbol;
if constexpr(E::den != 1) {
const auto txt = operator_text<(E::num < 0), NegativeExpCount, Idx>() + Symbol;
if constexpr (E::den != 1) {
// add root part
return txt + basic_fixed_string("^(") + regular<abs(E::num)>() + basic_fixed_string("/") + regular<E::den>() + basic_fixed_string(")");
}
else if constexpr(E::num != 1) {
return txt + basic_fixed_string("^(") + regular<abs(E::num)>() + basic_fixed_string("/") + regular<E::den>() +
basic_fixed_string(")");
} else if constexpr (E::num != 1) {
// add exponent part
if constexpr(NegativeExpCount > 1) { // no '/' sign here (only negative exponents)
if constexpr (NegativeExpCount > 1) { // no '/' sign here (only negative exponents)
return txt + superscript<E::num>();
}
else if constexpr(E::num != -1) { // -1 is replaced with '/' sign here
} else if constexpr (E::num != -1) { // -1 is replaced with '/' sign here
return txt + superscript<abs(E::num)>();
}
else {
} else {
return txt;
}
}
else {
} else {
return txt;
}
}

View File

@ -38,7 +38,7 @@ inline constexpr bool same_scaled_units<exponent_list<Es...>, Us...> = (UnitOf<U
template<Exponent E>
constexpr ratio inverse_if_negative(const ratio& r)
{
if constexpr(E::num * E::den > 0)
if constexpr (E::num * E::den > 0)
return r;
else
return inverse(r);
@ -47,7 +47,8 @@ constexpr ratio inverse_if_negative(const ratio& r)
template<Unit... Us, typename... Es>
constexpr ratio derived_ratio(exponent_list<Es...>)
{
return (... * inverse_if_negative<Es>(pow<detail::abs(Es::num)>(Us::ratio / dimension_unit<typename Es::dimension>::ratio)));
return (... * inverse_if_negative<Es>(
pow<detail::abs(Es::num)>(Us::ratio / dimension_unit<typename Es::dimension>::ratio)));
}
template<DerivedDimension D, Unit... Us>

View File

@ -54,7 +54,8 @@ struct dim_consolidate<exponent_list<E1, ERest...>> {
using type = type_list_push_front<typename dim_consolidate<exponent_list<ERest...>>::type, E1>;
};
template<BaseDimension Dim, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2, typename... ERest>
template<BaseDimension Dim, std::intmax_t Num1, std::intmax_t Den1, std::intmax_t Num2, std::intmax_t Den2,
typename... ERest>
struct dim_consolidate<exponent_list<exponent<Dim, Num1, Den1>, exponent<Dim, Num2, Den2>, ERest...>> {
using r1 = std::ratio<Num1, Den1>;
using r2 = std::ratio<Num2, Den2>;

View File

@ -30,8 +30,8 @@ namespace units::detail {
/**
* @brief Unpacks the list of potentially derived dimensions to a list containing only base dimensions
*
* @tparam Es Exponents of potentially derived dimensions
*
* @tparam Es Exponents of potentially derived dimensions
*/
template<Exponent... Es>
struct dim_unpack;

View File

@ -34,11 +34,11 @@ namespace units {
/**
* @brief Unknown dimension
*
*
* Sometimes a temporary partial result of a complex calculation may not result in a predefined
* dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_coherent_unit`
* and ratio(1).
*
*
* @tparam Es the list of exponents of ingredient dimensions
*/
template<Exponent... Es>
@ -70,7 +70,7 @@ struct downcast_dimension_impl<D> {
using type = TYPENAME check_unknown<downcast<D>>::type;
};
} // namespace detail
} // namespace detail
template<Dimension D>
using downcast_dimension = TYPENAME detail::downcast_dimension_impl<D>::type;
@ -97,8 +97,7 @@ struct dim_invert_impl<derived_dimension_base<Es...>> {
};
template<DerivedDimension D>
struct dim_invert_impl<D> : dim_invert_impl<downcast_base_t<D>> {
};
struct dim_invert_impl<D> : dim_invert_impl<downcast_base_t<D>> {};
} // namespace detail
@ -123,7 +122,7 @@ struct to_dimension<exponent_list<exponent<D, 1>>> {
/**
* @brief Merges 2 sorted derived dimensions into one units::derived_dimension_base
*
*
* A result of a dimensional calculation may result with many exponents of the same base dimension orginated
* from different parts of the equation. As the exponents lists of both operands it is enough to merge them
* into one list and consolidate duplicates. Also it is possible that final exponents list will contain only
@ -131,19 +130,22 @@ struct to_dimension<exponent_list<exponent<D, 1>>> {
* dimension itself.
*/
template<Dimension D1, Dimension D2>
using merge_dimension = TYPENAME to_dimension<typename dim_consolidate<type_list_merge_sorted<typename D1::exponents, typename D2::exponents, exponent_less>>::type>::type;
using merge_dimension = TYPENAME to_dimension<typename dim_consolidate<
type_list_merge_sorted<typename D1::exponents, typename D2::exponents, exponent_less>>::type>::type;
template<Dimension D1, Dimension D2>
struct dimension_multiply_impl;
template<BaseDimension D1, BaseDimension D2>
struct dimension_multiply_impl<D1, D2> {
using type = downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, derived_dimension_base<exponent<D2, 1>>>>;
using type = downcast_dimension<
merge_dimension<derived_dimension_base<exponent<D1, 1>>, derived_dimension_base<exponent<D2, 1>>>>;
};
template<BaseDimension D1, DerivedDimension D2>
struct dimension_multiply_impl<D1, D2> {
using type = downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, typename D2::downcast_base_type>>;
using type =
downcast_dimension<merge_dimension<derived_dimension_base<exponent<D1, 1>>, typename D2::downcast_base_type>>;
};
template<DerivedDimension D1, BaseDimension D2>

View File

@ -30,12 +30,10 @@ namespace units {
namespace detail {
template<typename T, typename U>
struct equivalent_impl : std::false_type {
};
struct equivalent_impl : std::false_type {};
template<typename T>
struct equivalent_impl<T, T> : std::true_type {
};
struct equivalent_impl<T, T> : std::true_type {};
// units
@ -47,39 +45,35 @@ struct equivalent_impl<U1, U2> : std::disjunction<std::is_base_of<U1, U2>, std::
// dimensions
template<BaseDimension D1, BaseDimension D2>
struct equivalent_impl<D1, D2> : std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
same_unit_reference<typename D1::base_unit, typename D2::base_unit>> {
};
struct equivalent_impl<D1, D2> :
std::conjunction<std::bool_constant<D1::symbol == D2::symbol>,
same_unit_reference<typename D1::base_unit, typename D2::base_unit>> {};
template<Exponent E1, Exponent E2>
struct equivalent_exp : std::false_type {
};
struct equivalent_exp : std::false_type {};
template<BaseDimension Dim1, std::intmax_t Num, std::intmax_t Den, BaseDimension Dim2>
struct equivalent_exp<exponent<Dim1, Num, Den>, exponent<Dim2, Num, Den>> : equivalent_impl<Dim1, Dim2> {
};
struct equivalent_exp<exponent<Dim1, Num, Den>, exponent<Dim2, Num, Den>> : equivalent_impl<Dim1, Dim2> {};
template<DerivedDimension D1, DerivedDimension D2>
struct equivalent_derived_dim : std::false_type {
};
struct equivalent_derived_dim : std::false_type {};
template<typename... Es1, typename... Es2>
requires(sizeof...(Es1) == sizeof...(Es2))
struct equivalent_derived_dim<derived_dimension_base<Es1...>, derived_dimension_base<Es2...>> :
std::conjunction<equivalent_exp<Es1, Es2>...> {
};
std::conjunction<equivalent_exp<Es1, Es2>...> {};
template<DerivedDimension D1, DerivedDimension D2>
struct equivalent_impl<D1, D2> :
std::disjunction<std::is_base_of<D1, D2>, std::is_base_of<D2, D1>,
equivalent_derived_dim<downcast_base_t<D1>, downcast_base_t<D2>>> {
};
equivalent_derived_dim<downcast_base_t<D1>, downcast_base_t<D2>>> {};
// additionally accounts for unknown dimensions
template<Unit U1, Dimension D1, Unit U2, Dimension D2>
struct equivalent_unit : std::disjunction<equivalent_impl<U1, U2>,
std::bool_constant<U1::ratio / dimension_unit<D1>::ratio == U2::ratio / dimension_unit<D2>::ratio>> {};
struct equivalent_unit :
std::disjunction<equivalent_impl<U1, U2>, std::bool_constant<U1::ratio / dimension_unit<D1>::ratio ==
U2::ratio / dimension_unit<D2>::ratio>> {};
// point origins
@ -90,41 +84,46 @@ concept EquivalentPointOrigins =
std::same_as<U, rebind_point_origin_dimension<T, typename U::dimension>>;
template<PointOrigin T, PointOrigin U>
struct equivalent_impl<T, U> : std::bool_constant<
EquivalentPointOrigins<T, U> && equivalent_impl<typename T::dimension, typename U::dimension>::value> {};
struct equivalent_impl<T, U> :
std::bool_constant<EquivalentPointOrigins<T, U> &&
equivalent_impl<typename T::dimension, typename U::dimension>::value> {};
// (point) kinds
template<Kind T, Kind U>
struct equivalent_impl<T, U> :
std::conjunction<std::is_same<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::dimension, typename U::dimension>> {};
std::conjunction<std::is_same<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::dimension, typename U::dimension>> {};
template<PointKind T, PointKind U>
struct equivalent_impl<T, U> :
std::conjunction<equivalent_impl<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::origin, typename U::origin>> {};
std::conjunction<equivalent_impl<typename T::base_kind, typename U::base_kind>,
equivalent_impl<typename T::origin, typename U::origin>> {};
// quantities, quantity points, quantity (point) kinds
template<Quantity Q1, Quantity Q2>
struct equivalent_impl<Q1, Q2> : std::conjunction<equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension,
typename Q2::unit, typename Q2::dimension>> {};
struct equivalent_impl<Q1, Q2> :
std::conjunction<
equivalent_impl<typename Q1::dimension, typename Q2::dimension>,
equivalent_unit<typename Q1::unit, typename Q1::dimension, typename Q2::unit, typename Q2::dimension>> {};
template<QuantityPoint QP1, QuantityPoint QP2>
struct equivalent_impl<QP1, QP2> : std::conjunction<equivalent_impl<typename QP1::quantity_type, typename QP2::quantity_type>,
equivalent_impl<typename QP1::origin, typename QP2::origin>> {};
struct equivalent_impl<QP1, QP2> :
std::conjunction<equivalent_impl<typename QP1::quantity_type, typename QP2::quantity_type>,
equivalent_impl<typename QP1::origin, typename QP2::origin>> {};
template<QuantityKind QK1, QuantityKind QK2>
struct equivalent_impl<QK1, QK2> : std::conjunction<equivalent_impl<typename QK1::kind_type, typename QK2::kind_type>,
equivalent_impl<typename QK1::quantity_type, typename QK2::quantity_type>> {};
struct equivalent_impl<QK1, QK2> :
std::conjunction<equivalent_impl<typename QK1::kind_type, typename QK2::kind_type>,
equivalent_impl<typename QK1::quantity_type, typename QK2::quantity_type>> {};
template<QuantityPointKind QPK1, QuantityPointKind QPK2>
struct equivalent_impl<QPK1, QPK2> : std::conjunction<equivalent_impl<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>,
equivalent_impl<typename QPK1::origin, typename QPK2::origin>> {};
struct equivalent_impl<QPK1, QPK2> :
std::conjunction<equivalent_impl<typename QPK1::quantity_kind_type, typename QPK2::quantity_kind_type>,
equivalent_impl<typename QPK1::origin, typename QPK2::origin>> {};
} // namespace detail

View File

@ -38,17 +38,16 @@ namespace units {
template<typename BaseType>
struct downcast_base {
using downcast_base_type = BaseType;
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND
friend auto downcast_guide(downcast_base);
friend auto downcast_poison_pill(downcast_base);
UNITS_DIAGNOSTIC_POP
UNITS_DIAGNOSTIC_POP
};
template<typename T>
concept Downcastable =
requires { typename T::downcast_base_type; } &&
std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
requires { typename T::downcast_base_type; } && std::derived_from<T, downcast_base<typename T::downcast_base_type>>;
template<typename T>
concept has_downcast_guide = requires(T t) { downcast_guide(t); };
@ -58,30 +57,31 @@ concept has_downcast_poison_pill = requires(T t) { downcast_poison_pill(t); };
template<typename Target, Downcastable T>
struct downcast_child : T {
friend auto downcast_guide(typename T::downcast_base)
{ return std::type_identity<Target>(); }
friend auto downcast_guide(typename T::downcast_base) { return std::type_identity<Target>(); }
};
template<Downcastable T>
struct downcast_poison : T {
friend auto downcast_poison_pill(typename T::downcast_base)
{ return true; }
friend auto downcast_poison_pill(typename T::downcast_base) { return true; }
};
enum class downcast_mode {
off = 0, // no downcasting at all
on = 1, // downcasting always forced -> compile-time errors in case of duplicated definitions
automatic = 2 // downcasting automatically enabled if no collisions are present
off = 0, // no downcasting at all
on = 1, // downcasting always forced -> compile-time errors in case of duplicated definitions
automatic = 2 // downcasting automatically enabled if no collisions are present
};
template<typename Target, Downcastable T, downcast_mode mode = static_cast<downcast_mode>(UNITS_DOWNCAST_MODE)>
struct downcast_dispatch : std::conditional_t<mode == downcast_mode::off, T,
struct downcast_dispatch :
std::conditional_t<mode == downcast_mode::off, T,
#ifdef UNITS_COMP_MSVC
downcast_child<Target, T>> {};
downcast_child<Target, T>> {
};
#else
std::conditional_t<mode == downcast_mode::automatic && has_downcast_guide<T>,
downcast_poison<T>, downcast_child<Target, T>>> {};
std::conditional_t<mode == downcast_mode::automatic && has_downcast_guide<T>, downcast_poison<T>,
downcast_child<Target, T>>> {
};
#endif
namespace detail {
@ -89,7 +89,7 @@ namespace detail {
template<typename T>
constexpr auto downcast_impl()
{
if constexpr(has_downcast_guide<downcast_base<T>> && !has_downcast_poison_pill<downcast_base<T>>)
if constexpr (has_downcast_guide<downcast_base<T>> && !has_downcast_poison_pill<downcast_base<T>>)
return decltype(downcast_guide(std::declval<downcast_base<T>>()))();
else
return std::type_identity<T>();

View File

@ -22,11 +22,11 @@
#pragma once
#include <units/bits/external/hacks.h> // IWYU pragma: keep
#include <units/bits/external/hacks.h> // IWYU pragma: keep
// IWYU pragma: begin_exports
#include <cstdlib>
#include <compare>
#include <cstdlib>
// IWYU pragma: end_exports
#include <cstddef>
@ -37,7 +37,7 @@ namespace units {
/**
* @brief A compile-time fixed string
*
*
* @tparam CharT Character type to be used by the string
* @tparam N The size of the string
*/
@ -70,7 +70,7 @@ struct basic_fixed_string {
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_fixed_string<CharT, N + N2> operator+(
const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs) noexcept
const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs) noexcept
{
CharT txt[N + N2 + 1] = {};
@ -82,21 +82,23 @@ struct basic_fixed_string {
[[nodiscard]] constexpr bool operator==(const basic_fixed_string& other) const
{
if (size() != other.size())
return false;
if (size() != other.size()) return false;
for (size_t i = 0; i != size(); ++i) {
if ((*this)[i] != other[i])
return false;
if ((*this)[i] != other[i]) return false;
}
return true;
// return std::ranges::equal(*this, other);
}
template<std::size_t N2>
[[nodiscard]] friend constexpr bool operator==(const basic_fixed_string&, const basic_fixed_string<CharT, N2>&) { return false; }
[[nodiscard]] friend constexpr bool operator==(const basic_fixed_string&, const basic_fixed_string<CharT, N2>&)
{
return false;
}
template<std::size_t N2>
[[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs, const basic_fixed_string<CharT, N2>& rhs)
[[nodiscard]] friend constexpr auto operator<=>(const basic_fixed_string& lhs,
const basic_fixed_string<CharT, N2>& rhs)
{
auto first1 = lhs.begin();
const auto last1 = lhs.end();
@ -105,12 +107,11 @@ struct basic_fixed_string {
auto comp = std::compare_three_way();
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
if (auto cmp = comp(*first1, *first2); cmp != 0)
return cmp;
return first1 != last1 ? std::strong_ordering::greater :
first2 != last2 ? std::strong_ordering::less :
std::strong_ordering::equal;
if (auto cmp = comp(*first1, *first2); cmp != 0) return cmp;
return first1 != last1 ? std::strong_ordering::greater
: first2 != last2 ? std::strong_ordering::less
: std::strong_ordering::equal;
// return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
};

View File

@ -39,9 +39,9 @@
#define UNITS_DIAGNOSTIC_PUSH UNITS_PRAGMA(GCC diagnostic push)
#define UNITS_DIAGNOSTIC_POP UNITS_PRAGMA(GCC diagnostic pop)
#define UNITS_DIAGNOSTIC_IGNORE_PRAGMAS UNITS_PRAGMA(GCC diagnostic ignored "-Wpragmas")
#define UNITS_DIAGNOSTIC_IGNORE(X) \
UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
#define UNITS_DIAGNOSTIC_IGNORE(X) \
UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \
UNITS_PRAGMA(GCC diagnostic ignored X)
#define UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF
@ -87,8 +87,8 @@
#endif
#include <concepts>
#include <compare>
#include <concepts>
#if UNITS_COMP_MSVC || UNITS_COMP_CLANG
@ -130,14 +130,14 @@ using concepts::totally_ordered;
using ranges::compare_three_way;
using ranges::input_iterator;
using ranges::sentinel_for;
using ranges::iter_value_t;
using ranges::sentinel_for;
namespace ranges {
using ::ranges::begin;
using ::ranges::end;
using ::ranges::distance;
using ::ranges::end;
using ::ranges::input_range;
using ::ranges::range_value_t;
@ -145,7 +145,7 @@ using ::ranges::range_value_t;
using ::ranges::lower_bound;
using ::ranges::transform;
}
} // namespace ranges
// missing in Range-v3
template<class T>
@ -153,15 +153,10 @@ concept floating_point = std::is_floating_point_v<T>;
template<class T>
concept default_initializable =
std::constructible_from<T> &&
requires { T{}; } &&
requires { ::new (static_cast<void*>(nullptr)) T; };
std::constructible_from<T> && requires { T{}; } && requires { ::new (static_cast<void*>(nullptr)) T; };
template<class F, class... Args>
concept invocable =
requires(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
};
concept invocable = requires(F&& f, Args&&... args) { std::invoke(std::forward<F>(f), std::forward<Args>(args)...); };
template<class F, class... Args>
concept regular_invocable = invocable<F, Args...>;
@ -172,44 +167,44 @@ constexpr bool cmp_equal(T t, U u) noexcept
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t == u;
return t == u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? false : UT(t) == u;
return t < 0 ? false : UT(t) == u;
else
return u < 0 ? false : t == UU(u);
return u < 0 ? false : t == UU(u);
}
template<class T, class U>
constexpr bool cmp_not_equal(T t, U u) noexcept
{
return !cmp_equal(t, u);
}
template<class T, class U>
constexpr bool cmp_less(T t, U u) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t < u;
return t < u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? true : UT(t) < u;
return t < 0 ? true : UT(t) < u;
else
return u < 0 ? false : t < UU(u);
return u < 0 ? false : t < UU(u);
}
template<class T, class U>
constexpr bool cmp_greater(T t, U u) noexcept
{
return cmp_less(u, t);
}
template<class T, class U>
constexpr bool cmp_less_equal(T t, U u) noexcept
{
return !cmp_greater(t, u);
}
template<class T, class U>
constexpr bool cmp_greater_equal(T t, U u) noexcept
{
@ -220,7 +215,7 @@ template<class R, class T>
constexpr bool in_range(T t) noexcept
{
return std::cmp_greater_equal(t, std::numeric_limits<R>::min()) &&
std::cmp_less_equal(t, std::numeric_limits<R>::max());
std::cmp_less_equal(t, std::numeric_limits<R>::max());
}
#elif UNITS_LIBCXX < 14000
@ -233,4 +228,4 @@ using ::ranges::compare_three_way;
#endif
} // namespace std
} // namespace std

View File

@ -28,19 +28,29 @@
namespace units::detail {
template<std::intmax_t Value>
requires (0 <= Value) && (Value < 10)
requires(0 <= Value) && (Value < 10)
inline constexpr basic_fixed_string superscript_number = "";
template<> inline constexpr basic_fixed_string superscript_number<0> = "\u2070";
template<> inline constexpr basic_fixed_string superscript_number<1> = "\u00b9";
template<> inline constexpr basic_fixed_string superscript_number<2> = "\u00b2";
template<> inline constexpr basic_fixed_string superscript_number<3> = "\u00b3";
template<> inline constexpr basic_fixed_string superscript_number<4> = "\u2074";
template<> inline constexpr basic_fixed_string superscript_number<5> = "\u2075";
template<> inline constexpr basic_fixed_string superscript_number<6> = "\u2076";
template<> inline constexpr basic_fixed_string superscript_number<7> = "\u2077";
template<> inline constexpr basic_fixed_string superscript_number<8> = "\u2078";
template<> inline constexpr basic_fixed_string superscript_number<9> = "\u2079";
template<>
inline constexpr basic_fixed_string superscript_number<0> = "\u2070";
template<>
inline constexpr basic_fixed_string superscript_number<1> = "\u00b9";
template<>
inline constexpr basic_fixed_string superscript_number<2> = "\u00b2";
template<>
inline constexpr basic_fixed_string superscript_number<3> = "\u00b3";
template<>
inline constexpr basic_fixed_string superscript_number<4> = "\u2074";
template<>
inline constexpr basic_fixed_string superscript_number<5> = "\u2075";
template<>
inline constexpr basic_fixed_string superscript_number<6> = "\u2076";
template<>
inline constexpr basic_fixed_string superscript_number<7> = "\u2077";
template<>
inline constexpr basic_fixed_string superscript_number<8> = "\u2078";
template<>
inline constexpr basic_fixed_string superscript_number<9> = "\u2079";
inline constexpr basic_symbol_text superscript_minus("\u207b", "-");
@ -49,9 +59,9 @@ inline constexpr basic_symbol_text superscript_prefix("", "^");
template<std::intmax_t Value>
constexpr auto superscript_helper()
{
if constexpr(Value < 0)
if constexpr (Value < 0)
return superscript_minus + superscript_helper<-Value>();
else if constexpr(Value < 10)
else if constexpr (Value < 10)
return basic_symbol_text(superscript_number<Value>, basic_fixed_string(static_cast<char>('0' + Value)));
else
return superscript_helper<Value / 10>() + superscript_helper<Value % 10>();

View File

@ -111,7 +111,7 @@ struct split_impl<List, Idx, N> {
};
template<template<typename...> typename List, std::size_t Idx, std::size_t N, typename T, typename... Rest>
requires (Idx < N)
requires(Idx < N)
struct split_impl<List, Idx, N, T, Rest...> : split_impl<List, Idx + 1, N, Rest...> {
using base = split_impl<List, Idx + 1, N, Rest...>;
using first_list = TYPENAME type_list_push_front_impl<typename base::first_list, T>::type;
@ -144,8 +144,7 @@ template<TypeList List>
struct type_list_split_half;
template<template<typename...> typename List, typename... Types>
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {
};
struct type_list_split_half<List<Types...>> : type_list_split<List<Types...>, (sizeof...(Types) + 1) / 2> {};
// merge_sorted
@ -174,13 +173,15 @@ template<template<typename...> typename List, typename Lhs1, typename... LhsRest
template<typename, typename> typename Pred>
requires Pred<Lhs1, Rhs1>::value
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = TYPENAME type_list_push_front_impl<typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type;
using type = TYPENAME type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type;
};
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = TYPENAME type_list_push_front_impl<typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type;
using type = TYPENAME type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type;
};
} // namespace detail

View File

@ -22,8 +22,8 @@
#pragma once
#include <cstdint>
#include <cassert>
#include <cstdint>
namespace units::detail {

View File

@ -36,12 +36,16 @@ template<typename Dim, template<typename...> typename DimTemplate>
inline constexpr bool same_exponents_of = false;
template<Exponent... Es, template<typename...> typename DimTemplate>
inline constexpr bool same_exponents_of<unknown_dimension<Es...>, DimTemplate> = requires { typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>; } && std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>::recipe>;
inline constexpr bool same_exponents_of<unknown_dimension<Es...>, DimTemplate> =
requires { typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>; } &&
std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit,
typename Es::dimension...>::recipe>;
} // namespace detail
} // namespace detail
template<typename Dim, template<typename...> typename DimTemplate>
concept EquivalentUnknownDimensionOfT = Dimension<Dim> && is_derived_from_specialization_of<Dim, unknown_dimension> && detail::same_exponents_of<Dim, DimTemplate>;
concept EquivalentUnknownDimensionOfT = Dimension<Dim> && is_derived_from_specialization_of<Dim, unknown_dimension> &&
detail::same_exponents_of<Dim, DimTemplate>;
#endif
@ -56,7 +60,7 @@ concept DimensionOfT = Dimension<Dim> && (is_derived_from_specialization_of<Dim,
#if UNITS_DOWNCAST_MODE == 0
|| EquivalentUnknownDimensionOfT<Dim, DimTemplate>
#endif
);
);
/**
* @brief A concept matching all quantities with provided dimension class template

View File

@ -22,6 +22,7 @@
#pragma once
#include <gsl/gsl-lite.hpp>
#include <array>
#include <cassert>
#include <cmath>
@ -29,7 +30,6 @@
#include <numeric>
#include <tuple>
#include <type_traits>
#include <gsl/gsl-lite.hpp>
namespace units::detail {
@ -106,9 +106,9 @@ template<typename T>
// (a 10^e) mod b -> [ (a mod b) (10^e mod b) ] mod b
return std::gcd(
b, static_cast<std::intmax_t>(mulmod(static_cast<std::uint64_t>(a % b),
modpow(10, static_cast<std::uint64_t>(e), static_cast<std::uint64_t>(b)),
static_cast<std::uint64_t>(b))));
b, static_cast<std::intmax_t>(mulmod(static_cast<std::uint64_t>(a % b),
modpow(10, static_cast<std::uint64_t>(e), static_cast<std::uint64_t>(b)),
static_cast<std::uint64_t>(b))));
}
constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
@ -119,8 +119,8 @@ constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
}
// Computes the rational gcd of n1/d1 x 10^e1 and n2/d2 x 10^e2
[[nodiscard]] constexpr auto gcd_frac(std::intmax_t n1, std::intmax_t d1, std::intmax_t e1, std::intmax_t n2, std::intmax_t d2,
std::intmax_t e2) noexcept
[[nodiscard]] constexpr auto gcd_frac(std::intmax_t n1, std::intmax_t d1, std::intmax_t e1, std::intmax_t n2,
std::intmax_t d2, std::intmax_t e2) noexcept
{
// Short cut for equal ratios
if (n1 == n2 && d1 == d2 && e1 == e2) {
@ -153,7 +153,7 @@ constexpr void cwap(std::intmax_t& lhs, std::intmax_t& rhs)
constexpr void normalize(std::intmax_t& num, std::intmax_t& den, std::intmax_t& exp)
{
if(num == 0) {
if (num == 0) {
den = 1;
exp = 0;
return;

View File

@ -33,7 +33,7 @@ namespace units::detail {
template<std::intmax_t N, typename F>
requires gt_zero<N>
[[nodiscard]] constexpr std::intmax_t iroot_impl(std::intmax_t v, F const& pow_function) noexcept
[[nodiscard]] constexpr std::intmax_t iroot_impl(std::intmax_t v, const F& pow_function) noexcept
{
if constexpr (N == 1) {
return v;

View File

@ -24,8 +24,8 @@
#include <units/bits/derived_symbol_text.h>
#include <units/bits/external/text_tools.h>
#include <units/prefix.h>
#include <units/derived_dimension.h>
#include <units/prefix.h>
namespace units::detail {
@ -34,33 +34,25 @@ inline constexpr basic_symbol_text base_multiplier("\u00D7 10", "x 10");
template<ratio R>
constexpr auto ratio_text()
{
if constexpr(R.num == 1 && R.den == 1 && R.exp != 0) {
if constexpr (R.num == 1 && R.den == 1 && R.exp != 0) {
return base_multiplier + superscript<R.exp>();
}
else if constexpr(R.num != 1 || R.den != 1 || R.exp != 0) {
} else if constexpr (R.num != 1 || R.den != 1 || R.exp != 0) {
auto txt = basic_fixed_string("[") + regular<R.num>();
if constexpr(R.den == 1) {
if constexpr(R.exp == 0) {
if constexpr (R.den == 1) {
if constexpr (R.exp == 0) {
return txt + basic_fixed_string("]");
} else {
return txt + " " + base_multiplier + superscript<R.exp>() + basic_fixed_string("]");
}
else {
return txt + " " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
} else {
if constexpr (R.exp == 0) {
return txt + basic_fixed_string("/") + regular<R.den>() + basic_fixed_string("]");
} else {
return txt + basic_fixed_string("/") + regular<R.den>() + " " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
}
}
else {
if constexpr(R.exp == 0) {
return txt + basic_fixed_string("/") + regular<R.den>() +
basic_fixed_string("]");
}
else {
return txt + basic_fixed_string("/") + regular<R.den>() +
" " + base_multiplier + superscript<R.exp>() +
basic_fixed_string("]");
}
}
}
else {
} else {
return basic_fixed_string("");
}
}
@ -68,32 +60,29 @@ constexpr auto ratio_text()
template<ratio R, typename PrefixFamily, std::size_t SymbolLen>
constexpr auto prefix_or_ratio_text()
{
if constexpr(R.num == 1 && R.den == 1 && R.exp == 0) {
if constexpr (R.num == 1 && R.den == 1 && R.exp == 0) {
// no ratio/prefix
return basic_fixed_string("");
}
else {
} else {
if constexpr (!is_same_v<PrefixFamily, no_prefix>) {
// try to form a prefix
using prefix = downcast<detail::prefix_base<PrefixFamily, R>>;
if constexpr(!is_same_v<prefix, prefix_base<PrefixFamily, R>>) {
if constexpr (!is_same_v<prefix, prefix_base<PrefixFamily, R>>) {
// print as a prefixed unit
return prefix::symbol;
}
else {
} else {
// print as a ratio of the coherent unit
constexpr auto txt = ratio_text<R>();
if constexpr(SymbolLen > 0 && txt.standard().size() > 0)
if constexpr (SymbolLen > 0 && txt.standard().size() > 0)
return txt + basic_fixed_string(" ");
else
return txt;
}
}
else {
} else {
// print as a ratio of the coherent unit
constexpr auto txt = ratio_text<R>();
if constexpr(SymbolLen > 0 && txt.standard().size() > 0)
if constexpr (SymbolLen > 0 && txt.standard().size() > 0)
return txt + basic_fixed_string(" ");
else
return txt;
@ -104,7 +93,8 @@ constexpr auto prefix_or_ratio_text()
template<typename... Es, std::size_t... Idxs>
constexpr auto derived_dimension_unit_text(exponent_list<Es...>, std::index_sequence<Idxs...>)
{
return (exp_text<Es, dimension_unit<typename Es::dimension>::symbol, negative_exp_count<Es...>, Idxs>() + ... + basic_symbol_text(basic_fixed_string("")));
return (exp_text<Es, dimension_unit<typename Es::dimension>::symbol, negative_exp_count<Es...>, Idxs>() + ... +
basic_symbol_text(basic_fixed_string("")));
}
template<typename... Es>
@ -120,10 +110,9 @@ template<Exponent Exp>
constexpr auto exponent_list_with_named_units(Exp)
{
using dim = TYPENAME Exp::dimension;
if constexpr(dimension_unit<dim>::is_named) {
if constexpr (dimension_unit<dim>::is_named) {
return exponent_list<Exp>();
}
else {
} else {
using recipe = TYPENAME dim::recipe;
return exponent_list_with_named_units(recipe());
}
@ -135,10 +124,7 @@ constexpr auto exponent_list_with_named_units(exponent_list<Es...>)
return type_list_join<decltype(exponent_list_with_named_units(Es()))...>();
}
constexpr auto exponent_list_with_named_units(exponent_list<> empty)
{
return empty;
}
constexpr auto exponent_list_with_named_units(exponent_list<> empty) { return empty; }
template<Dimension Dim>
constexpr auto derived_dimension_unit_text()
@ -149,29 +135,31 @@ constexpr auto derived_dimension_unit_text()
template<typename T>
// TODO replace with `inline constexpr bool has_symbol` when MSVC cathes up
concept has_symbol = requires{ T::symbol; };
concept has_symbol = requires { T::symbol; };
template<Dimension Dim, Unit U>
constexpr auto unit_text()
{
if constexpr(has_symbol<U>) {
if constexpr (has_symbol<U>) {
// already has a symbol so print it
return U::symbol;
}
else {
} else {
// print as a prefix or ratio of a coherent unit
using coherent_unit = dimension_unit<Dim>;
if constexpr(has_symbol<coherent_unit>) {
if constexpr (has_symbol<coherent_unit>) {
// use predefined coherent unit symbol
constexpr auto symbol_text = coherent_unit::symbol;
constexpr auto prefix_txt = prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family, symbol_text.standard().size()>();
constexpr auto prefix_txt =
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
symbol_text.standard().size()>();
return prefix_txt + symbol_text;
}
else {
} else {
// use derived dimension ingredients to create a unit symbol
constexpr auto symbol_text = derived_dimension_unit_text<Dim>();
constexpr auto prefix_txt = prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family, symbol_text.standard().size()>();
constexpr auto prefix_txt =
prefix_or_ratio_text<U::ratio / coherent_unit::ratio, typename U::reference::prefix_family,
symbol_text.standard().size()>();
return prefix_txt + symbol_text;
}
}

View File

@ -40,14 +40,15 @@ struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
};
template<typename C>
struct clock_origin : point_origin<isq::si::dim_time> { };
struct clock_origin : point_origin<isq::si::dim_time> {};
template<typename C, typename Rep, typename Period>
struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::duration<Rep, Period>>> {
using origin = clock_origin<C>;
using unit = downcast_unit<typename origin::dimension, ratio(Period::num, Period::den)>;
using rep = Rep;
[[nodiscard]] static constexpr auto relative(const std::chrono::time_point<C, std::chrono::duration<Rep, Period>>& qp) {
[[nodiscard]] static constexpr auto relative(const std::chrono::time_point<C, std::chrono::duration<Rep, Period>>& qp)
{
return qp.time_since_epoch();
}
};
@ -61,17 +62,16 @@ constexpr std::intmax_t pow_10(std::intmax_t v)
{
gsl_Expects(v > 0);
std::intmax_t res = 1;
for(std::intmax_t i = 0; i < v; i++)
res *= 10;
for (std::intmax_t i = 0; i < v; i++) res *= 10;
return res;
}
template<ratio R>
constexpr auto to_std_ratio_impl()
{
if constexpr(R.exp == 0)
if constexpr (R.exp == 0)
return std::ratio<R.num, R.den>{};
else if constexpr(R.exp > 0)
else if constexpr (R.exp > 0)
return std::ratio<R.num * pow_10(R.exp), R.den>{};
else
return std::ratio<R.num, R.den * pow_10(-R.exp)>{};
@ -96,4 +96,4 @@ template<typename C, typename U, typename Rep>
return ret_type(to_std_duration(qp.relative()));
}
} // namespace units
} // namespace units

View File

@ -30,11 +30,11 @@ namespace units {
/**
* @brief Specifies if a value of a type should be treated as a floating-point value
*
*
* This type trait should be specialized for a custom representation type to specify
* that values fo this type should be treated by the library as a floating-point ones
* which will enable implicit conversions between quantities.
*
*
* @tparam Rep a representation type for which a type trait is defined
*/
template<typename Rep>
@ -46,40 +46,56 @@ inline constexpr bool treat_as_floating_point<T> = treat_as_floating_point<typen
/**
* @brief A type trait that defines zero, one, min, and max for a representation type
*
*
* The zero, one, min, and max member functions in units::quantity forward their work to
* these methods. This type can be specialized if the representation Rep requires a specific
* implementation to return these quantity objects.
*
*
* @tparam Rep a representation type for which a type trait is defined
*/
template<typename Rep>
struct quantity_values {
static constexpr Rep zero() noexcept
requires std::constructible_from<Rep, int>
{ return Rep(0); }
{
return Rep(0);
}
static constexpr Rep one() noexcept
requires std::constructible_from<Rep, int>
{ return Rep(1); }
{
return Rep(1);
}
static constexpr Rep min() noexcept
requires requires { { std::numeric_limits<Rep>::lowest() } -> std::same_as<Rep>; }
{ return std::numeric_limits<Rep>::lowest(); }
requires requires {
{
std::numeric_limits<Rep>::lowest()
} -> std::same_as<Rep>;
}
{
return std::numeric_limits<Rep>::lowest();
}
static constexpr Rep max() noexcept
requires requires { { std::numeric_limits<Rep>::max() } -> std::same_as<Rep>; }
{ return std::numeric_limits<Rep>::max(); }
requires requires {
{
std::numeric_limits<Rep>::max()
} -> std::same_as<Rep>;
}
{
return std::numeric_limits<Rep>::max();
}
};
/**
* @brief Provides support for external quantity-like types
*
*
* The type trait should provide the following nested type aliases: @c dimension, @c unit, @c rep,
* and a static member function @c number(T) that will return the raw value of the quantity.
*
*
* Usage example can be found in @c units/chrono.h header file.
*
*
* @tparam T the type to provide support for
*/
template<typename T>
@ -87,15 +103,15 @@ struct quantity_like_traits;
/**
* @brief Provides support for external quantity point-like types
*
*
* The type trait should provide the following nested type aliases: @c origin, @c unit, @c rep,
* and a static member function @c relative(T) that will return the quantity-like value of the quantity point.
*
*
* Usage example can be found in @c units/chrono.h header file.
*
*
* @tparam T the type to provide support for
*/
template<typename T>
struct quantity_point_like_traits;
} // namespace units
} // namespace units

View File

@ -40,7 +40,7 @@ namespace detail {
/**
* @brief Converts user provided derived dimension specification into a valid units::derived_dimension_base definition
*
*
* User provided definition of a derived dimension may contain the same base dimension repeated more than once on the
* list possibly hidden in other derived units provided by the user. The process here should:
* 1. Extract derived dimensions into exponents of base dimensions.
@ -49,23 +49,24 @@ namespace detail {
* this base dimension.
*/
template<Exponent... Es>
using make_dimension = TYPENAME to_derived_dimension_base<typename dim_consolidate<type_list_sort<typename dim_unpack<Es...>::type, exponent_less>>::type>::type;
using make_dimension = TYPENAME to_derived_dimension_base<
typename dim_consolidate<type_list_sort<typename dim_unpack<Es...>::type, exponent_less>>::type>::type;
} // namespace detail
/**
* @brief The list of exponents of dimensions (both base and derived) provided by the user
*
*
* This is the user's interface to create derived dimensions. Exponents list can contain powers of factors of both
* base and derived dimensions. This is called a "recipe" of the dimension and among others is used to print
* unnamed coherent units of this dimension.
*
*
* Coherent unit is a unit that, for a given system of quantities and for a chosen set of base units, is a product
* of powers of base units with no other proportionality factor than one.
*
* The implementation is responsible for unpacking all of the dimensions into a list containing only base dimensions
* and their factors and putting them to derived_dimension_base class template.
*
*
* Sometimes units of equivalent quantities in different systems of units do not share the same reference so they
* cannot be easily converted to each other. An example can be a pressure for which a coherent unit in SI is pascal
* and in CGS barye. Those two units are not directly related with each other with some ratio. As they both are
@ -75,7 +76,7 @@ using make_dimension = TYPENAME to_derived_dimension_base<typename dim_consolida
* base_units_ratio of two quantities of equivalent dimensions in two different systems gives a ratio between their
* coherent units. Alternatively, the user would always have to directly define a barye in terms of pascal or vice
* versa.
*
*
* @tparam Child inherited class type used by the downcasting facility (CRTP Idiom)
* @tparam U a coherent unit of a derived dimension
* @tparam Es the list of exponents of ingredient dimensions

View File

@ -46,7 +46,8 @@ namespace units {
* GCC 10) which don't yet permit floating point NTTPs.
*/
template<typename T>
concept BaseRep = std::is_same_v<T, std::intmax_t> || std::is_same_v<std::remove_cvref_t<decltype(T::value)>, long double>;
concept BaseRep = std::is_same_v<T, std::intmax_t> || std::is_same_v < std::remove_cvref_t<decltype(T::value)>,
long double > ;
/**
* @brief A basis vector in our magnitude representation, raised to some rational power.
@ -108,7 +109,7 @@ template<typename T>
inline constexpr bool is_base_power = false;
template<BaseRep T>
inline constexpr bool is_base_power<base_power<T>> = true;
} // namespace detail
} // namespace detail
/**
* @brief Concept to detect whether a _type_ is a valid base power.
@ -119,34 +120,40 @@ inline constexpr bool is_base_power<base_power<T>> = true;
template<typename T>
concept BasePower = detail::is_base_power<T>;
namespace detail
namespace detail {
constexpr auto inverse(BasePower auto bp)
{
constexpr auto inverse(BasePower auto bp) {
bp.power.num *= -1;
return bp;
}
// `widen_t` gives the widest arithmetic type in the same category, for intermediate computations.
template<typename T> requires std::is_arithmetic_v<T>
using widen_t = std::conditional_t<
std::is_floating_point_v<T>,
long double,
std::conditional_t<std::is_signed_v<T>, std::intmax_t, std::uintmax_t>>;
template<typename T>
requires std::is_arithmetic_v<T>
using widen_t = std::conditional_t<std::is_floating_point_v<T>, long double,
std::conditional_t<std::is_signed_v<T>, std::intmax_t, std::uintmax_t>>;
// Raise an arbitrary arithmetic type to a positive integer power at compile time.
template<typename T> requires std::is_arithmetic_v<T>
constexpr T int_power(T base, std::integral auto exp){
template<typename T>
requires std::is_arithmetic_v<T>
constexpr T int_power(T base, std::integral auto exp)
{
// As this function should only be called at compile time, the exceptions herein function as
// "parameter-compatible static_asserts", and should not result in exceptions at runtime.
if (exp < 0) { throw std::invalid_argument{"int_power only supports positive integer powers"}; }
if (exp < 0) {
throw std::invalid_argument{"int_power only supports positive integer powers"};
}
constexpr auto checked_multiply = [] (auto a, auto b) {
constexpr auto checked_multiply = [](auto a, auto b) {
const auto result = a * b;
if (result / a != b) { throw std::overflow_error{"Wraparound detected"}; }
if (result / a != b) {
throw std::overflow_error{"Wraparound detected"};
}
return result;
};
constexpr auto checked_square = [checked_multiply] (auto a) { return checked_multiply(a, a); };
constexpr auto checked_square = [checked_multiply](auto a) { return checked_multiply(a, a); };
// TODO(chogg): Unify this implementation with the one in pow.h. That one takes its exponent as a
// template parameter, rather than a function parameter.
@ -163,7 +170,8 @@ constexpr T int_power(T base, std::integral auto exp){
}
template<typename T> requires std::is_arithmetic_v<T>
template<typename T>
requires std::is_arithmetic_v<T>
constexpr widen_t<T> compute_base_power(BasePower auto bp)
{
// This utility can only handle integer powers. To compute rational powers at compile time, we'll
@ -171,8 +179,12 @@ constexpr widen_t<T> compute_base_power(BasePower auto bp)
//
// Note that since this function should only be called at compile time, the point of these
// exceptions is to act as "static_assert substitutes", not to throw actual exceptions at runtime.
if (bp.power.den != 1) { throw std::invalid_argument{"Rational powers not yet supported"}; }
if (bp.power.exp < 0) { throw std::invalid_argument{"Unsupported exp value"}; }
if (bp.power.den != 1) {
throw std::invalid_argument{"Rational powers not yet supported"};
}
if (bp.power.exp < 0) {
throw std::invalid_argument{"Unsupported exp value"};
}
if (bp.power.num < 0) {
if constexpr (std::is_integral_v<T>) {
@ -191,10 +203,10 @@ constexpr widen_t<T> compute_base_power(BasePower auto bp)
// The input is the desired result, but in a (wider) intermediate type. The point of this function
// is to cast to the desired type, but avoid overflow in doing so.
template<typename To, typename From>
requires std::is_arithmetic_v<To>
&& std::is_arithmetic_v<From>
&& (std::is_integral_v<To> == std::is_integral_v<From>)
constexpr To checked_static_cast(From x) {
requires std::is_arithmetic_v<To> && std::is_arithmetic_v<From> &&
(std::is_integral_v<To> == std::is_integral_v<From>)
constexpr To checked_static_cast(From x)
{
// This function should only ever be called at compile time. The purpose of these exceptions is
// to produce compiler errors, because we cannot `static_assert` on function arguments.
if constexpr (std::is_integral_v<To>) {
@ -209,20 +221,22 @@ constexpr To checked_static_cast(From x) {
return static_cast<To>(x);
}
} // namespace detail
} // namespace detail
/**
* @brief Equality detection for two base powers.
*/
template<BasePower T, BasePower U>
constexpr bool operator==(T t, U u) {
constexpr bool operator==(T t, U u)
{
return std::is_same_v<T, U> && (t.get_base() == u.get_base()) && (t.power == u.power);
}
/**
* @brief A BasePower, raised to a rational power E.
*/
constexpr auto pow(BasePower auto bp, ratio p) {
constexpr auto pow(BasePower auto bp, ratio p)
{
bp.power = bp.power * p;
return bp;
}
@ -233,9 +247,10 @@ namespace detail {
// Find the smallest prime factor of `n`.
constexpr std::intmax_t find_first_factor(std::intmax_t n)
{
for (std::intmax_t f = 2; f * f <= n; f += 1 + (f % 2))
{
if (n % f == 0) { return f; }
for (std::intmax_t f = 2; f * f <= n; f += 1 + (f % 2)) {
if (n % f == 0) {
return f;
}
}
return n;
}
@ -244,8 +259,7 @@ constexpr std::intmax_t find_first_factor(std::intmax_t n)
constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n)
{
std::intmax_t m = 0;
while (n % factor == 0)
{
while (n % factor == 0) {
n /= factor;
++m;
}
@ -257,18 +271,26 @@ constexpr std::intmax_t multiplicity(std::intmax_t factor, std::intmax_t n)
// Undefined unless base > 1, pow >= 0, and (base ^ pow) evenly divides n.
constexpr std::intmax_t remove_power(std::intmax_t base, std::intmax_t pow, std::intmax_t n)
{
while (pow-- > 0) { n /= base; }
while (pow-- > 0) {
n /= base;
}
return n;
}
// A way to check whether a number is prime at compile time.
constexpr bool is_prime(std::intmax_t n) { return (n > 1) && (find_first_factor(n) == n); }
constexpr bool is_valid_base_power(const BasePower auto &bp) {
if (bp.power == 0) { return false; }
constexpr bool is_valid_base_power(const BasePower auto& bp)
{
if (bp.power == 0) {
return false;
}
if constexpr (std::is_same_v<decltype(bp.get_base()), std::intmax_t>) { return is_prime(bp.get_base()); }
else { return bp.get_base() > 0; }
if constexpr (std::is_same_v<decltype(bp.get_base()), std::intmax_t>) {
return is_prime(bp.get_base());
} else {
return bp.get_base() > 0;
}
}
// A function object to apply a predicate to all consecutive pairs of values in a sequence.
@ -277,16 +299,19 @@ struct pairwise_all {
Predicate predicate;
template<typename... Ts>
constexpr bool operator()(Ts&&... ts) const {
constexpr bool operator()(Ts&&... ts) const
{
// Carefully handle different sizes, avoiding unsigned integer underflow.
constexpr auto num_comparisons = [](auto num_elements) {
return (num_elements > 1) ? (num_elements - 1) : 0;
}(sizeof...(Ts));
// Compare zero or more pairs of neighbours as needed.
return [this]<std::size_t... Is>(std::tuple<Ts...> &&t, std::index_sequence<Is...>) {
return [this]<std::size_t... Is>(std::tuple<Ts...> && t, std::index_sequence<Is...>)
{
return (predicate(std::get<Is>(t), std::get<Is + 1>(t)) && ...);
}(std::make_tuple(std::forward<Ts>(ts)...), std::make_index_sequence<num_comparisons>());
}
(std::make_tuple(std::forward<Ts>(ts)...), std::make_index_sequence<num_comparisons>());
}
};
@ -296,8 +321,9 @@ pairwise_all(T) -> pairwise_all<T>;
// Check whether a sequence of (possibly heterogeneously typed) values are strictly increasing.
template<typename... Ts>
requires (std::is_signed_v<Ts> && ...)
constexpr bool strictly_increasing(Ts&&... ts) {
requires(std::is_signed_v<Ts> && ...)
constexpr bool strictly_increasing(Ts&&... ts)
{
return pairwise_all{std::less{}}(std::forward<Ts>(ts)...);
}
@ -310,14 +336,13 @@ inline constexpr bool all_bases_in_order = strictly_increasing(BPs.get_base()...
template<BasePower auto... BPs>
inline constexpr bool is_base_power_pack_valid = all_base_powers_valid<BPs...> && all_bases_in_order<BPs...>;
constexpr bool is_rational(BasePower auto bp) {
constexpr bool is_rational(BasePower auto bp)
{
return std::is_integral_v<decltype(bp.get_base())> && (bp.power.den == 1) && (bp.power.exp >= 0);
}
constexpr bool is_integral(BasePower auto bp) {
return is_rational(bp) && bp.power.num > 0;
}
} // namespace detail
constexpr bool is_integral(BasePower auto bp) { return is_rational(bp) && bp.power.num > 0; }
} // namespace detail
/**
* @brief A representation for positive real numbers which optimizes taking products and rational powers.
@ -341,7 +366,7 @@ template<typename T>
inline constexpr bool is_magnitude = false;
template<BasePower auto... BPs>
inline constexpr bool is_magnitude<magnitude<BPs...>> = true;
} // namespace detail
} // namespace detail
/**
* @brief Concept to detect whether T is a valid Magnitude.
@ -354,7 +379,8 @@ concept Magnitude = detail::is_magnitude<T>;
*/
template<typename T, BasePower auto... BPs>
requires std::is_floating_point_v<T> || (std::is_integral_v<T> && is_integral(magnitude<BPs...>{}))
constexpr T get_value(const magnitude<BPs...> &) {
constexpr T get_value(const magnitude<BPs...>&)
{
// Force the expression to be evaluated in a constexpr context, to catch, e.g., overflow.
constexpr auto result = detail::checked_static_cast<T>((detail::compute_base_power<T>(BPs) * ...));
@ -372,18 +398,26 @@ struct pi_base {
// Magnitude equality implementation.
template<BasePower auto... LeftBPs, BasePower auto... RightBPs>
constexpr bool operator==(magnitude<LeftBPs...>, magnitude<RightBPs...>) {
if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) { return ((LeftBPs == RightBPs) && ...); }
else { return false; }
constexpr bool operator==(magnitude<LeftBPs...>, magnitude<RightBPs...>)
{
if constexpr (sizeof...(LeftBPs) == sizeof...(RightBPs)) {
return ((LeftBPs == RightBPs) && ...);
} else {
return false;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Magnitude rational powers implementation.
template<ratio E, BasePower auto... BPs>
constexpr auto pow(magnitude<BPs...>) {
if constexpr (E == 0) { return magnitude<>{}; }
else { return magnitude<pow(BPs, E)...>{}; }
constexpr auto pow(magnitude<BPs...>)
{
if constexpr (E == 0) {
return magnitude<>{};
} else {
return magnitude<pow(BPs, E)...>{};
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -396,9 +430,10 @@ constexpr auto operator*(Magnitude auto m, magnitude<>) { return m; }
// Recursive case for the product of any two non-identity Magnitudes.
template<BasePower auto H1, BasePower auto... T1, BasePower auto H2, BasePower auto... T2>
constexpr auto operator*(magnitude<H1, T1...>, magnitude<H2, T2...>) {
constexpr auto operator*(magnitude<H1, T1...>, magnitude<H2, T2...>)
{
// Case for when H1 has the smaller base.
if constexpr(H1.get_base() < H2.get_base()){
if constexpr (H1.get_base() < H2.get_base()) {
if constexpr (sizeof...(T1) == 0) {
// Shortcut for the "pure prepend" case, which makes it easier to implement some of the other cases.
return magnitude<H1, H2, T2...>{};
@ -408,7 +443,7 @@ constexpr auto operator*(magnitude<H1, T1...>, magnitude<H2, T2...>) {
}
// Case for when H2 has the smaller base.
if constexpr(H1.get_base() > H2.get_base()){
if constexpr (H1.get_base() > H2.get_base()) {
return magnitude<H2>{} * (magnitude<H1, T1...>{} * magnitude<T2...>{});
}
@ -441,23 +476,25 @@ constexpr auto operator/(Magnitude auto l, Magnitude auto r) { return l * pow<-1
namespace detail {
// Helper to perform prime factorization at compile time.
template<std::intmax_t N>
requires (N > 0)
requires(N > 0)
struct prime_factorization {
static constexpr std::intmax_t first_base = find_first_factor(N);
static constexpr std::intmax_t first_power = multiplicity(first_base, N);
static constexpr std::intmax_t remainder = remove_power(first_base, first_power, N);
static constexpr auto value = magnitude<base_power{first_base, first_power}>{}
* prime_factorization<remainder>::value;
static constexpr auto value =
magnitude<base_power{first_base, first_power}>{} * prime_factorization<remainder>::value;
};
// Specialization for the prime factorization of 1 (base case).
template<>
struct prime_factorization<1> { static constexpr magnitude<> value{}; };
struct prime_factorization<1> {
static constexpr magnitude<> value{};
};
template<std::intmax_t N>
inline constexpr auto prime_factorization_v = prime_factorization<N>::value;
} // namespace detail
} // namespace detail
/**
* @brief Convert any positive integer to a Magnitude.
@ -466,11 +503,11 @@ inline constexpr auto prime_factorization_v = prime_factorization<N>::value;
* manually adding base powers.
*/
template<ratio R>
requires (R.num > 0)
constexpr Magnitude auto as_magnitude() {
return pow<R.exp>(detail::prime_factorization_v<10>)
* detail::prime_factorization_v<R.num>
/ detail::prime_factorization_v<R.den>;
requires(R.num > 0)
constexpr Magnitude auto as_magnitude()
{
return pow<R.exp>(detail::prime_factorization_v<10>) * detail::prime_factorization_v<R.num> /
detail::prime_factorization_v<R.den>;
}
} // namespace units
} // namespace units

View File

@ -60,7 +60,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Quantity Q>
using unit = downcast_unit<dim, pow<Num, Den>(Q::unit::ratio)>;
using std::pow;
return quantity<dim, unit, rep>(
static_cast<rep>(pow(q.number(), static_cast<double>(Num) / static_cast<double>(Den))));
static_cast<rep>(pow(q.number(), static_cast<double>(Num) / static_cast<double>(Den))));
}
}
@ -74,7 +74,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Quantity Q>
*/
template<Quantity Q>
[[nodiscard]] inline Quantity auto sqrt(const Q& q) noexcept
requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); }
requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); }
{
using dim = dimension_pow<typename Q::dimension, 1, 2>;
using unit = downcast_unit<dim, sqrt(Q::unit::ratio)>;
@ -126,7 +126,7 @@ template<typename U, typename Rep>
*/
template<typename D, typename U, typename Rep>
[[nodiscard]] inline quantity<D, U, Rep> abs(const quantity<D, U, Rep>& q) noexcept
requires requires { abs(q.number()); } || requires { std::abs(q.number()); }
requires requires { abs(q.number()); } || requires { std::abs(q.number()); }
{
using std::abs;
return quantity<D, U, Rep>(abs(q.number()));
@ -155,13 +155,12 @@ template<Quantity Q>
*/
template<Unit To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr quantity<D, To, Rep> floor(const quantity<D, U, Rep>& q) noexcept
requires ((!treat_as_floating_point<Rep>) ||
requires { floor(q.number()); } ||
requires { std::floor(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::quantity_cast<To>(q);
quantity<D, To, Rep>::one();
})
requires((!treat_as_floating_point<Rep>) || requires { floor(q.number()); } ||
requires { std::floor(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::quantity_cast<To>(q);
quantity<D, To, Rep>::one();
})
{
const auto handle_signed_results = [&]<typename T>(const T& res) {
if (res > q) {
@ -169,20 +168,17 @@ template<Unit To, typename D, typename U, typename Rep>
}
return res;
};
if constexpr(treat_as_floating_point<Rep>) {
if constexpr (treat_as_floating_point<Rep>) {
using std::floor;
if constexpr(std::is_same_v<To, U>) {
if constexpr (std::is_same_v<To, U>) {
return quantity<D, To, Rep>(floor(q.number()));
}
else {
} else {
return handle_signed_results(quantity<D, To, Rep>(floor(quantity_cast<To>(q).number())));
}
}
else {
if constexpr(std::is_same_v<To, U>) {
} else {
if constexpr (std::is_same_v<To, U>) {
return q;
}
else {
} else {
return handle_signed_results(quantity_cast<To>(q));
}
}
@ -209,13 +205,11 @@ template<Quantity To, std::same_as<typename To::dimension> D, typename U, std::s
*/
template<Unit To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr quantity<D, To, Rep> ceil(const quantity<D, U, Rep>& q) noexcept
requires ((!treat_as_floating_point<Rep>) ||
requires { ceil(q.number()); } ||
requires { std::ceil(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::quantity_cast<To>(q);
quantity<D, To, Rep>::one();
})
requires((!treat_as_floating_point<Rep>) || requires { ceil(q.number()); } || requires { std::ceil(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::quantity_cast<To>(q);
quantity<D, To, Rep>::one();
})
{
const auto handle_signed_results = [&]<typename T>(const T& res) {
if (res < q) {
@ -223,20 +217,17 @@ template<Unit To, typename D, typename U, typename Rep>
}
return res;
};
if constexpr(treat_as_floating_point<Rep>) {
if constexpr (treat_as_floating_point<Rep>) {
using std::ceil;
if constexpr(std::is_same_v<To, U>) {
if constexpr (std::is_same_v<To, U>) {
return quantity<D, To, Rep>(ceil(q.number()));
}
else {
} else {
return handle_signed_results(quantity<D, To, Rep>(ceil(quantity_cast<To>(q).number())));
}
}
else {
if constexpr(std::is_same_v<To, U>) {
} else {
if constexpr (std::is_same_v<To, U>) {
return q;
}
else {
} else {
return handle_signed_results(quantity_cast<To>(q));
}
}
@ -265,24 +256,21 @@ template<Quantity To, std::same_as<typename To::dimension> D, typename U, std::s
*/
template<Unit To, typename D, typename U, typename Rep>
[[nodiscard]] constexpr quantity<D, To, Rep> round(const quantity<D, U, Rep>& q) noexcept
requires ((!treat_as_floating_point<Rep>) ||
requires { round(q.number()); } ||
requires { std::round(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::floor<To>(q);
quantity<D, To, Rep>::one();
})
requires((!treat_as_floating_point<Rep>) || requires { round(q.number()); } ||
requires { std::round(q.number()); }) &&
(std::same_as<To, U> || requires {
::units::floor<To>(q);
quantity<D, To, Rep>::one();
})
{
if constexpr(std::is_same_v<To, U>) {
if constexpr(treat_as_floating_point<Rep>) {
if constexpr (std::is_same_v<To, U>) {
if constexpr (treat_as_floating_point<Rep>) {
using std::round;
return quantity<D, To, Rep>(round(q.number()));
}
else {
} else {
return q;
}
}
else {
} else {
const auto res_low = units::floor<To>(q);
const auto res_high = res_low + decltype(res_low)::one();
const auto diff0 = q - res_low;

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/bits/external/downcasting.h>
#include <units/bits/basic_concepts.h>
#include <units/bits/external/downcasting.h>
// IWYU pragma: begin_exports
#include <units/ratio.h>
#include <units/symbol_text.h>
@ -72,7 +72,7 @@ struct prefix_base : downcast_base<prefix_base<PF, R>> {
* @tparam R factor to be used to scale a unit
*/
template<typename Child, PrefixFamily PF, basic_symbol_text Symbol, ratio R>
requires (!std::same_as<PF, no_prefix>)
requires(!std::same_as<PF, no_prefix>)
struct prefix : downcast_dispatch<Child, detail::prefix_base<PF, R>, downcast_mode::on> {
static constexpr auto symbol = Symbol;
};

View File

@ -48,50 +48,38 @@ inline constexpr auto make_quantity = [](auto&& v) {
} // namespace detail
template<typename T>
concept floating_point_ = // exposition only
(Quantity<T> && treat_as_floating_point<typename T::rep>) ||
(!Quantity<T> && treat_as_floating_point<T>);
concept floating_point_ = // exposition only
(Quantity<T> && treat_as_floating_point<typename T::rep>) || (!Quantity<T> && treat_as_floating_point<T>);
template<typename From, typename To>
concept safe_convertible_to_ = // exposition only
(!Quantity<From>) &&
(!Quantity<To>) &&
std::convertible_to<From, To> &&
(floating_point_<To> || (!floating_point_<From>));
concept safe_convertible_to_ = // exposition only
(!Quantity<From>) && (!Quantity<To>) && std::convertible_to<From, To> &&
(floating_point_<To> || (!floating_point_<From>));
// QFrom ratio is an exact multiple of QTo
template<typename QFrom, typename QTo>
concept harmonic_ = // exposition only
Quantity<QFrom> &&
Quantity<QTo> &&
is_integral(detail::quantity_ratio<QFrom> / detail::quantity_ratio<QTo>);
concept harmonic_ = // exposition only
Quantity<QFrom> && Quantity<QTo> && is_integral(detail::quantity_ratio<QFrom> / detail::quantity_ratio<QTo>);
template<typename QFrom, typename QTo>
concept safe_castable_to_ = // exposition only
Quantity<QFrom> &&
QuantityOf<QTo, typename QFrom::dimension> &&
scalable_with_<typename QFrom::rep, typename QTo::rep> &&
(floating_point_<QTo> || (!floating_point_<QFrom> && harmonic_<QFrom, QTo>));
concept safe_castable_to_ = // exposition only
Quantity<QFrom> && QuantityOf<QTo, typename QFrom::dimension> &&
scalable_with_<typename QFrom::rep, typename QTo::rep> &&
(floating_point_<QTo> || (!floating_point_<QFrom> && harmonic_<QFrom, QTo>));
template<typename Func, typename T, typename U>
concept quantity_value_for_ =
std::regular_invocable<Func, T, U> &&
Representation<std::invoke_result_t<Func, T, U>>;
concept quantity_value_for_ = std::regular_invocable<Func, T, U> && Representation<std::invoke_result_t<Func, T, U>>;
template<typename T, typename Func, typename U, typename V>
concept invoke_result_convertible_to_ =
Representation<T> &&
quantity_value_for_<Func, U, V> &&
safe_convertible_to_<T, std::invoke_result_t<Func, U, V>>;
Representation<T> && quantity_value_for_<Func, U, V> && safe_convertible_to_<T, std::invoke_result_t<Func, U, V>>;
template<typename Func, typename Q, typename V>
concept have_quantity_for_ =
Quantity<Q> &&
(!Quantity<V>) &&
quantity_value_for_<Func, typename Q::rep, V>;
concept have_quantity_for_ = Quantity<Q> && (!Quantity<V>) && quantity_value_for_<Func, typename Q::rep, V>;
template<QuantityLike Q>
using quantity_like_type = quantity<typename quantity_like_traits<Q>::dimension, typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
using quantity_like_type = quantity<typename quantity_like_traits<Q>::dimension, typename quantity_like_traits<Q>::unit,
typename quantity_like_traits<Q>::rep>;
/**
* @brief A quantity
@ -144,76 +132,110 @@ public:
quantity(quantity&&) = default;
template<typename Value>
requires safe_convertible_to_<std::remove_cvref_t<Value>, rep>
constexpr explicit(!(std::same_as<dimension, dim_one> && std::same_as<unit, ::units::one>))
quantity(Value&& v) : number_(std::forward<Value>(v)) {}
requires(safe_convertible_to_<std::remove_cvref_t<Value>, rep>)
constexpr explicit(!(std::same_as<dimension, dim_one> && std::same_as<unit, ::units::one>)) quantity(Value&& v) :
number_(std::forward<Value>(v))
{
}
template<safe_castable_to_<quantity> Q>
constexpr explicit(false) quantity(const Q& q) : number_(quantity_cast<quantity>(q).number()) {}
constexpr explicit(false) quantity(const Q& q) : number_(quantity_cast<quantity>(q).number())
{
}
template<QuantityLike Q>
requires safe_castable_to_<quantity_like_type<Q>, quantity>
constexpr explicit quantity(const Q& q) : quantity(quantity_like_type<Q>(quantity_like_traits<Q>::number(q))) {}
requires(safe_castable_to_<quantity_like_type<Q>, quantity>)
constexpr explicit quantity(const Q& q) : quantity(quantity_like_type<Q>(quantity_like_traits<Q>::number(q)))
{
}
quantity& operator=(const quantity&) = default;
quantity& operator=(quantity&&) = default;
// data access
[[nodiscard]] constexpr rep& number() & noexcept { return number_; }
[[nodiscard]] constexpr const rep& number() const & noexcept { return number_; }
[[nodiscard]] constexpr const rep& number() const& noexcept { return number_; }
[[nodiscard]] constexpr rep&& number() && noexcept { return std::move(number_); }
[[nodiscard]] constexpr const rep&& number() const && noexcept { return std::move(number_); }
[[nodiscard]] constexpr const rep&& number() const&& noexcept { return std::move(number_); }
// member unary operators
[[nodiscard]] constexpr Quantity auto operator+() const
requires requires(rep v) { { +v } -> std::common_with<rep>; }
requires requires(rep v) {
{
+v
} -> std::common_with<rep>;
}
{
using ret = quantity<D, U, decltype(+number())>;
return ret(+number());
}
[[nodiscard]] constexpr Quantity auto operator-() const
requires std::regular_invocable<std::negate<>, rep>
requires(std::regular_invocable<std::negate<>, rep>)
{
using ret = quantity<D, U, decltype(-number())>;
return ret(-number());
}
constexpr quantity& operator++()
requires requires(rep v) { { ++v } -> std::same_as<rep&>; }
requires requires(rep v) {
{
++v
} -> std::same_as<rep&>;
}
{
++number_;
return *this;
}
[[nodiscard]] constexpr quantity operator++(int)
requires requires(rep v) { { v++ } -> std::same_as<rep>; }
requires requires(rep v) {
{
v++
} -> std::same_as<rep>;
}
{
return quantity(number_++);
}
constexpr quantity& operator--()
requires requires(rep v) { { --v } -> std::same_as<rep&>; }
requires requires(rep v) {
{
--v
} -> std::same_as<rep&>;
}
{
--number_;
return *this;
}
[[nodiscard]] constexpr quantity operator--(int)
requires requires(rep v) { { v-- } -> std::same_as<rep>; }
requires requires(rep v) {
{
v--
} -> std::same_as<rep>;
}
{
return quantity(number_--);
}
constexpr quantity& operator+=(const quantity& q)
requires requires(rep a, rep b) { { a += b } -> std::same_as<rep&>; }
requires requires(rep a, rep b) {
{
a += b
} -> std::same_as<rep&>;
}
{
number_ += q.number();
return *this;
}
constexpr quantity& operator-=(const quantity& q)
requires requires(rep a, rep b) { { a -= b } -> std::same_as<rep&>; }
requires requires(rep a, rep b) {
{
a -= b
} -> std::same_as<rep&>;
}
{
number_ -= q.number();
return *this;
@ -221,14 +243,22 @@ public:
template<typename Rep2>
constexpr quantity& operator*=(const Rep2& rhs)
requires requires(rep a, const Rep2 b) { { a *= b } -> std::same_as<rep&>; }
requires requires(rep a, const Rep2 b) {
{
a *= b
} -> std::same_as<rep&>;
}
{
number_ *= rhs;
return *this;
}
template<typename Rep2>
constexpr quantity& operator*=(const dimensionless<units::one, Rep2>& rhs)
requires requires(rep a, const Rep2 b) { { a *= b } -> std::same_as<rep&>; }
requires requires(rep a, const Rep2 b) {
{
a *= b
} -> std::same_as<rep&>;
}
{
number_ *= rhs.number();
return *this;
@ -236,7 +266,11 @@ public:
template<typename Rep2>
constexpr quantity& operator/=(const Rep2& rhs)
requires requires(rep a, const Rep2 b) { { a /= b } -> std::same_as<rep&>; }
requires requires(rep a, const Rep2 b) {
{
a /= b
} -> std::same_as<rep&>;
}
{
gsl_ExpectsAudit(rhs != quantity_values<Rep2>::zero());
number_ /= rhs;
@ -244,7 +278,11 @@ public:
}
template<typename Rep2>
constexpr quantity& operator/=(const dimensionless<units::one, Rep2>& rhs)
requires requires(rep a, const Rep2 b) { { a /= b } -> std::same_as<rep&>; }
requires requires(rep a, const Rep2 b) {
{
a /= b
} -> std::same_as<rep&>;
}
{
gsl_ExpectsAudit(rhs.number() != quantity_values<Rep2>::zero());
number_ /= rhs.number();
@ -253,8 +291,11 @@ public:
template<typename Rep2>
constexpr quantity& operator%=(const Rep2& rhs)
requires (!floating_point_<rep>) && (!floating_point_<Rep2>) &&
requires(rep a, const Rep2 b) { { a %= b } -> std::same_as<rep&>; }
requires(!floating_point_<rep>) && (!floating_point_<Rep2>) && requires(rep a, const Rep2 b) {
{
a %= b
} -> std::same_as<rep&>;
}
{
gsl_ExpectsAudit(rhs != quantity_values<Rep2>::zero());
number_ %= rhs;
@ -263,8 +304,11 @@ public:
template<typename Rep2>
constexpr quantity& operator%=(const dimensionless<units::one, Rep2>& rhs)
requires (!floating_point_<rep>) && (!floating_point_<Rep2>) &&
requires(rep a, const Rep2 b) { { a %= b } -> std::same_as<rep&>; }
requires(!floating_point_<rep>) && (!floating_point_<Rep2>) && requires(rep a, const Rep2 b) {
{
a %= b
} -> std::same_as<rep&>;
}
{
gsl_ExpectsAudit(rhs.number() != quantity_values<Rep2>::zero());
number_ %= rhs.number();
@ -272,8 +316,11 @@ public:
}
constexpr quantity& operator%=(const quantity& q)
requires (!floating_point_<rep>) &&
requires(rep a, rep b) { { a %= b } -> std::same_as<rep&>; }
requires(!floating_point_<rep>) && requires(rep a, rep b) {
{
a %= b
} -> std::same_as<rep&>;
}
{
gsl_ExpectsAudit(q.number() != quantity_values<rep>::zero());
number_ %= q.number();
@ -284,36 +331,48 @@ public:
// Below friend functions are to be found via argument-dependent lookup only
template<typename Value>
[[nodiscard]] friend constexpr Quantity auto operator+(const quantity& lhs, const Value& rhs)
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::plus<>, rep, Value>; } // when Clang catches up.
requires requires {
requires !Quantity<Value>;
requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::plus<>, rep, Value>;
} // when Clang catches up.
{
return units::quantity(lhs.number() + rhs);
}
template<typename Value>
[[nodiscard]] friend constexpr Quantity auto operator+(const Value& lhs, const quantity& rhs)
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::plus<>, Value, rep>; } // when Clang catches up.
requires requires {
requires !Quantity<Value>;
requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::plus<>, Value, rep>;
} // when Clang catches up.
{
return units::quantity(lhs + rhs.number());
}
template<typename Value>
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity& lhs, const Value& rhs)
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::minus<>, rep, Value>; } // when Clang catches up.
requires requires {
requires !Quantity<Value>;
requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::minus<>, rep, Value>;
} // when Clang catches up.
{
return units::quantity(lhs.number() - rhs);
}
template<typename Value>
[[nodiscard]] friend constexpr Quantity auto operator-(const Value& lhs, const quantity& rhs)
requires requires { requires !Quantity<Value>; requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::minus<>, Value, rep>; } // when Clang catches up.
requires requires {
requires !Quantity<Value>;
requires is_same_v<unit, units::one>; // TODO: Simplify
requires invoke_result_convertible_to_<rep, std::minus<>, Value, rep>;
} // when Clang catches up.
{
return units::quantity(lhs - rhs.number());
}
template<Representation Value>
requires invoke_result_convertible_to_<rep, std::multiplies<>, rep, const Value&>
requires(invoke_result_convertible_to_<rep, std::multiplies<>, rep, const Value&>)
[[nodiscard]] friend constexpr Quantity auto operator*(const quantity& q, const Value& v)
{
using ret = quantity<D, U, std::invoke_result_t<std::multiplies<>, rep, Value>>;
@ -321,7 +380,7 @@ public:
}
template<Representation Value>
requires invoke_result_convertible_to_<rep, std::multiplies<>, const Value&, rep>
requires(invoke_result_convertible_to_<rep, std::multiplies<>, const Value&, rep>)
[[nodiscard]] friend constexpr Quantity auto operator*(const Value& v, const quantity& q)
{
using ret = quantity<D, U, std::invoke_result_t<std::multiplies<>, Value, rep>>;
@ -329,8 +388,7 @@ public:
}
template<typename Value>
requires (!Quantity<Value>) &&
invoke_result_convertible_to_<rep, std::divides<>, rep, const Value&>
requires(!Quantity<Value>) && (invoke_result_convertible_to_<rep, std::divides<>, rep, const Value&>)
[[nodiscard]] friend constexpr Quantity auto operator/(const quantity& q, const Value& v)
{
gsl_ExpectsAudit(v != quantity_values<Value>::zero());
@ -339,8 +397,7 @@ public:
}
template<typename Value>
requires (!Quantity<Value>) &&
invoke_result_convertible_to_<rep, std::divides<>, const Value&, rep>
requires(!Quantity<Value>) && (invoke_result_convertible_to_<rep, std::divides<>, const Value&, rep>)
[[nodiscard]] friend constexpr Quantity auto operator/(const Value& v, const quantity& q)
{
gsl_ExpectsAudit(q.number() != quantity_values<rep>::zero());
@ -351,8 +408,8 @@ public:
}
template<typename Value>
requires (!Quantity<Value>) && (!floating_point_<rep>) && (!floating_point_<Value>) &&
invoke_result_convertible_to_<rep, std::modulus<>, rep, const Value&>
requires(!Quantity<Value>) && (!floating_point_<rep>) && (!floating_point_<Value>) &&
(invoke_result_convertible_to_<rep, std::modulus<>, rep, const Value&>)
[[nodiscard]] friend constexpr Quantity auto operator%(const quantity& q, const Value& v)
{
gsl_ExpectsAudit(v != quantity_values<Value>::zero());
@ -361,8 +418,7 @@ public:
}
[[nodiscard]] friend constexpr Quantity auto operator%(const quantity& lhs, const quantity& rhs)
requires (!floating_point_<rep>) &&
invoke_result_convertible_to_<rep, std::modulus<>, rep, rep>
requires(!floating_point_<rep>) && (invoke_result_convertible_to_<rep, std::modulus<>, rep, rep>)
{
gsl_ExpectsAudit(rhs.number() != quantity_values<rep>::zero());
using ret = quantity<D, U, std::invoke_result_t<std::modulus<>, rep, rep>>;
@ -385,18 +441,19 @@ public:
// CTAD
#if !UNITS_COMP_CLANG || UNITS_COMP_CLANG > 15
template<typename D, typename U, typename Rep>
explicit(false) quantity(Rep&&) -> quantity<D, U, Rep>;
explicit(false) quantity(Rep&&)->quantity<D, U, Rep>;
#endif
template<Representation Rep>
explicit(false) quantity(Rep) -> quantity<dim_one, one, Rep>;
explicit(false) quantity(Rep)->quantity<dim_one, one, Rep>;
template<QuantityLike Q>
explicit quantity(Q) -> quantity<typename quantity_like_traits<Q>::dimension, typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
explicit quantity(Q) -> quantity<typename quantity_like_traits<Q>::dimension, typename quantity_like_traits<Q>::unit,
typename quantity_like_traits<Q>::rep>;
// non-member binary operators
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
requires quantity_value_for_<std::plus<>, typename Q1::rep, typename Q2::rep>
requires(quantity_value_for_<std::plus<>, typename Q1::rep, typename Q2::rep>)
[[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs)
{
using ref = detail::common_quantity_reference<Q1, Q2>;
@ -405,7 +462,7 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
}
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
requires quantity_value_for_<std::minus<>, typename Q1::rep, typename Q2::rep>
requires(quantity_value_for_<std::minus<>, typename Q1::rep, typename Q2::rep>)
[[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs)
{
using ref = detail::common_quantity_reference<Q1, Q2>;
@ -414,14 +471,14 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
}
template<Quantity Q1, Quantity Q2>
requires quantity_value_for_<std::multiplies<>, typename Q1::rep, typename Q2::rep>
requires(quantity_value_for_<std::multiplies<>, typename Q1::rep, typename Q2::rep>)
[[nodiscard]] constexpr Quantity auto operator*(const Q1& lhs, const Q2& rhs)
{
return detail::make_quantity<Q1::reference * Q2::reference>(lhs.number() * rhs.number());
}
template<Quantity Q1, Quantity Q2>
requires quantity_value_for_<std::divides<>, typename Q1::rep, typename Q2::rep>
requires(quantity_value_for_<std::divides<>, typename Q1::rep, typename Q2::rep>)
[[nodiscard]] constexpr Quantity auto operator/(const Q1& lhs, const Q2& rhs)
{
gsl_ExpectsAudit(rhs.number() != quantity_values<typename Q2::rep>::zero());
@ -429,13 +486,14 @@ template<Quantity Q1, Quantity Q2>
}
template<Quantity Q1, Quantity Q2>
requires (!floating_point_<typename Q1::rep>) && (!floating_point_<typename Q2::rep>) &&
requires(!floating_point_<typename Q1::rep>) && (!floating_point_<typename Q2::rep>) &&
(QuantityEquivalentTo<Q2, Q1> || Dimensionless<Q2>) &&
quantity_value_for_<std::modulus<>, typename Q1::rep, typename Q2::rep>
(quantity_value_for_<std::modulus<>, typename Q1::rep, typename Q2::rep>)
[[nodiscard]] constexpr Quantity auto operator%(const Q1& lhs, const Q2& rhs)
{
gsl_ExpectsAudit(rhs.number() != quantity_values<typename Q2::rep>::zero());
using ret = quantity<typename Q1::dimension, typename Q1::unit, std::invoke_result_t<std::modulus<>, typename Q1::rep, typename Q2::rep>>;
using ret = quantity<typename Q1::dimension, typename Q1::unit,
std::invoke_result_t<std::modulus<>, typename Q1::rep, typename Q2::rep>>;
return ret(lhs.number() % rhs.number());
}
@ -462,7 +520,7 @@ template<typename D, typename U, typename Rep>
inline constexpr bool is_quantity<quantity<D, U, Rep>> = true;
template<typename T>
requires units::is_derived_from_specialization_of<T, units::quantity>
requires units::is_derived_from_specialization_of<T, units::quantity>
inline constexpr bool is_quantity<T> = true;
} // namespace detail

View File

@ -22,14 +22,15 @@
#pragma once
#include <units/concepts.h>
#include <units/customization_points.h>
#include <units/bits/dimension_op.h>
#include <units/bits/external/type_traits.h>
#include <units/bits/pow.h>
#include <units/concepts.h>
#include <units/customization_points.h>
UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA // warning C4244: 'argument': conversion from 'intmax_t' to 'T', possible loss of data with T=int
// warning C4244: 'argument': conversion from 'intmax_t' to 'T', possible loss of data with T=int
UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA
namespace units {
@ -48,28 +49,24 @@ class quantity_point_kind;
namespace detail {
template<typename T>
inline constexpr ratio quantity_ratio = std::enable_if_t<!Quantity<T>>{};
inline constexpr ratio quantity_ratio = std::enable_if_t<!Quantity<T>>{};
template<typename D, typename U, typename Rep>
inline constexpr ratio quantity_ratio<quantity<D, U, Rep>> = []
{
if constexpr(BaseDimension<D>) {
inline constexpr ratio quantity_ratio<quantity<D, U, Rep>> = [] {
if constexpr (BaseDimension<D>) {
return U::ratio;
}
else {
} else {
return D::base_units_ratio * U::ratio / D::coherent_unit::ratio;
}
}();
template<typename QFrom, typename QTo>
inline constexpr ratio cast_ratio = []
{
inline constexpr ratio cast_ratio = [] {
using FromU = TYPENAME QFrom::unit;
using ToU = TYPENAME QTo::unit;
if constexpr(same_unit_reference<FromU, ToU>::value) {
if constexpr (same_unit_reference<FromU, ToU>::value) {
return FromU::ratio / ToU::ratio;
}
else {
} else {
return quantity_ratio<QFrom> / quantity_ratio<QTo>;
}
}();
@ -78,18 +75,17 @@ template<typename From, typename To>
struct cast_traits;
template<typename From, typename To>
requires common_type_with_<std::common_type_t<From, To>, std::intmax_t>
struct cast_traits<From, To> {
requires common_type_with_<std::common_type_t<From, To>,
std::intmax_t> struct cast_traits<From, To> {
using ratio_type = std::common_type_t<std::common_type_t<From, To>, std::intmax_t>;
using rep_type = ratio_type;
};
template<typename From, typename To>
requires (!common_type_with_<std::common_type_t<From, To>, std::intmax_t>) &&
scalable_number_<std::common_type_t<From, To>, std::intmax_t> &&
requires { typename std::common_type_t<From, To>::value_type; } &&
common_type_with_<typename std::common_type_t<From, To>::value_type, std::intmax_t>
struct cast_traits<From, To> {
requires(!common_type_with_<std::common_type_t<From, To>, std::intmax_t>) &&
scalable_number_<std::common_type_t<From, To>,
std::intmax_t>&& requires { typename std::common_type_t<From, To>::value_type; } &&
common_type_with_<typename std::common_type_t<From, To>::value_type, std::intmax_t> struct cast_traits<From, To> {
using ratio_type = std::common_type_t<typename std::common_type_t<From, To>::value_type, std::intmax_t>;
using rep_type = std::common_type_t<From, To>;
};
@ -109,7 +105,7 @@ struct cast_traits<From, To> {
* @tparam To a target quantity type to cast to
*/
template<Quantity To, typename D, typename U, scalable_with_<typename To::rep> Rep>
requires QuantityOf<To, D> && std::constructible_from<typename To::rep, std::common_type_t<typename To::rep, Rep>>
requires QuantityOf<To, D> && (std::constructible_from<typename To::rep, std::common_type_t<typename To::rep, Rep>>)
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
{
using traits = detail::cast_traits<Rep, typename To::rep>;
@ -118,19 +114,20 @@ template<Quantity To, typename D, typename U, scalable_with_<typename To::rep> R
constexpr auto c_ratio = detail::cast_ratio<quantity<D, U, Rep>, To>;
if constexpr (treat_as_floating_point<rep_type>) {
return To(static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) *
(static_cast<ratio_type>(c_ratio.num) * detail::fpow10<ratio_type>(c_ratio.exp) / static_cast<ratio_type>(c_ratio.den))));
}
else {
return To(
static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) *
(static_cast<ratio_type>(c_ratio.num) * detail::fpow10<ratio_type>(c_ratio.exp) /
static_cast<ratio_type>(c_ratio.den))));
} else {
if constexpr (c_ratio.exp > 0) {
return To(static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) *
(static_cast<ratio_type>(c_ratio.num) * static_cast<ratio_type>(detail::ipow10(c_ratio.exp))) /
static_cast<ratio_type>(c_ratio.den)));
}
else {
return To(static_cast<TYPENAME To::rep>(static_cast<rep_type>(q.number()) *
static_cast<ratio_type>(c_ratio.num) /
(static_cast<ratio_type>(c_ratio.den) * static_cast<ratio_type>(detail::ipow10(-c_ratio.exp)))));
return To(static_cast<TYPENAME To::rep>(
static_cast<rep_type>(q.number()) *
(static_cast<ratio_type>(c_ratio.num) * static_cast<ratio_type>(detail::ipow10(c_ratio.exp))) /
static_cast<ratio_type>(c_ratio.den)));
} else {
return To(static_cast<TYPENAME To::rep>(
static_cast<rep_type>(q.number()) * static_cast<ratio_type>(c_ratio.num) /
(static_cast<ratio_type>(c_ratio.den) * static_cast<ratio_type>(detail::ipow10(-c_ratio.exp)))));
}
}
}
@ -209,7 +206,7 @@ template<Dimension ToD, Unit ToU, typename D, typename U, typename Rep>
* @tparam ToRep a representation type to use for a target quantity
*/
template<Representation ToRep, typename D, typename U, scalable_with_<ToRep> Rep>
requires std::constructible_from<ToRep, std::common_type_t<ToRep, Rep>>
requires(std::constructible_from<ToRep, std::common_type_t<ToRep, Rep>>)
[[nodiscard]] constexpr auto quantity_cast(const quantity<D, U, Rep>& q)
{
return quantity_cast<quantity<D, U, ToRep>>(q);
@ -233,9 +230,11 @@ template<Representation ToRep, typename D, typename U, scalable_with_<ToRep> Rep
*/
template<typename CastSpec, typename O, typename U, typename Rep>
[[nodiscard]] constexpr auto quantity_point_cast(const quantity_point<O, U, Rep>& qp)
requires requires { requires is_specialization_of<CastSpec, quantity_point>;
requires requires { quantity_cast<typename CastSpec::quantity_type>(qp.relative()); };
requires equivalent<O, typename CastSpec::origin>; } || // TODO: Simplify when Clang catches up.
requires requires {
requires is_specialization_of<CastSpec, quantity_point>;
requires requires { quantity_cast<typename CastSpec::quantity_type>(qp.relative()); };
requires equivalent<O, typename CastSpec::origin>;
} || // TODO: Simplify when Clang catches up.
requires { quantity_cast<CastSpec>(qp.relative()); }
{
if constexpr (is_specialization_of<CastSpec, quantity_point>)
@ -286,10 +285,13 @@ template<Dimension ToD, Unit ToU, typename O, typename U, typename Rep>
*/
template<typename CastSpec, typename K, typename U, typename Rep>
[[nodiscard]] constexpr QuantityKind auto quantity_kind_cast(const quantity_kind<K, U, Rep>& qk)
requires requires { requires is_specialization_of<CastSpec, quantity_kind>;
requires requires { quantity_cast<typename CastSpec::quantity_type>(qk.common()); }; } ||
requires { requires Kind<CastSpec>; requires UnitOf<U, typename CastSpec::dimension>; } ||
requires { quantity_cast<CastSpec>(qk.common()); } // TODO: Simplify when Clang catches up.
requires requires {
requires is_specialization_of<CastSpec, quantity_kind>;
requires requires { quantity_cast<typename CastSpec::quantity_type>(qk.common()); };
} || requires {
requires Kind<CastSpec>;
requires UnitOf<U, typename CastSpec::dimension>;
} || requires { quantity_cast<CastSpec>(qk.common()); } // TODO: Simplify when Clang catches up.
{
if constexpr (is_specialization_of<CastSpec, quantity_kind>)
return CastSpec(quantity_cast<typename CastSpec::quantity_type>(qk.common()));
@ -330,25 +332,27 @@ template<Kind ToK, Unit ToU, typename K, typename U, typename Rep>
* Implicit conversions between quantity point kinds of different types are allowed only for "safe"
* (i.e. non-truncating) conversion. In other cases an explicit cast has to be used.
*
* This cast gets the target (quantity) point kind type to cast to or anything that works for quantity_kind_cast. For example:
* This cast gets the target (quantity) point kind type to cast to or anything that works for quantity_kind_cast. For
* example:
*
* auto q1 = units::quantity_point_kind_cast<decltype(ns::x_coordinate{1 * m))>(ns::x_coordinate{1 * mm});
* auto q1 = units::quantity_point_kind_cast<decltype(ns::width{1 * m})>(ns::x_coordinate{1 * mm});
* auto q1 = units::quantity_point_kind_cast<ns::y_coordinate_kind>(ns::x_coordinate{1 * m});
* auto q1 = units::quantity_point_kind_cast<ns::height_kind>(ns::x_coordinate{1 * m});
* auto q1 = units::quantity_point_kind_cast<units::isq::si::length<units::isq::si::metre>>(ns::x_coordinate{1 * mm});
* auto q1 = units::quantity_point_kind_cast<units::isq::si::dim_acceleration>(quantity_point_kind(ns::rate_of_climb{200 * Gal}));
* auto q1 = units::quantity_point_kind_cast<units::isq::si::metre>(ns::x_coordinate{1 * mm});
* auto q1 = units::quantity_point_kind_cast<int>(ns::x_coordinate{1.0 * mm});
* auto q1 = units::quantity_point_kind_cast<units::isq::si::dim_acceleration>(quantity_point_kind(ns::rate_of_climb{200
* * Gal})); auto q1 = units::quantity_point_kind_cast<units::isq::si::metre>(ns::x_coordinate{1 * mm}); auto q1 =
* units::quantity_point_kind_cast<int>(ns::x_coordinate{1.0 * mm});
*
* @tparam CastSpec a target (quantity) point kind type to cast to or anything that works for quantity_kind_cast
*/
template<typename CastSpec, typename PK, typename U, typename Rep>
[[nodiscard]] constexpr QuantityPointKind auto quantity_point_kind_cast(const quantity_point_kind<PK, U, Rep>& qpk)
requires requires { requires is_specialization_of<CastSpec, quantity_point_kind>;
requires requires { quantity_kind_cast<typename CastSpec::quantity_kind_type>(qpk.relative()); };
requires equivalent<typename PK::origin, typename CastSpec::point_kind_type::origin>; } ||
requires { requires PointKind<CastSpec> && UnitOf<U, typename CastSpec::dimension>; } ||
requires requires {
requires is_specialization_of<CastSpec, quantity_point_kind>;
requires requires { quantity_kind_cast<typename CastSpec::quantity_kind_type>(qpk.relative()); };
requires equivalent<typename PK::origin, typename CastSpec::point_kind_type::origin>;
} || requires { requires PointKind<CastSpec> && UnitOf<U, typename CastSpec::dimension>; } ||
requires { quantity_kind_cast<CastSpec>(qpk.relative()); } // TODO: Simplify when Clang catches up.
{
if constexpr (is_specialization_of<CastSpec, quantity_point_kind>)

View File

@ -63,7 +63,7 @@ inline constexpr auto& downcasted_kind = downcasted_kind_fn<typename QK::kind_ty
*/
template<typename QK1, typename QK2>
concept QuantityKindRelatedTo = QuantityKind<QK1> && QuantityKind<QK2> &&
equivalent<typename QK1::kind_type::base_kind, typename QK2::kind_type::base_kind>;
equivalent<typename QK1::kind_type::base_kind, typename QK2::kind_type::base_kind>;
/**
* @brief A quantity kind
@ -94,24 +94,26 @@ public:
quantity_kind(quantity_kind&&) = default;
template<typename T>
requires
(Quantity<std::remove_cvref_t<T>> ||
QuantityLike<std::remove_cvref_t<T>> ||
(Dimensionless<quantity_type> && !Quantity<std::remove_cvref_t<T>>)) &&
std::constructible_from<quantity_type, T>
constexpr explicit quantity_kind(T&& t) : q_(std::forward<T>(t)) {}
requires(Quantity<std::remove_cvref_t<T>> || QuantityLike<std::remove_cvref_t<T>> ||
(Dimensionless<quantity_type> && !Quantity<std::remove_cvref_t<T>>)) &&
std::constructible_from<quantity_type, T>
constexpr explicit quantity_kind(T&& t) : q_(std::forward<T>(t))
{
}
template<QuantityKindEquivalentTo<quantity_kind> QK2>
requires std::convertible_to<typename QK2::quantity_type, quantity_type>
constexpr explicit(false) quantity_kind(const QK2& qk) : q_(qk.common()) {}
constexpr explicit(false) quantity_kind(const QK2& qk) : q_(qk.common())
{
}
quantity_kind& operator=(const quantity_kind&) = default;
quantity_kind& operator=(quantity_kind&&) = default;
[[nodiscard]] constexpr quantity_type& common() & noexcept { return q_; }
[[nodiscard]] constexpr const quantity_type& common() const & noexcept { return q_; }
[[nodiscard]] constexpr const quantity_type& common() const& noexcept { return q_; }
[[nodiscard]] constexpr quantity_type&& common() && noexcept { return std::move(q_); }
[[nodiscard]] constexpr const quantity_type&& common() const && noexcept { return std::move(q_); }
[[nodiscard]] constexpr const quantity_type&& common() const&& noexcept { return std::move(q_); }
[[nodiscard]] static constexpr quantity_kind zero() noexcept
requires requires { quantity_type::zero(); }
@ -222,17 +224,18 @@ public:
template<typename Rep2>
constexpr quantity_kind& operator%=(const Rep2& rhs)
requires (!Quantity<Rep2> || Dimensionless<Rep2>) && requires(quantity_type q, const Rep2 r) { q %= r; }
requires(!Quantity<Rep2> || Dimensionless<Rep2>) && requires(quantity_type q, const Rep2 r) { q %= r; }
{
gsl_ExpectsAudit(rhs != quantity_values<Rep2>::zero());
q_ %= rhs;
return *this;
}
template<QuantityKind QK>
constexpr quantity_kind& operator%=(const QK& rhs)
requires (QuantityKindEquivalentTo<QK, quantity_kind> || std::same_as<typename QK::kind_type, downcast_kind<K, dim_one>>) &&
requires(quantity_type q) { q %= rhs.common(); }
requires(QuantityKindEquivalentTo<QK, quantity_kind> ||
std::same_as<typename QK::kind_type, downcast_kind<K, dim_one>>) &&
requires(quantity_type q) { q %= rhs.common(); }
{
gsl_ExpectsAudit(rhs.common().number() != quantity_values<typename QK::rep>::zero());
q_ %= rhs.common();
@ -243,21 +246,33 @@ public:
// Below friend functions are to be found via argument-dependent lookup only
template<Representation Value>
[[nodiscard]] friend constexpr QuantityKind auto operator*(const quantity_kind& qk, const Value& v)
requires requires(quantity_type q) { { q * v } -> Quantity; }
requires requires(quantity_type q) {
{
q* v
} -> Quantity;
}
{
return detail::make_quantity_kind<quantity_kind>(qk.common() * v);
}
template<Representation Value>
[[nodiscard]] friend constexpr QuantityKind auto operator*(const Value& v, const quantity_kind& qk)
requires requires(quantity_type q) { { v * q } -> Quantity; }
requires requires(quantity_type q) {
{
v* q
} -> Quantity;
}
{
return detail::make_quantity_kind<quantity_kind>(v * qk.common());
}
template<Representation Value>
[[nodiscard]] friend constexpr QuantityKind auto operator/(const quantity_kind& qk, const Value& v)
requires requires(quantity_type q) { { q / v } -> Quantity; }
requires requires(quantity_type q) {
{
q / v
} -> Quantity;
}
{
gsl_ExpectsAudit(v != quantity_values<Value>::zero());
return detail::make_quantity_kind<quantity_kind>(qk.common() / v);
@ -265,7 +280,11 @@ public:
template<Representation Value>
[[nodiscard]] friend constexpr QuantityKind auto operator/(const Value& v, const quantity_kind& qk)
requires requires(quantity_type q) { { v / q } -> Quantity; }
requires requires(quantity_type q) {
{
v / q
} -> Quantity;
}
{
gsl_ExpectsAudit(qk.common().number() != quantity_values<rep>::zero());
return detail::downcasted_kind<quantity_kind>(v / qk.common());
@ -297,7 +316,7 @@ template<QuantityKind QK1, QuantityKindEquivalentTo<QK1> QK2>
template<QuantityKind QK1, QuantityKindEquivalentTo<QK1> QK2>
[[nodiscard]] constexpr QuantityKind auto operator-(const QK1& lhs, const QK2& rhs)
requires requires { lhs.common() - rhs.common(); }
requires requires { lhs.common() - rhs.common(); }
{
return detail::make_quantity_kind<QK1>(lhs.common() - rhs.common());
}
@ -311,7 +330,7 @@ template<QuantityKind QK, Quantity Q>
template<Quantity Q, QuantityKind QK>
[[nodiscard]] constexpr QuantityKind auto operator*(const Q& lhs, const QK& rhs)
requires requires { lhs * rhs.common(); }
requires requires { lhs* rhs.common(); }
{
return detail::downcasted_kind<QK>(lhs * rhs.common());
}

View File

@ -76,25 +76,31 @@ public:
template<typename T>
requires std::constructible_from<quantity_type, T>
constexpr explicit quantity_point(T&& t) : q_(std::forward<T>(t)) {}
constexpr explicit quantity_point(T&& t) : q_(std::forward<T>(t))
{
}
template<QuantityPointOf<origin> QP2>
requires std::convertible_to<typename QP2::quantity_type, quantity_type>
constexpr explicit(false) quantity_point(const QP2& qp) : q_(qp.relative()) {}
constexpr explicit(false) quantity_point(const QP2& qp) : q_(qp.relative())
{
}
template<QuantityPointLike QP>
constexpr explicit quantity_point(const QP& qp)
requires std::is_constructible_v<quantity_type, decltype(quantity_point_like_traits<QP>::relative(qp))> &&
equivalent<origin, typename quantity_point_like_traits<QP>::origin>
: q_(quantity_point_like_traits<QP>::relative(qp)) {}
equivalent<origin, typename quantity_point_like_traits<QP>::origin>
: q_(quantity_point_like_traits<QP>::relative(qp))
{
}
quantity_point& operator=(const quantity_point&) = default;
quantity_point& operator=(quantity_point&&) = default;
[[nodiscard]] constexpr quantity_type& relative() & noexcept { return q_; }
[[nodiscard]] constexpr const quantity_type& relative() const & noexcept { return q_; }
[[nodiscard]] constexpr const quantity_type& relative() const& noexcept { return q_; }
[[nodiscard]] constexpr quantity_type&& relative() && noexcept { return std::move(q_); }
[[nodiscard]] constexpr const quantity_type&& relative() const && noexcept { return std::move(q_); }
[[nodiscard]] constexpr const quantity_type&& relative() const&& noexcept { return std::move(q_); }
[[nodiscard]] static constexpr quantity_point min() noexcept
requires requires { quantity_type::min(); }
@ -207,13 +213,14 @@ template<Quantity Q>
explicit quantity_point(Q) -> quantity_point<dynamic_origin<typename Q::dimension>, typename Q::unit, typename Q::rep>;
template<QuantityLike Q>
explicit quantity_point(Q) -> quantity_point<dynamic_origin<typename quantity_like_traits<Q>::dimension>,
typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
explicit quantity_point(Q)
-> quantity_point<dynamic_origin<typename quantity_like_traits<Q>::dimension>, typename quantity_like_traits<Q>::unit,
typename quantity_like_traits<Q>::rep>;
template<QuantityPointLike QP>
explicit quantity_point(QP) -> quantity_point<typename quantity_point_like_traits<QP>::origin,
typename quantity_point_like_traits<QP>::unit,
typename quantity_point_like_traits<QP>::rep>;
explicit quantity_point(QP)
-> quantity_point<typename quantity_point_like_traits<QP>::origin, typename quantity_point_like_traits<QP>::unit,
typename quantity_point_like_traits<QP>::rep>;
namespace detail {

View File

@ -63,26 +63,32 @@ public:
template<typename T>
requires std::constructible_from<quantity_kind_type, T>
constexpr explicit quantity_point_kind(T&& t) : qk_(std::forward<T>(t)) {}
constexpr explicit quantity_point_kind(T&& t) : qk_(std::forward<T>(t))
{
}
constexpr explicit quantity_point_kind(const quantity_point<origin, U, Rep>& qp) : qk_(qp.relative()) {}
constexpr explicit quantity_point_kind(quantity_point<origin, U, Rep>&& qp) : qk_(std::move(qp).relative()) {}
template<QuantityPointLike QP>
requires std::constructible_from<quantity_point<origin, U, Rep>, QP>
constexpr explicit quantity_point_kind(const QP& qp) : qk_(quantity_point_like_traits<QP>::relative(qp)) {}
requires(std::constructible_from<quantity_point<origin, U, Rep>, QP>)
constexpr explicit quantity_point_kind(const QP& qp) : qk_(quantity_point_like_traits<QP>::relative(qp))
{
}
template<QuantityPointKindOf<point_kind_type> QPK2>
requires std::convertible_to<typename QPK2::quantity_kind_type, quantity_kind_type>
constexpr explicit(false) quantity_point_kind(const QPK2& qpk) : qk_(qpk.relative()) {}
constexpr explicit(false) quantity_point_kind(const QPK2& qpk) : qk_(qpk.relative())
{
}
quantity_point_kind& operator=(const quantity_point_kind&) = default;
quantity_point_kind& operator=(quantity_point_kind&&) = default;
[[nodiscard]] constexpr quantity_kind_type& relative() & noexcept { return qk_; }
[[nodiscard]] constexpr const quantity_kind_type& relative() const & noexcept { return qk_; }
[[nodiscard]] constexpr const quantity_kind_type& relative() const& noexcept { return qk_; }
[[nodiscard]] constexpr quantity_kind_type&& relative() && noexcept { return std::move(qk_); }
[[nodiscard]] constexpr const quantity_kind_type&& relative() const && noexcept { return std::move(qk_); }
[[nodiscard]] constexpr const quantity_kind_type&& relative() const&& noexcept { return std::move(qk_); }
[[nodiscard]] static constexpr quantity_point_kind min() noexcept
requires requires { quantity_kind_type::min(); }
@ -180,12 +186,11 @@ public:
{
return lhs.relative() == rhs.relative();
}
};
template<QuantityKind QK>
quantity_point_kind(QK) ->
quantity_point_kind<downcast_point_kind<typename QK::kind_type>, typename QK::unit, typename QK::rep>;
quantity_point_kind(QK)
-> quantity_point_kind<downcast_point_kind<typename QK::kind_type>, typename QK::unit, typename QK::rep>;
namespace detail {

View File

@ -23,460 +23,534 @@
#pragma once
#include <units/concepts.h>
#include <random>
#include <functional>
#include <random>
namespace units {
namespace detail {
template <Quantity Q, typename InputIt>
static std::vector<typename Q::rep> i_qty_to_rep(InputIt first, InputIt last)
{
std::vector<typename Q::rep> intervals_rep;
intervals_rep.reserve(static_cast<size_t>(std::distance(first, last)));
for (auto itr = first; itr != last; ++itr) { intervals_rep.push_back(itr->number()); }
return intervals_rep;
}
template <Quantity Q>
static std::vector<typename Q::rep> bl_qty_to_rep(std::initializer_list<Q>& bl)
{
std::vector<typename Q::rep> bl_rep;
bl_rep.reserve(bl.size());
for (const Q& qty : bl) { bl_rep.push_back(qty.number()); }
return bl_rep;
}
template <Quantity Q, typename UnaryOperation>
inline static std::vector<typename Q::rep> fw_bl_pwc(std::initializer_list<Q>& bl, UnaryOperation fw)
{
using rep = TYPENAME Q::rep;
std::vector<rep> w_bl;
w_bl.reserve(bl.size());
for (const Q& qty : bl) { w_bl.push_back(fw(qty)); }
std::vector<rep> weights;
weights.reserve(bl.size());
for (size_t i = 0; i < bl.size() - 1; ++i) { weights.push_back(w_bl[i] + w_bl[i + 1]); }
weights.push_back(0);
return weights;
}
template <Quantity Q, typename UnaryOperation>
static std::vector<typename Q::rep> fw_bl_pwl(std::initializer_list<Q>& bl, UnaryOperation fw)
{
std::vector<typename Q::rep> weights;
weights.reserve(bl.size());
for (const Q& qty : bl) { weights.push_back(fw(qty)); }
return weights;
}
} // namespace detail
template<Quantity Q, typename InputIt>
static std::vector<typename Q::rep> i_qty_to_rep(InputIt first, InputIt last)
{
std::vector<typename Q::rep> intervals_rep;
intervals_rep.reserve(static_cast<size_t>(std::distance(first, last)));
for (auto itr = first; itr != last; ++itr) {
intervals_rep.push_back(itr->number());
}
return intervals_rep;
}
template<Quantity Q>
requires std::integral<typename Q::rep>
struct uniform_int_distribution : public std::uniform_int_distribution<typename Q::rep>
static std::vector<typename Q::rep> bl_qty_to_rep(std::initializer_list<Q>& bl)
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::uniform_int_distribution<rep>;
uniform_int_distribution() : base() {}
uniform_int_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
std::vector<typename Q::rep> bl_rep;
bl_rep.reserve(bl.size());
for (const Q& qty : bl) {
bl_rep.push_back(qty.number());
}
return bl_rep;
}
template<Quantity Q, typename UnaryOperation>
inline static std::vector<typename Q::rep> fw_bl_pwc(std::initializer_list<Q>& bl, UnaryOperation fw)
{
using rep = TYPENAME Q::rep;
std::vector<rep> w_bl;
w_bl.reserve(bl.size());
for (const Q& qty : bl) {
w_bl.push_back(fw(qty));
}
std::vector<rep> weights;
weights.reserve(bl.size());
for (size_t i = 0; i < bl.size() - 1; ++i) {
weights.push_back(w_bl[i] + w_bl[i + 1]);
}
weights.push_back(0);
return weights;
}
template<Quantity Q, typename UnaryOperation>
static std::vector<typename Q::rep> fw_bl_pwl(std::initializer_list<Q>& bl, UnaryOperation fw)
{
std::vector<typename Q::rep> weights;
weights.reserve(bl.size());
for (const Q& qty : bl) {
weights.push_back(fw(qty));
}
return weights;
}
} // namespace detail
template<Quantity Q>
requires std::integral<typename Q::rep>
struct uniform_int_distribution : public std::uniform_int_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::uniform_int_distribution<rep>;
uniform_int_distribution() : base() {}
uniform_int_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct uniform_real_distribution : public std::uniform_real_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::uniform_real_distribution<rep>;
uniform_real_distribution() : base() {}
uniform_real_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct uniform_real_distribution : public std::uniform_real_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::uniform_real_distribution<rep>;
uniform_real_distribution() : base() {}
uniform_real_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::integral<typename Q::rep>
struct binomial_distribution : public std::binomial_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::binomial_distribution<rep>;
binomial_distribution() : base() {}
binomial_distribution(const Q& t, double p) : base(t.number(), p) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q t() const { return Q(base::t()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::integral<typename Q::rep>
struct binomial_distribution : public std::binomial_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::binomial_distribution<rep>;
binomial_distribution() : base() {}
binomial_distribution(const Q& t, double p) : base(t.number(), p) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q t() const { return Q(base::t()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::integral<typename Q::rep>
struct negative_binomial_distribution : public std::negative_binomial_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::negative_binomial_distribution<rep>;
negative_binomial_distribution() : base() {}
negative_binomial_distribution(const Q& k, double p) : base(k.number(), p) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q k() const { return Q(base::k()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::integral<typename Q::rep>
struct negative_binomial_distribution : public std::negative_binomial_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::negative_binomial_distribution<rep>;
negative_binomial_distribution() : base() {}
negative_binomial_distribution(const Q& k, double p) : base(k.number(), p) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q k() const { return Q(base::k()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::integral<typename Q::rep>
struct geometric_distribution : public std::geometric_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::geometric_distribution<rep>;
geometric_distribution() : base() {}
geometric_distribution(double p) : base(p) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
requires std::integral<typename Q::rep>
struct geometric_distribution : public std::geometric_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::geometric_distribution<rep>;
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
geometric_distribution() : base() {}
geometric_distribution(double p) : base(p) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::integral<typename Q::rep>
struct poisson_distribution : public std::poisson_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::poisson_distribution<rep>;
poisson_distribution() : base() {}
explicit poisson_distribution(double p) : base(p) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::integral<typename Q::rep>
struct poisson_distribution : public std::poisson_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::poisson_distribution<rep>;
poisson_distribution() : base() {}
explicit poisson_distribution(double p) : base(p) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct exponential_distribution : public std::exponential_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::exponential_distribution<rep>;
exponential_distribution() : base() {}
explicit exponential_distribution(const rep& lambda) : base(lambda) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct exponential_distribution : public std::exponential_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::exponential_distribution<rep>;
exponential_distribution() : base() {}
explicit exponential_distribution(const rep& lambda) : base(lambda) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct gamma_distribution : public std::gamma_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::gamma_distribution<rep>;
gamma_distribution() : base() {}
gamma_distribution(const rep& alpha, const rep& beta) : base(alpha, beta) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct gamma_distribution : public std::gamma_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::gamma_distribution<rep>;
gamma_distribution() : base() {}
gamma_distribution(const rep& alpha, const rep& beta) : base(alpha, beta) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct weibull_distribution : public std::weibull_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::weibull_distribution<rep>;
weibull_distribution() : base() {}
weibull_distribution(const rep& a, const rep& b) : base(a, b) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct weibull_distribution : public std::weibull_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::weibull_distribution<rep>;
weibull_distribution() : base() {}
weibull_distribution(const rep& a, const rep& b) : base(a, b) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct extreme_value_distribution : public std::extreme_value_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::extreme_value_distribution<rep>;
extreme_value_distribution() : base() {}
extreme_value_distribution(const Q& a, const rep& b) : base(a.number(), b) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
requires std::floating_point<typename Q::rep>
struct extreme_value_distribution : public std::extreme_value_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::extreme_value_distribution<rep>;
Q a() const { return Q(base::a()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
extreme_value_distribution() : base() {}
extreme_value_distribution(const Q& a, const rep& b) : base(a.number(), b) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q a() const { return Q(base::a()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct normal_distribution : public std::normal_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::normal_distribution<rep>;
normal_distribution() : base() {}
normal_distribution(const Q& mean, const Q& stddev) : base(mean.number(), stddev.number()) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q mean() const { return Q(base::mean()); }
Q stddev() const { return Q(base::stddev()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct normal_distribution : public std::normal_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::normal_distribution<rep>;
normal_distribution() : base() {}
normal_distribution(const Q& mean, const Q& stddev) : base(mean.number(), stddev.number()) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q mean() const { return Q(base::mean()); }
Q stddev() const { return Q(base::stddev()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct lognormal_distribution : public std::lognormal_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::lognormal_distribution<rep>;
lognormal_distribution() : base() {}
lognormal_distribution(const Q& m, const Q& s) : base(m.number(), s.number()) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q m() const { return Q(base::m()); }
Q s() const { return Q(base::s()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct lognormal_distribution : public std::lognormal_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::lognormal_distribution<rep>;
lognormal_distribution() : base() {}
lognormal_distribution(const Q& m, const Q& s) : base(m.number(), s.number()) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q m() const { return Q(base::m()); }
Q s() const { return Q(base::s()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct chi_squared_distribution : public std::chi_squared_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::chi_squared_distribution<rep>;
chi_squared_distribution() : base() {}
explicit chi_squared_distribution(const rep& n) : base(n) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct chi_squared_distribution : public std::chi_squared_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::chi_squared_distribution<rep>;
chi_squared_distribution() : base() {}
explicit chi_squared_distribution(const rep& n) : base(n) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::cauchy_distribution<rep>;
cauchy_distribution() : base() {}
cauchy_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::cauchy_distribution<rep>;
cauchy_distribution() : base() {}
cauchy_distribution(const Q& a, const Q& b) : base(a.number(), b.number()) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q a() const { return Q(base::a()); }
Q b() const { return Q(base::b()); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct fisher_f_distribution : public std::fisher_f_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::fisher_f_distribution<rep>;
fisher_f_distribution() : base() {}
fisher_f_distribution(const rep& m, const rep& n) : base(m, n) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct fisher_f_distribution : public std::fisher_f_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::fisher_f_distribution<rep>;
fisher_f_distribution() : base() {}
fisher_f_distribution(const rep& m, const rep& n) : base(m, n) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
struct student_t_distribution : public std::student_t_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::student_t_distribution<rep>;
student_t_distribution() : base() {}
explicit student_t_distribution(const rep& n) : base(n) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
requires std::floating_point<typename Q::rep>
struct student_t_distribution : public std::student_t_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::student_t_distribution<rep>;
student_t_distribution() : base() {}
explicit student_t_distribution(const rep& n) : base(n) {}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::integral<typename Q::rep>
struct discrete_distribution : public std::discrete_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::discrete_distribution<rep>;
discrete_distribution() : base() {}
template <typename InputIt>
discrete_distribution(InputIt first, InputIt last) : base(first, last) {}
requires std::integral<typename Q::rep>
struct discrete_distribution : public std::discrete_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::discrete_distribution<rep>;
discrete_distribution(std::initializer_list<double> weights) : base(weights) {}
discrete_distribution() : base() {}
template <typename UnaryOperation>
discrete_distribution(std::size_t count, double xmin, double xmax, UnaryOperation unary_op) :
base(count, xmin, xmax, unary_op) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
template<typename InputIt>
discrete_distribution(InputIt first, InputIt last) : base(first, last)
{
}
discrete_distribution(std::initializer_list<double> weights) : base(weights) {}
template<typename UnaryOperation>
discrete_distribution(std::size_t count, double xmin, double xmax, UnaryOperation unary_op) :
base(count, xmin, xmax, unary_op)
{
}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
class piecewise_constant_distribution : public std::piecewise_constant_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::piecewise_constant_distribution<rep>;
template <typename InputIt>
piecewise_constant_distribution(const std::vector<rep>& i, InputIt first_w) :
base(i.cbegin(), i.cend(), first_w) {}
piecewise_constant_distribution(const std::vector<rep>& bl, const std::vector<rep>& weights) :
base(bl.cbegin(), bl.cend(), weights.cbegin()) {}
requires std::floating_point<typename Q::rep>
class piecewise_constant_distribution : public std::piecewise_constant_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::piecewise_constant_distribution<rep>;
template<typename InputIt>
piecewise_constant_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w)
{
}
piecewise_constant_distribution(const std::vector<rep>& bl, const std::vector<rep>& weights) :
base(bl.cbegin(), bl.cend(), weights.cbegin())
{
}
public:
piecewise_constant_distribution() : base() {}
template <typename InputIt1, typename InputIt2>
piecewise_constant_distribution(InputIt1 first_i, InputIt1 last_i, InputIt2 first_w) :
piecewise_constant_distribution(detail::i_qty_to_rep<Q>(first_i, last_i), first_w) {}
piecewise_constant_distribution() : base() {}
template <typename UnaryOperation>
piecewise_constant_distribution(std::initializer_list<Q> bl, UnaryOperation fw) :
piecewise_constant_distribution(detail::bl_qty_to_rep(bl), detail::fw_bl_pwc(bl, fw)) {}
template<typename InputIt1, typename InputIt2>
piecewise_constant_distribution(InputIt1 first_i, InputIt1 last_i, InputIt2 first_w) :
piecewise_constant_distribution(detail::i_qty_to_rep<Q>(first_i, last_i), first_w)
{
}
template <typename UnaryOperation>
piecewise_constant_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); }) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
template<typename UnaryOperation>
piecewise_constant_distribution(std::initializer_list<Q> bl, UnaryOperation fw) :
piecewise_constant_distribution(detail::bl_qty_to_rep(bl), detail::fw_bl_pwc(bl, fw))
{
}
std::vector<Q> intervals() const
{
std::vector<rep> intervals_rep = base::intervals();
std::vector<Q> intervals_qty;
intervals_qty.reserve(intervals_rep.size());
for (const rep& val : intervals_rep) { intervals_qty.push_back(Q(val)); }
return intervals_qty;
template<typename UnaryOperation>
piecewise_constant_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); })
{
}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
std::vector<Q> intervals() const
{
std::vector<rep> intervals_rep = base::intervals();
std::vector<Q> intervals_qty;
intervals_qty.reserve(intervals_rep.size());
for (const rep& val : intervals_rep) {
intervals_qty.push_back(Q(val));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
return intervals_qty;
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
template<Quantity Q>
requires std::floating_point<typename Q::rep>
class piecewise_linear_distribution : public std::piecewise_linear_distribution<typename Q::rep>
{
using rep = TYPENAME Q::rep;
using base = TYPENAME std::piecewise_linear_distribution<rep>;
template <typename InputIt>
piecewise_linear_distribution(const std::vector<rep>& i, InputIt first_w) :
base(i.cbegin(), i.cend(), first_w) {}
piecewise_linear_distribution(const std::vector<rep>& bl, const std::vector<rep>& weights) :
base(bl.cbegin(), bl.cend(), weights.cbegin()) {}
requires std::floating_point<typename Q::rep>
class piecewise_linear_distribution : public std::piecewise_linear_distribution<typename Q::rep> {
using rep = TYPENAME Q::rep;
using base = TYPENAME std::piecewise_linear_distribution<rep>;
template<typename InputIt>
piecewise_linear_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w)
{
}
piecewise_linear_distribution(const std::vector<rep>& bl, const std::vector<rep>& weights) :
base(bl.cbegin(), bl.cend(), weights.cbegin())
{
}
public:
piecewise_linear_distribution() : base() {}
template <typename InputIt1, typename InputIt2>
piecewise_linear_distribution(InputIt1 first_i, InputIt1 last_i, InputIt2 first_w) :
piecewise_linear_distribution(detail::i_qty_to_rep<Q>(first_i, last_i), first_w) {}
piecewise_linear_distribution() : base() {}
template <typename UnaryOperation>
piecewise_linear_distribution(std::initializer_list<Q> bl, UnaryOperation fw) :
piecewise_linear_distribution(detail::bl_qty_to_rep(bl), detail::fw_bl_pwl(bl, fw)) {}
template<typename InputIt1, typename InputIt2>
piecewise_linear_distribution(InputIt1 first_i, InputIt1 last_i, InputIt2 first_w) :
piecewise_linear_distribution(detail::i_qty_to_rep<Q>(first_i, last_i), first_w)
{
}
template <typename UnaryOperation>
piecewise_linear_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); }) {}
template<typename Generator>
Q operator()(Generator& g) { return Q(base::operator()(g)); }
template<typename UnaryOperation>
piecewise_linear_distribution(std::initializer_list<Q> bl, UnaryOperation fw) :
piecewise_linear_distribution(detail::bl_qty_to_rep(bl), detail::fw_bl_pwl(bl, fw))
{
}
std::vector<Q> intervals() const
{
std::vector<rep> intervals_rep = base::intervals();
std::vector<Q> intervals_qty;
intervals_qty.reserve(intervals_rep.size());
for (const rep& val : intervals_rep) { intervals_qty.push_back(Q(val)); }
return intervals_qty;
template<typename UnaryOperation>
piecewise_linear_distribution(std::size_t nw, const Q& xmin, const Q& xmax, UnaryOperation fw) :
base(nw, xmin.number(), xmax.number(), [fw](rep val) { return fw(Q(val)); })
{
}
template<typename Generator>
Q operator()(Generator& g)
{
return Q(base::operator()(g));
}
std::vector<Q> intervals() const
{
std::vector<rep> intervals_rep = base::intervals();
std::vector<Q> intervals_qty;
intervals_qty.reserve(intervals_rep.size());
for (const rep& val : intervals_rep) {
intervals_qty.push_back(Q(val));
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
return intervals_qty;
}
Q min() const { return Q(base::min()); }
Q max() const { return Q(base::max()); }
};
} // namespace units
} // namespace units

View File

@ -30,9 +30,9 @@
#include <cstdint>
// IWYU pragma: end_exports
#include <gsl/gsl-lite.hpp>
#include <array>
#include <numeric>
#include <gsl/gsl-lite.hpp>
namespace units {
@ -52,7 +52,7 @@ struct ratio {
std::intmax_t den;
std::intmax_t exp;
constexpr explicit(false) ratio(std::intmax_t n, std::intmax_t d = 1, std::intmax_t e = 0): num(n), den(d), exp(e)
constexpr explicit(false) ratio(std::intmax_t n, std::intmax_t d = 1, std::intmax_t e = 0) : num(n), den(d), exp(e)
{
gsl_Expects(den != 0);
detail::normalize(num, den, exp);
@ -60,16 +60,13 @@ struct ratio {
[[nodiscard]] friend constexpr bool operator==(const ratio&, const ratio&) = default;
[[nodiscard]] friend constexpr ratio operator-(const ratio& r)
{
return ratio(-r.num, r.den, r.exp);
}
[[nodiscard]] friend constexpr ratio operator-(const ratio& r) { return ratio(-r.num, r.den, r.exp); }
[[nodiscard]] friend constexpr ratio operator+(ratio lhs, ratio rhs)
{
// First, get the inputs into a common exponent.
const auto common_exp = std::min(lhs.exp, rhs.exp);
auto commonify = [common_exp](ratio &r) {
auto commonify = [common_exp](ratio& r) {
while (r.exp > common_exp) {
r.num *= 10;
--r.exp;
@ -86,24 +83,17 @@ struct ratio {
const std::intmax_t gcd1 = std::gcd(lhs.num, rhs.den);
const std::intmax_t gcd2 = std::gcd(rhs.num, lhs.den);
return ratio(detail::safe_multiply(lhs.num / gcd1, rhs.num / gcd2),
detail::safe_multiply(lhs.den / gcd2, rhs.den / gcd1),
lhs.exp + rhs.exp);
detail::safe_multiply(lhs.den / gcd2, rhs.den / gcd1), lhs.exp + rhs.exp);
}
[[nodiscard]] friend constexpr ratio operator/(const ratio& lhs, const ratio& rhs)
{
return lhs * inverse(rhs);
}
[[nodiscard]] friend constexpr ratio operator/(const ratio& lhs, const ratio& rhs) { return lhs * inverse(rhs); }
};
[[nodiscard]] constexpr ratio inverse(const ratio& r)
{
return ratio(r.den, r.num, -r.exp);
}
[[nodiscard]] constexpr ratio inverse(const ratio& r) { return ratio(r.den, r.num, -r.exp); }
[[nodiscard]] constexpr bool is_integral(const ratio& r)
{
if(r.exp < 0) {
if (r.exp < 0) {
return false;
} else {
return detail::gcdpow(r.num, r.exp, r.den) == r.den;

View File

@ -36,24 +36,26 @@ struct reference;
namespace detail {
template<typename D, typename D1, typename U1, typename D2, typename U2>
using reference_multiply_impl = reference<D, downcast_unit<D,
(U1::ratio / dimension_unit<D1>::ratio) * (U2::ratio / dimension_unit<D2>::ratio) * dimension_unit<D>::ratio>>;
using reference_multiply_impl =
reference<D, downcast_unit<D, (U1::ratio / dimension_unit<D1>::ratio) * (U2::ratio / dimension_unit<D2>::ratio) *
dimension_unit<D>::ratio>>;
template<typename D, typename D1, typename U1, typename D2, typename U2>
using reference_divide_impl = reference<D, downcast_unit<D,
(U1::ratio / dimension_unit<D1>::ratio) / (U2::ratio / dimension_unit<D2>::ratio) * dimension_unit<D>::ratio>>;
using reference_divide_impl =
reference<D, downcast_unit<D, (U1::ratio / dimension_unit<D1>::ratio) / (U2::ratio / dimension_unit<D2>::ratio) *
dimension_unit<D>::ratio>>;
} // namespace detail
template<Reference R1, Reference R2>
using reference_multiply = detail::reference_multiply_impl<
dimension_multiply<typename R1::dimension, typename R2::dimension>,
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
using reference_multiply =
detail::reference_multiply_impl<dimension_multiply<typename R1::dimension, typename R2::dimension>,
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
template<Reference R1, Reference R2>
using reference_divide = detail::reference_divide_impl<
dimension_divide<typename R1::dimension, typename R2::dimension>,
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
using reference_divide =
detail::reference_divide_impl<dimension_divide<typename R1::dimension, typename R2::dimension>,
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
/**
* @brief The type for quantity references
@ -62,21 +64,21 @@ using reference_divide = detail::reference_divide_impl<
*
* @code{.cpp}
* namespace length_references {
*
*
* inline constexpr auto m = reference<dim_length, metre>{};
* inline constexpr auto km = reference<dim_length, kilometre>{};
*
*
* }
*
*
* namespace references {
*
*
* using namespace length_references;
*
*
* }
* @endcode
*
*
* Quantity references simplify quantity creation:
*
*
* @code{.cpp}
* using namespace units::isq::si::references;
*
@ -85,12 +87,12 @@ using reference_divide = detail::reference_divide_impl<
* @endcode
*
* Also, it is allowed to define custom quantity references from existing ones:
*
*
* @code{.cpp}
* constexpr auto Nm = N * m;
* constexpr auto mph = mi / h;
* @endcode
*
*
* The following syntaxes are not allowed:
* `2 / s`, `km * 3`, `s / 4`, `70 * km / h`.
*/
@ -103,10 +105,16 @@ struct reference {
// Below friend functions are to be found via argument-dependent lookup only
template<Reference R2>
[[nodiscard]] friend constexpr reference_multiply<reference, R2> operator*(reference, R2) { return {}; }
[[nodiscard]] friend constexpr reference_multiply<reference, R2> operator*(reference, R2)
{
return {};
}
template<Reference R2>
[[nodiscard]] friend constexpr reference_divide<reference, R2> operator/(reference, R2) { return {}; }
[[nodiscard]] friend constexpr reference_divide<reference, R2> operator/(reference, R2)
{
return {};
}
template<Representation Rep>
[[nodiscard]] friend constexpr Quantity auto operator*(const Rep& lhs, reference)
@ -117,7 +125,10 @@ struct reference {
friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete;
template<Reference R2>
[[nodiscard]] friend constexpr bool operator==(reference, R2) { return false; }
[[nodiscard]] friend constexpr bool operator==(reference, R2)
{
return false;
}
[[nodiscard]] friend constexpr bool operator==(reference, reference) { return true; }
};

View File

@ -25,8 +25,8 @@
// IWYU pragma: begin_exports
#include <units/bits/external/fixed_string.h>
#include <compare>
#include <cstdint>
#include <cstddef>
#include <cstdint>
// IWYU pragma: end_exports
#include <gsl/gsl-lite.hpp>
@ -42,8 +42,7 @@ constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) no
{
#ifndef NDEBUG
if constexpr (N != 0)
for (size_t i = 0; i < N; ++i)
validate_ascii_char(s[i]);
for (size_t i = 0; i < N; ++i) validate_ascii_char(s[i]);
#endif
}
@ -52,11 +51,11 @@ constexpr void validate_ascii_string([[maybe_unused]] const char (&s)[N + 1]) no
/**
* @brief A symbol text representation
*
*
* This class template is responsible for definition and handling of a symbol text
* representation. In the libary it is used to define symbols of units and prefixes.
* Each symbol can have two versions: Unicode and ASCI-only.
*
*
* @tparam StandardCharT Character type to be used for a Unicode representation
* @tparam N The size of a Unicode symbol
* @tparam M The size of the ASCII-only symbol
@ -66,12 +65,30 @@ struct basic_symbol_text {
basic_fixed_string<StandardCharT, N> standard_;
basic_fixed_string<char, M> ascii_;
constexpr basic_symbol_text(char std) noexcept: standard_(std), ascii_(std) { detail::validate_ascii_char(std); }
constexpr basic_symbol_text(StandardCharT std, char a) noexcept: standard_(std), ascii_(a) { detail::validate_ascii_char(a); }
constexpr basic_symbol_text(const char (&std)[N + 1]) noexcept: standard_(std), ascii_(std) { detail::validate_ascii_string<N>(std); }
constexpr basic_symbol_text(const basic_fixed_string<char, N>& std) noexcept: standard_(std), ascii_(std) { detail::validate_ascii_string<N>(std.data_); }
constexpr basic_symbol_text(const StandardCharT (&std)[N + 1], const char (&a)[M + 1]) noexcept: standard_(std), ascii_(a) { detail::validate_ascii_string<M>(a); }
constexpr basic_symbol_text(const basic_fixed_string<StandardCharT, N>& std, const basic_fixed_string<char, M>& a) noexcept: standard_(std), ascii_(a) { detail::validate_ascii_string<M>(a.data_); }
constexpr basic_symbol_text(char std) noexcept : standard_(std), ascii_(std) { detail::validate_ascii_char(std); }
constexpr basic_symbol_text(StandardCharT std, char a) noexcept : standard_(std), ascii_(a)
{
detail::validate_ascii_char(a);
}
constexpr basic_symbol_text(const char (&std)[N + 1]) noexcept : standard_(std), ascii_(std)
{
detail::validate_ascii_string<N>(std);
}
constexpr basic_symbol_text(const basic_fixed_string<char, N>& std) noexcept : standard_(std), ascii_(std)
{
detail::validate_ascii_string<N>(std.data_);
}
constexpr basic_symbol_text(const StandardCharT (&std)[N + 1], const char (&a)[M + 1]) noexcept :
standard_(std), ascii_(a)
{
detail::validate_ascii_string<M>(a);
}
constexpr basic_symbol_text(const basic_fixed_string<StandardCharT, N>& std,
const basic_fixed_string<char, M>& a) noexcept :
standard_(std), ascii_(a)
{
detail::validate_ascii_string<M>(a.data_);
}
[[nodiscard]] constexpr auto& standard() { return standard_; }
[[nodiscard]] constexpr const auto& standard() const { return standard_; }
@ -80,48 +97,47 @@ struct basic_symbol_text {
template<std::size_t N2, std::size_t M2>
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + N2, M + M2> operator+(
const basic_symbol_text& lhs, const basic_symbol_text<StandardCharT, N2, M2>& rhs) noexcept
const basic_symbol_text& lhs, const basic_symbol_text<StandardCharT, N2, M2>& rhs) noexcept
{
return basic_symbol_text<StandardCharT, N + N2, M + M2>(
lhs.standard() + rhs.standard(), lhs.ascii() + rhs.ascii());
return basic_symbol_text<StandardCharT, N + N2, M + M2>(lhs.standard() + rhs.standard(), lhs.ascii() + rhs.ascii());
}
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + N2, M + N2> operator+(
const basic_symbol_text& lhs, const basic_fixed_string<StandardCharT, N2>& rhs) noexcept
const basic_symbol_text& lhs, const basic_fixed_string<StandardCharT, N2>& rhs) noexcept
{
return lhs + basic_symbol_text<StandardCharT, N2, N2>(rhs);
}
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + N2, M + N2> operator+(
const basic_fixed_string<StandardCharT, N2>& lhs, const basic_symbol_text& rhs) noexcept
const basic_fixed_string<StandardCharT, N2>& lhs, const basic_symbol_text& rhs) noexcept
{
return basic_symbol_text<StandardCharT, N2, N2>(lhs) + rhs;
}
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + N2 - 1, M + N2 - 1> operator+(
const basic_symbol_text& lhs, const StandardCharT (&rhs)[N2]) noexcept
const basic_symbol_text& lhs, const StandardCharT (&rhs)[N2]) noexcept
{
return lhs + basic_symbol_text<StandardCharT, N2 - 1, N2 - 1>(rhs);
}
template<std::size_t N2>
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + N2 - 1, M + N2 - 1> operator+(
const StandardCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept
const StandardCharT (&lhs)[N2], const basic_symbol_text& rhs) noexcept
{
return basic_symbol_text<StandardCharT, N2 - 1, N2 - 1>(lhs) + rhs;
}
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + 1, M + 1> operator+(
const basic_symbol_text& lhs, StandardCharT rhs) noexcept
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + 1, M + 1> operator+(const basic_symbol_text& lhs,
StandardCharT rhs) noexcept
{
return lhs + basic_symbol_text<StandardCharT, 1, 1>(rhs);
}
[[nodiscard]] constexpr friend basic_symbol_text<StandardCharT, N + 1, M + 1> operator+(
StandardCharT lhs, const basic_symbol_text& rhs) noexcept
StandardCharT lhs, const basic_symbol_text& rhs) noexcept
{
return basic_symbol_text<StandardCharT, 1, 1>(lhs) + rhs;
}
@ -142,7 +158,7 @@ struct basic_symbol_text {
}
};
basic_symbol_text(char) -> basic_symbol_text<char, 1, 1>;
basic_symbol_text(char)->basic_symbol_text<char, 1, 1>;
template<typename StandardCharT>
basic_symbol_text(StandardCharT, char) -> basic_symbol_text<StandardCharT, 1, 1>;
@ -157,7 +173,7 @@ template<typename StandardCharT, std::size_t N, std::size_t M>
basic_symbol_text(const StandardCharT (&)[N], const char (&)[M]) -> basic_symbol_text<StandardCharT, N - 1, M - 1>;
template<typename StandardCharT, std::size_t N, std::size_t M>
basic_symbol_text(const basic_fixed_string<StandardCharT, N>&,
const basic_fixed_string<char, M>&) -> basic_symbol_text<StandardCharT, N, M>;
basic_symbol_text(const basic_fixed_string<StandardCharT, N>&, const basic_fixed_string<char, M>&)
-> basic_symbol_text<StandardCharT, N, M>;
} // namespace units

View File

@ -26,9 +26,9 @@
#include <units/bits/external/downcasting.h>
// IWYU pragma: begin_exports
#include <units/bits/derived_unit.h>
#include <units/bits/derived_unit.h>
#include <units/bits/external/fixed_string.h>
#include <units/prefix.h>
#include <units/prefix.h>
#include <units/ratio.h>
#include <units/symbol_text.h>
// IWYU pragma: end_exports
@ -41,7 +41,7 @@ namespace units {
* A unit is an entity defined and adopted by convention, with which any other quantity of
* the same kind can be compared to express the ratio of the second quantity to the first
* one as a number.
*
*
* All units of the same dimension can be convereted between each other. To allow this all of
* them are expressed as different ratios of the same one proprietary chosen reference unit
* (i.e. all length units are expressed in terms of meter, all mass units are expressed in
@ -162,7 +162,7 @@ struct derived_unit : downcast_dispatch<Child, detail::derived_unit<Dim, U, URes
};
/**
* @brief A named unit with a deduced ratio
* @brief A named unit with a deduced ratio
*
* Defines a new unit with a deduced ratio and the given symbol based on the recipe from the provided
* derived dimension. The number and order of provided units should match the recipe of the
@ -229,7 +229,7 @@ struct prefixed_alias_unit : U {
/**
* @brief Unknown unit
*
*
* Used as a coherent unit of an unknown dimension.
*/
struct unknown_coherent_unit : unit<unknown_coherent_unit> {};

View File

@ -28,11 +28,11 @@ namespace units::isq::iec80000 {
struct binary_prefix : prefix_family {};
struct kibi : units::prefix<kibi, binary_prefix, "Ki", ratio( 1'024)> {};
struct mebi : units::prefix<mebi, binary_prefix, "Mi", ratio( 1'048'576)> {};
struct gibi : units::prefix<gibi, binary_prefix, "Gi", ratio( 1'073'741'824)> {};
struct tebi : units::prefix<tebi, binary_prefix, "Ti", ratio( 1'099'511'627'776)> {};
struct pebi : units::prefix<pebi, binary_prefix, "Pi", ratio( 1'125'899'906'842'624)> {};
struct kibi : units::prefix<kibi, binary_prefix, "Ki", ratio(1'024)> {};
struct mebi : units::prefix<mebi, binary_prefix, "Mi", ratio(1'048'576)> {};
struct gibi : units::prefix<gibi, binary_prefix, "Gi", ratio(1'073'741'824)> {};
struct tebi : units::prefix<tebi, binary_prefix, "Ti", ratio(1'099'511'627'776)> {};
struct pebi : units::prefix<pebi, binary_prefix, "Pi", ratio(1'125'899'906'842'624)> {};
struct exbi : units::prefix<exbi, binary_prefix, "Ei", ratio(1'152'921'504'606'846'976)> {};
} // namespace units::isq::iec80000

View File

@ -54,19 +54,55 @@ using modulation_rate = quantity<dim_modulation_rate, U, Rep>;
inline namespace literals {
constexpr auto operator"" _q_Bd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<baud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<kilobaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<megabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<gigabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<terabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<petabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<exabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<zettabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YBd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return modulation_rate<yottabaud, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Bd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<baud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<kilobaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<megabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<gigabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<terabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<petabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<exabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<zettabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YBd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return modulation_rate<yottabaud, std::int64_t>(static_cast<std::int64_t>(l));
}
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -90,7 +126,7 @@ using namespace modulation_rate_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::iec80000
@ -98,16 +134,25 @@ using namespace modulation_rate_references;
namespace units::aliases::isq::iec80000::inline modulation_rate {
template<Representation Rep = double> using Bd = units::isq::iec80000::modulation_rate<units::isq::iec80000::baud, Rep>;
template<Representation Rep = double> using kBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::kilobaud, Rep>;
template<Representation Rep = double> using MBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::megabaud, Rep>;
template<Representation Rep = double> using GBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::gigabaud, Rep>;
template<Representation Rep = double> using TBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::terabaud, Rep>;
template<Representation Rep = double> using PBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::petabaud, Rep>;
template<Representation Rep = double> using EBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::exabaud, Rep>;
template<Representation Rep = double> using ZBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::zettabaud, Rep>;
template<Representation Rep = double> using YBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::yottabaud, Rep>;
template<Representation Rep = double>
using Bd = units::isq::iec80000::modulation_rate<units::isq::iec80000::baud, Rep>;
template<Representation Rep = double>
using kBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::kilobaud, Rep>;
template<Representation Rep = double>
using MBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::megabaud, Rep>;
template<Representation Rep = double>
using GBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::gigabaud, Rep>;
template<Representation Rep = double>
using TBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::terabaud, Rep>;
template<Representation Rep = double>
using PBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::petabaud, Rep>;
template<Representation Rep = double>
using EBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::exabaud, Rep>;
template<Representation Rep = double>
using ZBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::zettabaud, Rep>;
template<Representation Rep = double>
using YBd = units::isq::iec80000::modulation_rate<units::isq::iec80000::yottabaud, Rep>;
} // namespace units::aliases::isq::iec80000::inline modulation_rate
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -84,46 +84,163 @@ using storage_capacity = quantity<dim_storage_capacity, U, Rep>;
inline namespace literals {
// bits
constexpr auto operator"" _q_bit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<bit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_bit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<bit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<kilobit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Mbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<megabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<gigabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Tbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<terabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<petabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ebit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<exabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Zbit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<zettabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ybit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<yottabit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<kilobit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Mbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<megabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<gigabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Tbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<terabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<petabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ebit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<exabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Zbit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<zettabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ybit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<yottabit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Kibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<kibibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Mibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<mebibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<gibibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Tibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<tebibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<pebibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Eibit(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<exbibit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Kibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<kibibit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Mibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<mebibit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<gibibit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Tibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<tebibit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<pebibit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Eibit(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<exbibit, std::int64_t>(static_cast<std::int64_t>(l));
}
// bytes
constexpr auto operator"" _q_B(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<byte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_B(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<byte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<kilobyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<megabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<gigabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<terabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<petabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<exabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<zettabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<yottabyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<kilobyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<megabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<gigabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<terabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<petabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<exabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<zettabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<yottabyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_KiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<kibibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<mebibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<gibibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<tebibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<pebibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
// constexpr auto operator"" _q_EiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return storage_capacity<exbibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_KiB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<kibibyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MiB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<mebibyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GiB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<gibibyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TiB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<tebibyte, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PiB(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return storage_capacity<pebibyte, std::int64_t>(static_cast<std::int64_t>(l));
}
// constexpr auto operator"" _q_EiB(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return
// storage_capacity<exbibyte, std::int64_t>(static_cast<std::int64_t>(l)); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -175,7 +292,7 @@ using namespace storage_capacity_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::iec80000
@ -184,43 +301,73 @@ using namespace storage_capacity_references;
namespace units::aliases::isq::iec80000::inline storage_capacity {
// bits
template<Representation Rep = double> using bit = units::isq::iec80000::storage_capacity<units::isq::iec80000::bit, Rep>;
template<Representation Rep = double>
using bit = units::isq::iec80000::storage_capacity<units::isq::iec80000::bit, Rep>;
template<Representation Rep = double> using kbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::kilobit, Rep>;
template<Representation Rep = double> using Mbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::megabit, Rep>;
template<Representation Rep = double> using Gbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::gigabit, Rep>;
template<Representation Rep = double> using Tbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::terabit, Rep>;
template<Representation Rep = double> using Pbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::petabit, Rep>;
template<Representation Rep = double> using Ebit = units::isq::iec80000::storage_capacity<units::isq::iec80000::exabit, Rep>;
template<Representation Rep = double> using Zbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::zettabit, Rep>;
template<Representation Rep = double> using Ybit = units::isq::iec80000::storage_capacity<units::isq::iec80000::yottabit, Rep>;
template<Representation Rep = double>
using kbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::kilobit, Rep>;
template<Representation Rep = double>
using Mbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::megabit, Rep>;
template<Representation Rep = double>
using Gbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::gigabit, Rep>;
template<Representation Rep = double>
using Tbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::terabit, Rep>;
template<Representation Rep = double>
using Pbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::petabit, Rep>;
template<Representation Rep = double>
using Ebit = units::isq::iec80000::storage_capacity<units::isq::iec80000::exabit, Rep>;
template<Representation Rep = double>
using Zbit = units::isq::iec80000::storage_capacity<units::isq::iec80000::zettabit, Rep>;
template<Representation Rep = double>
using Ybit = units::isq::iec80000::storage_capacity<units::isq::iec80000::yottabit, Rep>;
template<Representation Rep = double> using Kibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::kibibit, Rep>;
template<Representation Rep = double> using Mibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::mebibit, Rep>;
template<Representation Rep = double> using Gibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::gibibit, Rep>;
template<Representation Rep = double> using Tibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::tebibit, Rep>;
template<Representation Rep = double> using Pibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::pebibit, Rep>;
template<Representation Rep = double> using Eibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::exbibit, Rep>;
template<Representation Rep = double>
using Kibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::kibibit, Rep>;
template<Representation Rep = double>
using Mibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::mebibit, Rep>;
template<Representation Rep = double>
using Gibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::gibibit, Rep>;
template<Representation Rep = double>
using Tibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::tebibit, Rep>;
template<Representation Rep = double>
using Pibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::pebibit, Rep>;
template<Representation Rep = double>
using Eibit = units::isq::iec80000::storage_capacity<units::isq::iec80000::exbibit, Rep>;
// bytes
template<Representation Rep = double> using B = units::isq::iec80000::storage_capacity<units::isq::iec80000::byte, Rep>;
template<Representation Rep = double>
using B = units::isq::iec80000::storage_capacity<units::isq::iec80000::byte, Rep>;
template<Representation Rep = double> using kB = units::isq::iec80000::storage_capacity<units::isq::iec80000::kilobyte, Rep>;
template<Representation Rep = double> using MB = units::isq::iec80000::storage_capacity<units::isq::iec80000::megabyte, Rep>;
template<Representation Rep = double> using GB = units::isq::iec80000::storage_capacity<units::isq::iec80000::gigabyte, Rep>;
template<Representation Rep = double> using TB = units::isq::iec80000::storage_capacity<units::isq::iec80000::terabyte, Rep>;
template<Representation Rep = double> using PB = units::isq::iec80000::storage_capacity<units::isq::iec80000::petabyte, Rep>;
template<Representation Rep = double> using EB = units::isq::iec80000::storage_capacity<units::isq::iec80000::exabyte, Rep>;
template<Representation Rep = double> using ZB = units::isq::iec80000::storage_capacity<units::isq::iec80000::zettabyte, Rep>;
template<Representation Rep = double> using YB = units::isq::iec80000::storage_capacity<units::isq::iec80000::yottabyte, Rep>;
template<Representation Rep = double>
using kB = units::isq::iec80000::storage_capacity<units::isq::iec80000::kilobyte, Rep>;
template<Representation Rep = double>
using MB = units::isq::iec80000::storage_capacity<units::isq::iec80000::megabyte, Rep>;
template<Representation Rep = double>
using GB = units::isq::iec80000::storage_capacity<units::isq::iec80000::gigabyte, Rep>;
template<Representation Rep = double>
using TB = units::isq::iec80000::storage_capacity<units::isq::iec80000::terabyte, Rep>;
template<Representation Rep = double>
using PB = units::isq::iec80000::storage_capacity<units::isq::iec80000::petabyte, Rep>;
template<Representation Rep = double>
using EB = units::isq::iec80000::storage_capacity<units::isq::iec80000::exabyte, Rep>;
template<Representation Rep = double>
using ZB = units::isq::iec80000::storage_capacity<units::isq::iec80000::zettabyte, Rep>;
template<Representation Rep = double>
using YB = units::isq::iec80000::storage_capacity<units::isq::iec80000::yottabyte, Rep>;
template<Representation Rep = double> using KiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::kibibyte, Rep>;
template<Representation Rep = double> using MiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::mebibyte, Rep>;
template<Representation Rep = double> using GiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::gibibyte, Rep>;
template<Representation Rep = double> using TiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::tebibyte, Rep>;
template<Representation Rep = double> using PiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::pebibyte, Rep>;
// template<Representation Rep = double> using EiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::exbibyte, Rep>;
template<Representation Rep = double>
using KiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::kibibyte, Rep>;
template<Representation Rep = double>
using MiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::mebibyte, Rep>;
template<Representation Rep = double>
using GiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::gibibyte, Rep>;
template<Representation Rep = double>
using TiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::tebibyte, Rep>;
template<Representation Rep = double>
using PiB = units::isq::iec80000::storage_capacity<units::isq::iec80000::pebibyte, Rep>;
// template<Representation Rep = double> using EiB =
// units::isq::iec80000::storage_capacity<units::isq::iec80000::exbibyte, Rep>;
} // namespace units::aliases::isq::iec80000::inline storage_capacity
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -47,11 +47,15 @@ using traffic_intensity = quantity<dim_traffic_intensity, U, Rep>;
inline namespace literals {
constexpr auto operator"" _q_E(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return traffic_intensity<erlang, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_E(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return traffic_intensity<erlang, std::int64_t>(static_cast<std::int64_t>(l));
}
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -67,7 +71,7 @@ using namespace traffic_intensity_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::iec80000
@ -75,8 +79,9 @@ using namespace traffic_intensity_references;
namespace units::aliases::isq::iec80000::inline traffic_intensity {
template<Representation Rep = double> using E = units::isq::iec80000::traffic_intensity<units::isq::iec80000::erlang, Rep>;
template<Representation Rep = double>
using E = units::isq::iec80000::traffic_intensity<units::isq::iec80000::erlang, Rep>;
} // namespace units::aliases::isq::iec80000::inline traffic_intensity
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -35,7 +35,9 @@
namespace units::isq::iec80000 {
struct byte_per_second : unit<byte_per_second> {};
struct dim_transfer_rate : derived_dimension<dim_transfer_rate, byte_per_second, exponent<dim_storage_capacity, 1>, exponent<si::dim_time, -1>> {};
struct dim_transfer_rate :
derived_dimension<dim_transfer_rate, byte_per_second, exponent<dim_storage_capacity, 1>,
exponent<si::dim_time, -1>> {};
struct kilobyte_per_second : derived_unit<kilobyte_per_second, dim_transfer_rate, kilobyte, si::second> {};
struct megabyte_per_second : derived_unit<megabyte_per_second, dim_transfer_rate, megabyte, si::second> {};
@ -56,19 +58,55 @@ using transfer_rate = quantity<dim_transfer_rate, U, Rep>;
inline namespace literals {
constexpr auto operator"" _q_B_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<byte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<kilobyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<megabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<gigabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<terabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<petabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<exabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<zettabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YB_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return transfer_rate<yottabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_B_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<byte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<kilobyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<megabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<gigabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<terabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<petabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<exabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<zettabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YB_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return transfer_rate<yottabyte_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::iec80000
@ -76,16 +114,25 @@ constexpr auto operator"" _q_YB_per_s(unsigned long long l) { gsl_ExpectsAudit(s
namespace units::aliases::isq::iec80000::inline transfer_rate {
template<Representation Rep = double> using B_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::byte_per_second, Rep>;
template<Representation Rep = double> using kB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::kilobyte_per_second, Rep>;
template<Representation Rep = double> using MB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::megabyte_per_second, Rep>;
template<Representation Rep = double> using GB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::gigabyte_per_second, Rep>;
template<Representation Rep = double> using TB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::terabyte_per_second, Rep>;
template<Representation Rep = double> using PB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::petabyte_per_second, Rep>;
template<Representation Rep = double> using EB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::exabyte_per_second, Rep>;
template<Representation Rep = double> using ZB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::zettabyte_per_second, Rep>;
template<Representation Rep = double> using YB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::yottabyte_per_second, Rep>;
template<Representation Rep = double>
using B_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::byte_per_second, Rep>;
template<Representation Rep = double>
using kB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::kilobyte_per_second, Rep>;
template<Representation Rep = double>
using MB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::megabyte_per_second, Rep>;
template<Representation Rep = double>
using GB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::gigabyte_per_second, Rep>;
template<Representation Rep = double>
using TB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::terabyte_per_second, Rep>;
template<Representation Rep = double>
using PB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::petabyte_per_second, Rep>;
template<Representation Rep = double>
using EB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::exabyte_per_second, Rep>;
template<Representation Rep = double>
using ZB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::zettabyte_per_second, Rep>;
template<Representation Rep = double>
using YB_per_s = units::isq::iec80000::transfer_rate<units::isq::iec80000::yottabyte_per_second, Rep>;
} // namespace units::aliases::isq::iec80000::inline transfer_rate
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,13 +48,13 @@ inline constexpr auto GeV = reference<dim_acceleration, gigaelectronvolt>{};
} // namespace acceleration_references
namespace references {
namespace references {
using namespace acceleration_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -62,8 +62,9 @@ using namespace acceleration_references;
namespace units::aliases::isq::natural::inline acceleration {
template<Representation Rep = double> using GeV = units::isq::natural::acceleration<units::isq::natural::gigaelectronvolt, Rep>;
template<Representation Rep = double>
using GeV = units::isq::natural::acceleration<units::isq::natural::gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline acceleration
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,13 +48,13 @@ inline constexpr auto GeV = reference<dim_energy, gigaelectronvolt>{};
} // namespace energy_references
namespace references {
namespace references {
using namespace energy_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -62,8 +62,9 @@ using namespace energy_references;
namespace units::aliases::isq::natural::inline energy {
template<Representation Rep = double> using GeV = units::isq::natural::energy<units::isq::natural::gigaelectronvolt, Rep>;
template<Representation Rep = double>
using GeV = units::isq::natural::energy<units::isq::natural::gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline energy
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,13 +48,13 @@ inline constexpr auto GeV2 = reference<dim_force, square_gigaelectronvolt>{};
} // namespace force_references
namespace references {
namespace references {
using namespace force_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -62,8 +62,9 @@ using namespace force_references;
namespace units::aliases::isq::natural::inline force {
template<Representation Rep = double> using GeV2 = units::isq::natural::force<units::isq::natural::square_gigaelectronvolt, Rep>;
template<Representation Rep = double>
using GeV2 = units::isq::natural::force<units::isq::natural::square_gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline force
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,13 +45,13 @@ inline constexpr auto inv_GeV = reference<dim_length, inverted_gigaelectronvolt>
} // namespace length_references
namespace references {
namespace references {
using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -59,8 +59,9 @@ using namespace length_references;
namespace units::aliases::isq::natural::inline length {
template<Representation Rep = double> using inv_GeV = units::isq::natural::length<units::isq::natural::inverted_gigaelectronvolt, Rep>;
template<Representation Rep = double>
using inv_GeV = units::isq::natural::length<units::isq::natural::inverted_gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,13 +45,13 @@ inline constexpr auto GeV = reference<dim_mass, gigaelectronvolt>{};
} // namespace mass_references
namespace references {
namespace references {
using namespace mass_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -59,8 +59,9 @@ using namespace mass_references;
namespace units::aliases::isq::natural::inline mass {
template<Representation Rep = double> using GeV = units::isq::natural::mass<units::isq::natural::gigaelectronvolt, Rep>;
template<Representation Rep = double>
using GeV = units::isq::natural::mass<units::isq::natural::gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline mass
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,13 +48,13 @@ inline constexpr auto GeV = reference<dim_momentum, gigaelectronvolt>{};
} // namespace momentum_references
namespace references {
namespace references {
using namespace momentum_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -62,8 +62,9 @@ using namespace momentum_references;
namespace units::aliases::isq::natural::inline momentum {
template<Representation Rep = double> using GeV = units::isq::natural::momentum<units::isq::natural::gigaelectronvolt, Rep>;
template<Representation Rep = double>
using GeV = units::isq::natural::momentum<units::isq::natural::gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline momentum
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,13 +45,13 @@ inline constexpr auto inv_GeV = reference<dim_time, inverted_gigaelectronvolt>{}
} // namespace time_references
namespace references {
namespace references {
using namespace time_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::natural
@ -59,8 +59,9 @@ using namespace time_references;
namespace units::aliases::isq::natural::inline time {
template<Representation Rep = double> using inv_GeV = units::isq::natural::time<units::isq::natural::inverted_gigaelectronvolt, Rep>;
template<Representation Rep = double>
using inv_GeV = units::isq::natural::time<units::isq::natural::inverted_gigaelectronvolt, Rep>;
} // namespace units::aliases::isq::natural::inline time
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -33,7 +33,8 @@ namespace units::isq::natural {
struct electronvolt : named_unit<electronvolt, "eV", si::prefix> {};
struct gigaelectronvolt : prefixed_unit<gigaelectronvolt, si::giga, electronvolt> {};
struct inverted_gigaelectronvolt : named_unit<inverted_gigaelectronvolt, basic_symbol_text{"GeV⁻¹", "GeV^-1"}, no_prefix> {};
struct inverted_gigaelectronvolt :
named_unit<inverted_gigaelectronvolt, basic_symbol_text{"GeV⁻¹", "GeV^-1"}, no_prefix> {};
struct square_gigaelectronvolt : named_unit<square_gigaelectronvolt, basic_symbol_text{"GeV²", "GeV^2"}, no_prefix> {};
// NOTE: eV as a base unit with no relation to joule prevents us from going back

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/generic/angle.h>
#include <units/concepts.h>
#include <units/generic/angle.h>
#include <units/isq/dimensions/time.h>
namespace units::isq {
@ -34,7 +34,7 @@ struct dim_angular_velocity;
template<typename Child, Unit U, DimensionOfT<dim_angle> A, DimensionOfT<dim_time> T>
struct dim_angular_velocity<Child, U, A, T> : derived_dimension<Child, U, exponent<A, 1>, exponent<T, -1>> {};
template <typename T>
template<typename T>
concept AngularVelocity = QuantityOfT<T, dim_angular_velocity>;
} // namespace units::isq

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/concepts.h>
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/isq/dimensions/time.h>
namespace units::isq {

View File

@ -23,8 +23,8 @@
#pragma once
#include <units/concepts.h>
#include <units/isq/dimensions/length.h>
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/isq/dimensions/length.h>
namespace units::isq {

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/acceleration.h>
#include <units/concepts.h>
#include <units/isq/dimensions/acceleration.h>
#include <units/isq/dimensions/mass.h>
namespace units::isq {

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/concepts.h>
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/isq/dimensions/energy.h>
#include <units/isq/dimensions/mass.h>
#include <units/isq/dimensions/thermodynamic_temperature.h>

View File

@ -23,8 +23,8 @@
#pragma once
#include <units/concepts.h>
#include <units/isq/dimensions/luminous_intensity.h>
#include <units/isq/dimensions/length.h>
#include <units/isq/dimensions/luminous_intensity.h>
namespace units::isq {

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/area.h>
#include <units/concepts.h>
#include <units/isq/dimensions/area.h>
#include <units/isq/dimensions/magnetic_induction.h>
namespace units::isq {

View File

@ -29,11 +29,12 @@
namespace units::isq {
template <typename Child, Unit U, typename...>
template<typename Child, Unit U, typename...>
struct dim_magnetic_induction;
template <typename Child, Unit U, DimensionOfT<dim_voltage> V, DimensionOfT<dim_time> T, DimensionOfT<dim_length> L>
struct dim_magnetic_induction<Child, U, V, T, L> : derived_dimension<Child, U, exponent<V, 1>, exponent<T, 1>, exponent<L, -2>> {};
template<typename Child, Unit U, DimensionOfT<dim_voltage> V, DimensionOfT<dim_time> T, DimensionOfT<dim_length> L>
struct dim_magnetic_induction<Child, U, V, T, L> :
derived_dimension<Child, U, exponent<V, 1>, exponent<T, 1>, exponent<L, -2>> {};
template<typename T>
concept MagneticInduction = QuantityOfT<T, dim_magnetic_induction>;

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/concepts.h>
#include <units/isq/dimensions/amount_of_substance.h>
#include <units/isq/dimensions/energy.h>
namespace units::isq {

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/capacitance.h>
#include <units/concepts.h>
#include <units/isq/dimensions/capacitance.h>
#include <units/isq/dimensions/length.h>
namespace units::isq {

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/isq/dimensions/area.h>
#include <units/concepts.h>
#include <units/isq/dimensions/area.h>
#include <units/isq/dimensions/force.h>
namespace units::isq {

View File

@ -28,11 +28,11 @@
namespace units::isq {
template <typename Child, Unit U, typename...>
template<typename Child, Unit U, typename...>
struct dim_resistance;
template <typename Child, Unit U, DimensionOfT<dim_voltage> V, DimensionOfT<dim_electric_current> C>
struct dim_resistance<Child, U, V, C> : derived_dimension<Child,U, exponent<V, 1>, exponent<C, -1>> {};
template<typename Child, Unit U, DimensionOfT<dim_voltage> V, DimensionOfT<dim_electric_current> C>
struct dim_resistance<Child, U, V, C> : derived_dimension<Child, U, exponent<V, 1>, exponent<C, -1>> {};
template<typename T>
concept Resistance = QuantityOfT<T, dim_resistance>;

View File

@ -32,8 +32,10 @@ namespace units::isq {
template<typename Child, Unit U, typename...>
struct dim_thermal_conductivity;
template<typename Child, Unit U, DimensionOfT<dim_power> P, DimensionOfT<dim_length> L, DimensionOfT<dim_thermodynamic_temperature> T>
struct dim_thermal_conductivity<Child, U, P, L, T> : derived_dimension<Child, U, exponent<P, 1>, exponent<L, -1>, exponent<T, -1>> {};
template<typename Child, Unit U, DimensionOfT<dim_power> P, DimensionOfT<dim_length> L,
DimensionOfT<dim_thermodynamic_temperature> T>
struct dim_thermal_conductivity<Child, U, P, L, T> :
derived_dimension<Child, U, exponent<P, 1>, exponent<L, -1>, exponent<T, -1>> {};
template<typename T>
concept ThermalConductivity = QuantityOfT<T, dim_thermal_conductivity>;

View File

@ -22,8 +22,8 @@
#pragma once
#include <units/generic/angle.h>
#include <units/concepts.h>
#include <units/generic/angle.h>
#include <units/isq/dimensions/energy.h>
namespace units::isq {

View File

@ -45,12 +45,16 @@ using acceleration = quantity<dim_acceleration, U, Rep>;
inline namespace literals {
// Gal
constexpr auto operator"" _q_Gal(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return acceleration<gal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gal(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return acceleration<gal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gal(long double l) { return acceleration<gal, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -66,7 +70,7 @@ using namespace acceleration_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -74,8 +78,9 @@ using namespace acceleration_references;
namespace units::aliases::isq::si::cgs::inline acceleration {
template<Representation Rep = double> using Gal = units::isq::si::cgs::acceleration<units::isq::si::cgs::gal, Rep>;
template<Representation Rep = double>
using Gal = units::isq::si::cgs::acceleration<units::isq::si::cgs::gal, Rep>;
} // namespace units::aliases::isq::si::cgs::inline acceleration
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -47,12 +47,16 @@ using area = quantity<dim_area, U, Rep>;
inline namespace literals {
// cm2
constexpr auto operator"" _q_cm2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return area<square_centimetre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cm2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return area<square_centimetre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cm2(long double l) { return area<square_centimetre, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -68,7 +72,7 @@ using namespace area_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -76,8 +80,9 @@ using namespace area_references;
namespace units::aliases::isq::si::cgs::inline area {
template<Representation Rep = double> using cm2 = units::isq::si::cgs::area<units::isq::si::cgs::square_centimetre, Rep>;
template<Representation Rep = double>
using cm2 = units::isq::si::cgs::area<units::isq::si::cgs::square_centimetre, Rep>;
} // namespace units::aliases::isq::si::cgs::inline area
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -23,15 +23,14 @@
#pragma once
// IWYU pragma: begin_exports
#include <units/isq/si/cgs/length.h>
#include <units/isq/si/cgs/mass.h>
#include <units/isq/si/cgs/time.h>
#include <units/isq/si/cgs/acceleration.h>
#include <units/isq/si/cgs/area.h>
#include <units/isq/si/cgs/energy.h>
#include <units/isq/si/cgs/force.h>
#include <units/isq/si/cgs/length.h>
#include <units/isq/si/cgs/mass.h>
#include <units/isq/si/cgs/power.h>
#include <units/isq/si/cgs/pressure.h>
#include <units/isq/si/cgs/speed.h>
#include <units/isq/si/cgs/time.h>
// IWYU pragma: end_exports

View File

@ -47,12 +47,16 @@ using energy = quantity<dim_energy, U, Rep>;
inline namespace literals {
// erg
constexpr auto operator"" _q_erg(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<erg, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_erg(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<erg, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_erg(long double l) { return energy<erg, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -68,7 +72,7 @@ using namespace energy_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -76,8 +80,9 @@ using namespace energy_references;
namespace units::aliases::isq::si::cgs::inline energy {
template<Representation Rep = double> using erg = units::isq::si::cgs::energy<units::isq::si::cgs::erg, Rep>;
template<Representation Rep = double>
using erg = units::isq::si::cgs::energy<units::isq::si::cgs::erg, Rep>;
} // namespace units::aliases::isq::si::cgs::inline energy
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,12 +48,16 @@ using force = quantity<dim_force, U, Rep>;
inline namespace literals {
// dyn
constexpr auto operator"" _q_dyn(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return force<dyne, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dyn(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return force<dyne, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dyn(long double l) { return force<dyne, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -69,7 +73,7 @@ using namespace force_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -77,8 +81,9 @@ using namespace force_references;
namespace units::aliases::isq::si::cgs::inline force {
template<Representation Rep = double> using dyn = units::isq::si::cgs::force<units::isq::si::cgs::dyne, Rep>;
template<Representation Rep = double>
using dyn = units::isq::si::cgs::force<units::isq::si::cgs::dyne, Rep>;
} // namespace units::aliases::isq::si::cgs::inline force
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -46,12 +46,16 @@ using length = quantity<dim_length, U, Rep>;
inline namespace literals {
// cm
constexpr auto operator"" _q_cm(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<centimetre, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cm(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<centimetre, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cm(long double l) { return length<centimetre, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -67,7 +71,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -75,8 +79,9 @@ using namespace length_references;
namespace units::aliases::isq::si::cgs::inline length {
template<Representation Rep = double> using cm = units::isq::si::cgs::length<units::isq::si::cgs::centimetre, Rep>;
template<Representation Rep = double>
using cm = units::isq::si::cgs::length<units::isq::si::cgs::centimetre, Rep>;
} // namespace units::aliases::isq::si::cgs::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -46,12 +46,16 @@ using mass = quantity<dim_mass, U, Rep>;
inline namespace literals {
// g
constexpr auto operator"" _q_g(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<gram, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_g(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<gram, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_g(long double l) { return mass<gram, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -67,7 +71,7 @@ using namespace mass_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -75,8 +79,9 @@ using namespace mass_references;
namespace units::aliases::isq::si::cgs::inline mass {
template<Representation Rep = double> using g = units::isq::si::cgs::mass<units::isq::si::cgs::gram, Rep>;
template<Representation Rep = double>
using g = units::isq::si::cgs::mass<units::isq::si::cgs::gram, Rep>;
} // namespace units::aliases::isq::si::cgs::inline mass
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -46,12 +46,16 @@ using power = quantity<dim_power, U, Rep>;
inline namespace literals {
// erg/s
constexpr auto operator"" _q_erg_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return power<erg_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_erg_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return power<erg_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_erg_per_s(long double l) { return power<erg_per_second, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si::cgs
@ -59,8 +63,9 @@ constexpr auto operator"" _q_erg_per_s(long double l) { return power<erg_per_sec
namespace units::aliases::isq::si::cgs::inline power {
template<Representation Rep = double> using erg_per_s = units::isq::si::cgs::power<units::isq::si::cgs::erg_per_second, Rep>;
template<Representation Rep = double>
using erg_per_s = units::isq::si::cgs::power<units::isq::si::cgs::erg_per_second, Rep>;
} // namespace units::aliases::isq::si::cgs::inline power
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -48,12 +48,16 @@ using pressure = quantity<dim_pressure, U, Rep>;
inline namespace literals {
// Ba
constexpr auto operator"" _q_Ba(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return pressure<barye, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ba(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return pressure<barye, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ba(long double l) { return pressure<barye, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -69,7 +73,7 @@ using namespace pressure_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -77,8 +81,9 @@ using namespace pressure_references;
namespace units::aliases::isq::si::cgs::inline pressure {
template<Representation Rep = double> using Ba = units::isq::si::cgs::pressure<units::isq::si::cgs::barye, Rep>;
template<Representation Rep = double>
using Ba = units::isq::si::cgs::pressure<units::isq::si::cgs::barye, Rep>;
} // namespace units::aliases::isq::si::cgs::inline pressure
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,12 +45,16 @@ using speed = quantity<dim_speed, U, Rep>;
inline namespace literals {
// cm/s
constexpr auto operator"" _q_cm_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return speed<centimetre_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cm_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return speed<centimetre_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cm_per_s(long double l) { return speed<centimetre_per_second, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si::cgs
@ -58,8 +62,9 @@ constexpr auto operator"" _q_cm_per_s(long double l) { return speed<centimetre_p
namespace units::aliases::isq::si::cgs::inline speed {
template<Representation Rep = double> using cm_per_s = units::isq::si::cgs::speed<units::isq::si::cgs::centimetre_per_second, Rep>;
template<Representation Rep = double>
using cm_per_s = units::isq::si::cgs::speed<units::isq::si::cgs::centimetre_per_second, Rep>;
} // namespace units::aliases::isq::si::cgs::inline speed
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,7 +45,7 @@ using si::literals::operator"" _q_s;
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -61,7 +61,7 @@ using namespace time_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::cgs
@ -73,4 +73,4 @@ using namespace units::aliases::isq::si::time;
} // namespace units::aliases::isq::si::cgs::inline time
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -41,8 +41,8 @@ struct inch : named_scaled_unit<inch, "in", no_prefix, ratio(1, 12), foot> {};
// thousandth of an inch
struct thousandth : named_scaled_unit<thousandth, "thou", no_prefix, ratio(1, 1'000), inch> {};
struct thou : alias_unit<thousandth, "thou", no_prefix>{};
struct mil : alias_unit<thousandth, "mil", no_prefix>{};
struct thou : alias_unit<thousandth, "thou", no_prefix> {};
struct mil : alias_unit<thousandth, "mil", no_prefix> {};
struct yard : named_scaled_unit<yard, "yd", si::prefix, ratio(3, 1), foot> {};
@ -64,43 +64,79 @@ using length = quantity<dim_length, U, Rep>;
inline namespace literals {
// Thousandth
constexpr auto operator"" _q_thou(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<thousandth, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_thou(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<thousandth, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_thou(long double l) { return length<thousandth, long double>(l); }
constexpr auto operator"" _q_mil(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<thousandth, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mil(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<thousandth, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mil(long double l) { return length<thousandth, long double>(l); }
// Inch
constexpr auto operator"" _q_in(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<inch, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_in(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<inch, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_in(long double l) { return length<inch, long double>(l); }
// Foot
constexpr auto operator"" _q_ft(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft(long double l) { return length<foot, long double>(l); }
// Yard
constexpr auto operator"" _q_yd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<yard, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<yard, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yd(long double l) { return length<yard, long double>(l); }
// Fathom
constexpr auto operator"" _q_ftm(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<fathom, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ftm(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<fathom, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ftm(long double l) { return length<fathom, long double>(l); }
// Kiloyard
constexpr auto operator"" _q_kyd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<kiloyard, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kyd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<kiloyard, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kyd(long double l) { return length<kiloyard, long double>(l); }
// Mile
constexpr auto operator"" _q_mile(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<mile, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mile(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<mile, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mile(long double l) { return length<mile, long double>(l); }
// Nautical mile
constexpr auto operator"" _q_naut_mi(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return length<nautical_mile, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_naut_mi(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return length<nautical_mile, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_naut_mi(long double l) { return length<nautical_mile, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -125,7 +161,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::fps
@ -133,17 +169,26 @@ using namespace length_references;
namespace units::aliases::isq::si::fps::inline length {
template<Representation Rep = double> using thou = units::isq::si::fps::length<units::isq::si::fps::thousandth, Rep>;
template<Representation Rep = double> using mil = thou<Rep>;
template<Representation Rep = double>
using thou = units::isq::si::fps::length<units::isq::si::fps::thousandth, Rep>;
template<Representation Rep = double>
using mil = thou<Rep>;
template<Representation Rep = double> using in = units::isq::si::fps::length<units::isq::si::fps::inch, Rep>;
template<Representation Rep = double> using ft = units::isq::si::fps::length<units::isq::si::fps::foot, Rep>;
template<Representation Rep = double> using yd = units::isq::si::fps::length<units::isq::si::fps::yard, Rep>;
template<Representation Rep = double> using ftm = units::isq::si::fps::length<units::isq::si::fps::fathom, Rep>;
template<Representation Rep = double> using kyd = units::isq::si::fps::length<units::isq::si::fps::kiloyard, Rep>;
template<Representation Rep = double> using mile = units::isq::si::fps::length<units::isq::si::fps::mile, Rep>;
template<Representation Rep = double> using naut_mi = units::isq::si::fps::length<units::isq::si::fps::nautical_mile, Rep>;
template<Representation Rep = double>
using in = units::isq::si::fps::length<units::isq::si::fps::inch, Rep>;
template<Representation Rep = double>
using ft = units::isq::si::fps::length<units::isq::si::fps::foot, Rep>;
template<Representation Rep = double>
using yd = units::isq::si::fps::length<units::isq::si::fps::yard, Rep>;
template<Representation Rep = double>
using ftm = units::isq::si::fps::length<units::isq::si::fps::fathom, Rep>;
template<Representation Rep = double>
using kyd = units::isq::si::fps::length<units::isq::si::fps::kiloyard, Rep>;
template<Representation Rep = double>
using mile = units::isq::si::fps::length<units::isq::si::fps::mile, Rep>;
template<Representation Rep = double>
using naut_mi = units::isq::si::fps::length<units::isq::si::fps::nautical_mile, Rep>;
} // namespace units::aliases::isq::si::fps::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -42,65 +42,101 @@ struct dim_mass : isq::dim_mass<pound> {};
template<UnitOf<dim_mass> U, Representation Rep = double>
using mass = quantity<dim_mass, U, Rep>;
struct grain : named_scaled_unit<grain, "gr", no_prefix, ratio(1, 7000), pound>{};
struct grain : named_scaled_unit<grain, "gr", no_prefix, ratio(1, 7000), pound> {};
struct dram : named_scaled_unit<dram, "dr", no_prefix, ratio(1, 256), pound>{};
struct dram : named_scaled_unit<dram, "dr", no_prefix, ratio(1, 256), pound> {};
struct ounce : named_scaled_unit<ounce, "oz", no_prefix, ratio(1, 16), pound>{};
struct ounce : named_scaled_unit<ounce, "oz", no_prefix, ratio(1, 16), pound> {};
struct stone : named_scaled_unit<stone, "st", no_prefix, ratio(14, 1), pound>{};
struct stone : named_scaled_unit<stone, "st", no_prefix, ratio(14, 1), pound> {};
struct quarter : named_scaled_unit<quarter, "qr", no_prefix, ratio(28, 1), pound>{};
struct quarter : named_scaled_unit<quarter, "qr", no_prefix, ratio(28, 1), pound> {};
struct hundredweight : named_scaled_unit<hundredweight, "cwt", no_prefix, ratio(112, 1), pound>{};
struct hundredweight : named_scaled_unit<hundredweight, "cwt", no_prefix, ratio(112, 1), pound> {};
struct short_ton : named_scaled_unit<short_ton, "ton (short)", no_prefix, ratio(2'000, 1), pound>{};
struct short_ton : named_scaled_unit<short_ton, "ton (short)", no_prefix, ratio(2'000, 1), pound> {};
struct long_ton : named_scaled_unit<long_ton, "ton (long)", no_prefix, ratio(2'240, 1), pound>{};
struct long_ton : named_scaled_unit<long_ton, "ton (long)", no_prefix, ratio(2'240, 1), pound> {};
#ifndef UNITS_NO_LITERALS
inline namespace literals {
// Grain
constexpr auto operator"" _q_gr(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<grain, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_gr(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<grain, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_gr(long double l) { return mass<grain, long double>(l); }
// Dram
constexpr auto operator"" _q_dr(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<dram, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dr(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<dram, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dr(long double l) { return mass<dram, long double>(l); }
// Ounce
constexpr auto operator"" _q_oz(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<ounce, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_oz(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<ounce, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_oz(long double l) { return mass<ounce, long double>(l); }
// Pound
constexpr auto operator"" _q_lb(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<pound, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_lb(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<pound, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_lb(long double l) { return mass<pound, long double>(l); }
// Stone
constexpr auto operator"" _q_st(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<stone, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_st(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<stone, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_st(long double l) { return mass<stone, long double>(l); }
// Quarter
constexpr auto operator"" _q_qr(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<quarter, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_qr(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<quarter, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_qr(long double l) { return mass<quarter, long double>(l); }
// Hundredweight
constexpr auto operator"" _q_cwt(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<hundredweight, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_cwt(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<hundredweight, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_cwt(long double l) { return mass<hundredweight, long double>(l); }
// Short ton
constexpr auto operator"" _q_ston(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<short_ton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ston(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<short_ton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ston(long double l) { return mass<short_ton, long double>(l); }
// Long Ton
constexpr auto operator"" _q_lton(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<long_ton, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_lton(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<long_ton, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_lton(long double l) { return mass<long_ton, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -124,7 +160,7 @@ using namespace mass_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::fps
@ -132,16 +168,25 @@ using namespace mass_references;
namespace units::aliases::isq::si::fps::inline mass {
template<Representation Rep = double> using gr = units::isq::si::fps::mass<units::isq::si::fps::grain, Rep>;
template<Representation Rep = double> using dr = units::isq::si::fps::mass<units::isq::si::fps::dram, Rep>;
template<Representation Rep = double> using oz = units::isq::si::fps::mass<units::isq::si::fps::ounce, Rep>;
template<Representation Rep = double> using lb = units::isq::si::fps::mass<units::isq::si::fps::pound, Rep>;
template<Representation Rep = double> using st = units::isq::si::fps::mass<units::isq::si::fps::stone, Rep>;
template<Representation Rep = double> using qr = units::isq::si::fps::mass<units::isq::si::fps::quarter, Rep>;
template<Representation Rep = double> using cwt = units::isq::si::fps::mass<units::isq::si::fps::hundredweight, Rep>;
template<Representation Rep = double> using ston = units::isq::si::fps::mass<units::isq::si::fps::short_ton, Rep>;
template<Representation Rep = double> using lton = units::isq::si::fps::mass<units::isq::si::fps::long_ton, Rep>;
template<Representation Rep = double>
using gr = units::isq::si::fps::mass<units::isq::si::fps::grain, Rep>;
template<Representation Rep = double>
using dr = units::isq::si::fps::mass<units::isq::si::fps::dram, Rep>;
template<Representation Rep = double>
using oz = units::isq::si::fps::mass<units::isq::si::fps::ounce, Rep>;
template<Representation Rep = double>
using lb = units::isq::si::fps::mass<units::isq::si::fps::pound, Rep>;
template<Representation Rep = double>
using st = units::isq::si::fps::mass<units::isq::si::fps::stone, Rep>;
template<Representation Rep = double>
using qr = units::isq::si::fps::mass<units::isq::si::fps::quarter, Rep>;
template<Representation Rep = double>
using cwt = units::isq::si::fps::mass<units::isq::si::fps::hundredweight, Rep>;
template<Representation Rep = double>
using ston = units::isq::si::fps::mass<units::isq::si::fps::short_ton, Rep>;
template<Representation Rep = double>
using lton = units::isq::si::fps::mass<units::isq::si::fps::long_ton, Rep>;
} // namespace units::aliases::isq::si::fps::inline mass
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -51,20 +51,32 @@ using power = quantity<dim_power, U, Rep>;
inline namespace literals {
// foot pound force per second
constexpr auto operator"" _q_ft_pdl_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return power<foot_poundal_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_pdl_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return power<foot_poundal_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_pdl_per_s(long double l) { return power<foot_poundal_per_second, long double>(l); }
// foot pound force per second
constexpr auto operator"" _q_ft_lbf_per_s(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return power<foot_pound_force_per_second, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_lbf_per_s(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return power<foot_pound_force_per_second, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_lbf_per_s(long double l) { return power<foot_pound_force_per_second, long double>(l); }
// horse power
constexpr auto operator"" _q_hp(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return power<horse_power, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hp(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return power<horse_power, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hp(long double l) { return power<horse_power, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -80,7 +92,7 @@ using namespace power_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::fps
@ -88,10 +100,13 @@ using namespace power_references;
namespace units::aliases::isq::si::fps::inline power {
template<Representation Rep = double> using ft_pdl_per_s = units::isq::si::fps::power<units::isq::si::fps::foot_poundal_per_second, Rep>;
template<Representation Rep = double> using ft_lbf_per_s = units::isq::si::fps::power<units::isq::si::fps::foot_pound_force_per_second, Rep>;
template<Representation Rep = double> using hp = units::isq::si::fps::power<units::isq::si::fps::horse_power, Rep>;
template<Representation Rep = double>
using ft_pdl_per_s = units::isq::si::fps::power<units::isq::si::fps::foot_poundal_per_second, Rep>;
template<Representation Rep = double>
using ft_lbf_per_s = units::isq::si::fps::power<units::isq::si::fps::foot_pound_force_per_second, Rep>;
template<Representation Rep = double>
using hp = units::isq::si::fps::power<units::isq::si::fps::horse_power, Rep>;
} // namespace units::aliases::isq::si::fps::inline power
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -34,9 +34,9 @@
namespace units::isq::si::fps {
using si::second;
using si::minute;
using si::hour;
using si::minute;
using si::second;
using si::dim_time;
using si::time;
@ -49,7 +49,7 @@ using si::literals::operator"" _q_s;
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -65,7 +65,7 @@ using namespace time_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::fps
@ -77,4 +77,4 @@ using namespace units::aliases::isq::si::time;
} // namespace units::aliases::isq::si::fps::inline time
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -47,16 +47,24 @@ using volume = quantity<dim_volume, U, Rep>;
inline namespace literals {
// ft3
constexpr auto operator"" _q_ft3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return volume<cubic_foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return volume<cubic_foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft3(long double l) { return volume<cubic_foot, long double>(l); }
// yd3
constexpr auto operator"" _q_yd3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return volume<cubic_yard, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yd3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return volume<cubic_yard, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yd3(long double l) { return volume<cubic_yard, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -73,7 +81,7 @@ using namespace volume_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::fps
@ -81,9 +89,11 @@ using namespace volume_references;
namespace units::aliases::isq::si::fps::inline volume {
template<Representation Rep = double> using ft3 = units::isq::si::fps::volume<units::isq::si::fps::cubic_foot, Rep>;
template<Representation Rep = double> using yd3 = units::isq::si::fps::volume<units::isq::si::fps::cubic_yard, Rep>;
template<Representation Rep = double>
using ft3 = units::isq::si::fps::volume<units::isq::si::fps::cubic_foot, Rep>;
template<Representation Rep = double>
using yd3 = units::isq::si::fps::volume<units::isq::si::fps::cubic_yard, Rep>;
} // namespace units::aliases::isq::si::fps::inline volume
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -34,9 +34,9 @@
namespace units::isq::si::hep {
using units::isq::si::electronvolt;
struct yeV : prefixed_unit<yeV, yocto, electronvolt> {}; // N.B. very rarely used
struct zeV : prefixed_unit<zeV, zepto, electronvolt> {}; // N.B. very rarely used
struct aeV : prefixed_unit<aeV, atto, electronvolt> {}; // N.B. very rarely used
struct yeV : prefixed_unit<yeV, yocto, electronvolt> {}; // N.B. very rarely used
struct zeV : prefixed_unit<zeV, zepto, electronvolt> {}; // N.B. very rarely used
struct aeV : prefixed_unit<aeV, atto, electronvolt> {}; // N.B. very rarely used
struct feV : prefixed_unit<feV, femto, electronvolt> {};
struct peV : prefixed_unit<peV, pico, electronvolt> {};
struct neV : prefixed_unit<neV, nano, electronvolt> {};
@ -48,9 +48,9 @@ struct MeV : prefixed_unit<MeV, mega, electronvolt> {};
using GeV = gigaelectronvolt;
struct TeV : prefixed_unit<TeV, tera, electronvolt> {};
struct PeV : prefixed_unit<PeV, peta, electronvolt> {};
struct EeV : prefixed_unit<EeV, exa, electronvolt> {}; // N.B. very rarely used
struct ZeV : prefixed_unit<ZeV, zetta, electronvolt> {}; // N.B. very rarely used
struct YeV : prefixed_unit<YeV, yotta, electronvolt> {}; // N.B. very rarely used
struct EeV : prefixed_unit<EeV, exa, electronvolt> {}; // N.B. very rarely used
struct ZeV : prefixed_unit<ZeV, zetta, electronvolt> {}; // N.B. very rarely used
struct YeV : prefixed_unit<YeV, yotta, electronvolt> {}; // N.B. very rarely used
template<UnitOf<dim_energy> U, Representation Rep = double>
using energy = quantity<dim_energy, U, Rep>;
@ -59,39 +59,95 @@ using energy = quantity<dim_energy, U, Rep>;
inline namespace literals {
constexpr auto operator"" _q_feV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<feV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_feV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<feV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_feV(long double l) { return energy<feV, long double>(l); }
constexpr auto operator"" _q_peV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<peV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_peV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<peV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_peV(long double l) { return energy<peV, long double>(l); }
constexpr auto operator"" _q_neV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<neV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_neV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<neV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_neV(long double l) { return energy<ueV, long double>(l); }
constexpr auto operator"" _q_ueV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<neV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ueV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<neV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ueV(long double l) { return energy<ueV, long double>(l); }
constexpr auto operator"" _q_meV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<meV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_meV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<meV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_meV(long double l) { return energy<meV, long double>(l); }
constexpr auto operator"" _q_eV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<eV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_eV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<eV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_eV(long double l) { return energy<eV, long double>(l); }
constexpr auto operator"" _q_keV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<keV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_keV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<keV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_keV(long double l) { return energy<keV, long double>(l); }
constexpr auto operator"" _q_MeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<MeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<MeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MeV(long double l) { return energy<MeV, long double>(l); }
constexpr auto operator"" _q_GeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<GeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<GeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GeV(long double l) { return energy<GeV, long double>(l); }
constexpr auto operator"" _q_TeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<TeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<TeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TeV(long double l) { return energy<TeV, long double>(l); }
constexpr auto operator"" _q_PeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<PeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<PeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PeV(long double l) { return energy<PeV, long double>(l); }
constexpr auto operator"" _q_EeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<EeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<EeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EeV(long double l) { return energy<EeV, long double>(l); }
constexpr auto operator"" _q_ZeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<ZeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ZeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<ZeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ZeV(long double l) { return energy<ZeV, long double>(l); }
constexpr auto operator"" _q_YeV(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return energy<YeV, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YeV(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return energy<YeV, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YeV(long double l) { return energy<YeV, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -107,7 +163,7 @@ using namespace energy_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::hep
@ -115,26 +171,43 @@ using namespace energy_references;
namespace units::aliases::isq::si::hep::inline energy {
template<Representation Rep = double> using yeV = units::isq::si::hep::energy<units::isq::si::hep::yeV, Rep>;
template<Representation Rep = double> using zeV = units::isq::si::hep::energy<units::isq::si::hep::zeV, Rep>;
template<Representation Rep = double> using aeV = units::isq::si::hep::energy<units::isq::si::hep::aeV, Rep>;
template<Representation Rep = double> using feV = units::isq::si::hep::energy<units::isq::si::hep::feV, Rep>;
template<Representation Rep = double> using peV = units::isq::si::hep::energy<units::isq::si::hep::peV, Rep>;
template<Representation Rep = double> using neV = units::isq::si::hep::energy<units::isq::si::hep::neV, Rep>;
template<Representation Rep = double> using ueV = units::isq::si::hep::energy<units::isq::si::hep::ueV, Rep>;
template<Representation Rep = double> using meV = units::isq::si::hep::energy<units::isq::si::hep::meV, Rep>;
template<Representation Rep = double>
using yeV = units::isq::si::hep::energy<units::isq::si::hep::yeV, Rep>;
template<Representation Rep = double>
using zeV = units::isq::si::hep::energy<units::isq::si::hep::zeV, Rep>;
template<Representation Rep = double>
using aeV = units::isq::si::hep::energy<units::isq::si::hep::aeV, Rep>;
template<Representation Rep = double>
using feV = units::isq::si::hep::energy<units::isq::si::hep::feV, Rep>;
template<Representation Rep = double>
using peV = units::isq::si::hep::energy<units::isq::si::hep::peV, Rep>;
template<Representation Rep = double>
using neV = units::isq::si::hep::energy<units::isq::si::hep::neV, Rep>;
template<Representation Rep = double>
using ueV = units::isq::si::hep::energy<units::isq::si::hep::ueV, Rep>;
template<Representation Rep = double>
using meV = units::isq::si::hep::energy<units::isq::si::hep::meV, Rep>;
template<Representation Rep = double> using eV = units::isq::si::hep::energy<units::isq::si::hep::eV, Rep>;
template<Representation Rep = double>
using eV = units::isq::si::hep::energy<units::isq::si::hep::eV, Rep>;
template<Representation Rep = double> using keV = units::isq::si::hep::energy<units::isq::si::hep::keV, Rep>;
template<Representation Rep = double> using MeV = units::isq::si::hep::energy<units::isq::si::hep::MeV, Rep>;
template<Representation Rep = double> using GeV = units::isq::si::hep::energy<units::isq::si::hep::GeV, Rep>;
template<Representation Rep = double> using TeV = units::isq::si::hep::energy<units::isq::si::hep::TeV, Rep>;
template<Representation Rep = double> using PeV = units::isq::si::hep::energy<units::isq::si::hep::PeV, Rep>;
template<Representation Rep = double> using EeV = units::isq::si::hep::energy<units::isq::si::hep::EeV, Rep>;
template<Representation Rep = double> using ZeV = units::isq::si::hep::energy<units::isq::si::hep::ZeV, Rep>;
template<Representation Rep = double> using YeV = units::isq::si::hep::energy<units::isq::si::hep::YeV, Rep>;
template<Representation Rep = double>
using keV = units::isq::si::hep::energy<units::isq::si::hep::keV, Rep>;
template<Representation Rep = double>
using MeV = units::isq::si::hep::energy<units::isq::si::hep::MeV, Rep>;
template<Representation Rep = double>
using GeV = units::isq::si::hep::energy<units::isq::si::hep::GeV, Rep>;
template<Representation Rep = double>
using TeV = units::isq::si::hep::energy<units::isq::si::hep::TeV, Rep>;
template<Representation Rep = double>
using PeV = units::isq::si::hep::energy<units::isq::si::hep::PeV, Rep>;
template<Representation Rep = double>
using EeV = units::isq::si::hep::energy<units::isq::si::hep::EeV, Rep>;
template<Representation Rep = double>
using ZeV = units::isq::si::hep::energy<units::isq::si::hep::ZeV, Rep>;
template<Representation Rep = double>
using YeV = units::isq::si::hep::energy<units::isq::si::hep::YeV, Rep>;
} // namespace units::aliases::isq::si::hep::inline energy
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -34,22 +34,29 @@
namespace units::isq::si::hep {
struct eV_per_c2 : named_scaled_unit<eV_per_c2, basic_symbol_text{"eV/c²", "eV/c^2"}, prefix, ratio(1'7826'619'216'279, 1'000'000'000'000, -35), kilogram> {};
struct eV_per_c2 :
named_scaled_unit<eV_per_c2, basic_symbol_text{"eV/c²", "eV/c^2"}, prefix,
ratio(1'7826'619'216'279, 1'000'000'000'000, -35), kilogram> {};
struct feV_per_c2 : prefixed_unit<feV_per_c2, femto, eV_per_c2> {};
struct peV_per_c2 : prefixed_unit<peV_per_c2, pico, eV_per_c2> {};
struct neV_per_c2 : prefixed_unit<neV_per_c2, nano, eV_per_c2> {};
struct ueV_per_c2 : prefixed_unit<ueV_per_c2, micro, eV_per_c2> {};
struct meV_per_c2 : prefixed_unit<meV_per_c2, milli, eV_per_c2> {}; // approximate mass of an electron/positron (0.511 MeV/c2)
struct meV_per_c2 :
prefixed_unit<meV_per_c2, milli, eV_per_c2> {}; // approximate mass of an electron/positron (0.511 MeV/c2)
struct keV_per_c2 : prefixed_unit<keV_per_c2, kilo, eV_per_c2> {};
struct MeV_per_c2 : prefixed_unit<MeV_per_c2, mega, eV_per_c2> {};
struct GeV_per_c2 : prefixed_unit<GeV_per_c2, giga, eV_per_c2> {}; // approximate mass of a proton (0.938 GeV/c2) or neutron
struct GeV_per_c2 :
prefixed_unit<GeV_per_c2, giga, eV_per_c2> {}; // approximate mass of a proton (0.938 GeV/c2) or neutron
struct TeV_per_c2 : prefixed_unit<TeV_per_c2, tera, eV_per_c2> {};
struct PeV_per_c2 : prefixed_unit<PeV_per_c2, peta, eV_per_c2> {};
struct EeV_per_c2 : prefixed_unit<EeV_per_c2, exa, eV_per_c2> {};
struct YeV_per_c2 : prefixed_unit<YeV_per_c2, yotta, eV_per_c2> {};
struct electron_mass : named_scaled_unit<eV_per_c2, "m_e", prefix, ratio(9'109'383'701'528, 1'000'000'000'000, -31), kilogram> {};
struct proton_mass : named_scaled_unit<eV_per_c2, "m_p", prefix, ratio(1'672'621'923'695, 1'000'000'000'000, -27), kilogram> {};
struct neutron_mass : named_scaled_unit<eV_per_c2, "m_n", prefix, ratio(1'674'927'498'049, 1'000'000'000'000, -27), kilogram> {};
struct electron_mass :
named_scaled_unit<eV_per_c2, "m_e", prefix, ratio(9'109'383'701'528, 1'000'000'000'000, -31), kilogram> {};
struct proton_mass :
named_scaled_unit<eV_per_c2, "m_p", prefix, ratio(1'672'621'923'695, 1'000'000'000'000, -27), kilogram> {};
struct neutron_mass :
named_scaled_unit<eV_per_c2, "m_n", prefix, ratio(1'674'927'498'049, 1'000'000'000'000, -27), kilogram> {};
struct dim_mass : isq::dim_mass<eV_per_c2> {};
@ -59,46 +66,110 @@ using mass = quantity<dim_mass, U, Rep>;
#ifndef UNITS_NO_LITERALS
inline namespace literals {
constexpr auto operator"" _q_feV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<feV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_feV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<feV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_feV_per_c2(long double l) { return mass<feV_per_c2, long double>(l); }
constexpr auto operator"" _q_peV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<peV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_peV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<peV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_peV_per_c2(long double l) { return mass<peV_per_c2, long double>(l); }
constexpr auto operator"" _q_neV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<neV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_neV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<neV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_neV_per_c2(long double l) { return mass<neV_per_c2, long double>(l); }
constexpr auto operator"" _q_ueV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<ueV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ueV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<ueV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ueV_per_c2(long double l) { return mass<ueV_per_c2, long double>(l); }
constexpr auto operator"" _q_meV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<meV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_meV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<meV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_meV_per_c2(long double l) { return mass<meV_per_c2, long double>(l); }
// eV_per_c2
constexpr auto operator"" _q_eV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<eV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_eV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<eV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_eV_per_c2(long double l) { return mass<eV_per_c2, long double>(l); }
constexpr auto operator"" _q_keV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<keV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_keV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<keV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_keV_per_c2(long double l) { return mass<keV_per_c2, long double>(l); }
constexpr auto operator"" _q_MeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<MeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<MeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MeV_per_c2(long double l) { return mass<MeV_per_c2, long double>(l); }
constexpr auto operator"" _q_GeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<GeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<GeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GeV_per_c2(long double l) { return mass<GeV_per_c2, long double>(l); }
constexpr auto operator"" _q_TeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<TeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<TeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TeV_per_c2(long double l) { return mass<TeV_per_c2, long double>(l); }
constexpr auto operator"" _q_PeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<PeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<PeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PeV_per_c2(long double l) { return mass<PeV_per_c2, long double>(l); }
constexpr auto operator"" _q_EeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<EeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<EeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EeV_per_c2(long double l) { return mass<EeV_per_c2, long double>(l); }
constexpr auto operator"" _q_YeV_per_c2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<YeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YeV_per_c2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<YeV_per_c2, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YeV_per_c2(long double l) { return mass<YeV_per_c2, long double>(l); }
// special HEP masses
constexpr auto operator"" _q_electron_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<electron_mass, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_electron_mass(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<electron_mass, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_electron_mass(long double l) { return mass<electron_mass, long double>(l); }
constexpr auto operator"" _q_proton_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<proton_mass, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_proton_mass(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<proton_mass, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_proton_mass(long double l) { return mass<proton_mass, long double>(l); }
constexpr auto operator"" _q_neutron_mass(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return mass<neutron_mass, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_neutron_mass(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return mass<neutron_mass, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_neutron_mass(long double l) { return mass<neutron_mass, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -114,7 +185,7 @@ using namespace mass_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::hep
@ -122,8 +193,9 @@ using namespace mass_references;
namespace units::aliases::isq::si::hep::inline mass {
template<Representation Rep = double> using eV_per_c2g = units::isq::si::hep::mass<units::isq::si::hep::eV_per_c2, Rep>;
template<Representation Rep = double>
using eV_per_c2g = units::isq::si::hep::mass<units::isq::si::hep::eV_per_c2, Rep>;
} // namespace units::aliases::isq::si::hep::inline mass
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -35,7 +35,9 @@
namespace units::isq::si::hep {
struct eV_per_c : named_scaled_unit<eV_per_c, "eV/c", prefix, ratio(5'344'285'992'678, 1'000'000'000'000, -35), ::units::isq::si::kilogram_metre_per_second> {};
struct eV_per_c :
named_scaled_unit<eV_per_c, "eV/c", prefix, ratio(5'344'285'992'678, 1'000'000'000'000, -35),
::units::isq::si::kilogram_metre_per_second> {};
struct feV_per_c : prefixed_unit<feV_per_c, femto, eV_per_c> {};
struct peV_per_c : prefixed_unit<peV_per_c, pico, eV_per_c> {};
struct neV_per_c : prefixed_unit<neV_per_c, nano, eV_per_c> {};
@ -58,48 +60,101 @@ using momentum = quantity<dim_momentum, U, Rep>;
inline namespace literals {
constexpr auto operator"" _q_feV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<feV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_feV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<feV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_feV_per_c(long double l) { return momentum<feV_per_c, long double>(l); }
constexpr auto operator"" _q_peV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<peV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_peV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<peV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_peV_per_c(long double l) { return momentum<peV_per_c, long double>(l); }
constexpr auto operator"" _q_neV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<neV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_neV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<neV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_neV_per_c(long double l) { return momentum<neV_per_c, long double>(l); }
constexpr auto operator"" _q_ueV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<ueV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ueV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<ueV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ueV_per_c(long double l) { return momentum<ueV_per_c, long double>(l); }
constexpr auto operator"" _q_meV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<meV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_meV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<meV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_meV_per_c(long double l) { return momentum<meV_per_c, long double>(l); }
// eV_per_c
constexpr auto operator"" _q_eV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<eV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_eV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<eV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_eV_per_c(long double l) { return momentum<eV_per_c, long double>(l); }
constexpr auto operator"" _q_keV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<keV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_keV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<keV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_keV_per_c(long double l) { return momentum<keV_per_c, long double>(l); }
constexpr auto operator"" _q_MeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<MeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_MeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<MeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_MeV_per_c(long double l) { return momentum<MeV_per_c, long double>(l); }
constexpr auto operator"" _q_GeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<GeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_GeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<GeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_GeV_per_c(long double l) { return momentum<GeV_per_c, long double>(l); }
constexpr auto operator"" _q_TeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<TeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_TeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<TeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_TeV_per_c(long double l) { return momentum<TeV_per_c, long double>(l); }
constexpr auto operator"" _q_PeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<PeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_PeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<PeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_PeV_per_c(long double l) { return momentum<PeV_per_c, long double>(l); }
constexpr auto operator"" _q_EeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<EeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_EeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<EeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_EeV_per_c(long double l) { return momentum<EeV_per_c, long double>(l); }
constexpr auto operator"" _q_YeV_per_c(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return momentum<YeV_per_c, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_YeV_per_c(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return momentum<YeV_per_c, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_YeV_per_c(long double l) { return momentum<YeV_per_c, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si
} // namespace units::isq::si::hep
#ifndef UNITS_NO_ALIASES
namespace units::aliases::isq::si::inline momentum {
template<Representation Rep = double> using eV_per_c = units::isq::si::hep::momentum<units::isq::si::hep::eV_per_c, Rep>;
template<Representation Rep = double>
using eV_per_c = units::isq::si::hep::momentum<units::isq::si::hep::eV_per_c, Rep>;
} // namespace units::aliases::isq::si::inline momentum
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -49,20 +49,32 @@ struct angstrom : named_scaled_unit<angstrom, "angstrom", no_prefix, ratio(1, 1,
inline namespace literals {
// ly
constexpr auto operator"" _q_ly(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<light_year, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ly(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<light_year, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ly(long double l) { return si::length<light_year, long double>(l); }
// pc
constexpr auto operator"" _q_pc(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<parsec, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pc(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<parsec, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pc(long double l) { return si::length<parsec, long double>(l); }
// angstrom
constexpr auto operator"" _q_angstrom(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<angstrom, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_angstrom(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<angstrom, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_angstrom(long double l) { return si::length<angstrom, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -80,7 +92,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::iau
@ -88,10 +100,13 @@ using namespace length_references;
namespace units::aliases::isq::si::iau::inline length {
template<Representation Rep = double> using ly = units::isq::si::length<units::isq::si::iau::light_year, Rep>;
template<Representation Rep = double> using pc = units::isq::si::length<units::isq::si::iau::parsec, Rep>;
template<Representation Rep = double> using angstrom = units::isq::si::length<units::isq::si::iau::angstrom, Rep>;
template<Representation Rep = double>
using ly = units::isq::si::length<units::isq::si::iau::light_year, Rep>;
template<Representation Rep = double>
using pc = units::isq::si::length<units::isq::si::iau::parsec, Rep>;
template<Representation Rep = double>
using angstrom = units::isq::si::length<units::isq::si::iau::angstrom, Rep>;
} // namespace units::aliases::isq::si::iau
} // namespace units::aliases::isq::si::iau::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -45,16 +45,24 @@ struct rod : named_scaled_unit<rod, "rd", no_prefix, ratio(1, 4), chain> {};
inline namespace literals {
// ch
constexpr auto operator"" _q_ch(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<chain, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ch(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<chain, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ch(long double l) { return si::length<chain, long double>(l); }
// rd
constexpr auto operator"" _q_rd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<rod, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_rd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<rod, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_rd(long double l) { return si::length<rod, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -71,7 +79,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::imperial
@ -79,9 +87,11 @@ using namespace length_references;
namespace units::aliases::isq::si::imperial::inline length {
template<Representation Rep = double> using ch = units::isq::si::length<units::isq::si::imperial::chain, Rep>;
template<Representation Rep = double> using rd = units::isq::si::length<units::isq::si::imperial::rod, Rep>;
template<Representation Rep = double>
using ch = units::isq::si::length<units::isq::si::imperial::chain, Rep>;
template<Representation Rep = double>
using rd = units::isq::si::length<units::isq::si::imperial::rod, Rep>;
} // namespace units::aliases::isq::si::imperial::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -71,40 +71,72 @@ using mil = thou;
inline namespace literals {
// yd
constexpr auto operator"" _q_yd(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<yard, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_yd(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<yard, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_yd(long double l) { return si::length<yard, long double>(l); }
// ft
constexpr auto operator"" _q_ft(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft(long double l) { return si::length<foot, long double>(l); }
// fathom
constexpr auto operator"" _q_fathom(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<fathom, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fathom(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<fathom, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fathom(long double l) { return si::length<fathom, long double>(l); }
// in
constexpr auto operator"" _q_in(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<inch, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_in(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<inch, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_in(long double l) { return si::length<inch, long double>(l); }
// mi
constexpr auto operator"" _q_mi(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<mile, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mi(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<mile, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mi(long double l) { return si::length<mile, long double>(l); }
// mi_naut
constexpr auto operator"" _q_naut_mi(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<nautical_mile, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_naut_mi(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<nautical_mile, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_naut_mi(long double l) { return si::length<nautical_mile, long double>(l); }
// thou
constexpr auto operator"" _q_thou(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<thou, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_thou(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<thou, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_thou(long double l) { return si::length<thou, long double>(l); }
// mil
constexpr auto operator"" _q_mil(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<mil, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mil(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<mil, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mil(long double l) { return si::length<mil, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -127,7 +159,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::international
@ -135,15 +167,23 @@ using namespace length_references;
namespace units::aliases::isq::si::international::inline length {
template<Representation Rep = double> using yd = units::isq::si::length<units::isq::si::international::yard, Rep>;
template<Representation Rep = double> using ft = units::isq::si::length<units::isq::si::international::foot, Rep>;
template<Representation Rep = double> using fathom = units::isq::si::length<units::isq::si::international::fathom, Rep>;
template<Representation Rep = double> using in = units::isq::si::length<units::isq::si::international::inch, Rep>;
template<Representation Rep = double> using mi = units::isq::si::length<units::isq::si::international::mile, Rep>;
template<Representation Rep = double> using mi_naut = units::isq::si::length<units::isq::si::international::nautical_mile, Rep>;
template<Representation Rep = double> using thou = units::isq::si::length<units::isq::si::international::thou, Rep>;
template<Representation Rep = double> using mil = units::isq::si::length<units::isq::si::international::mil, Rep>;
template<Representation Rep = double>
using yd = units::isq::si::length<units::isq::si::international::yard, Rep>;
template<Representation Rep = double>
using ft = units::isq::si::length<units::isq::si::international::foot, Rep>;
template<Representation Rep = double>
using fathom = units::isq::si::length<units::isq::si::international::fathom, Rep>;
template<Representation Rep = double>
using in = units::isq::si::length<units::isq::si::international::inch, Rep>;
template<Representation Rep = double>
using mi = units::isq::si::length<units::isq::si::international::mile, Rep>;
template<Representation Rep = double>
using mi_naut = units::isq::si::length<units::isq::si::international::nautical_mile, Rep>;
template<Representation Rep = double>
using thou = units::isq::si::length<units::isq::si::international::thou, Rep>;
template<Representation Rep = double>
using mil = units::isq::si::length<units::isq::si::international::mil, Rep>;
} // namespace units::aliases::isq::si::international::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -41,12 +41,16 @@ struct mile_per_hour : derived_unit<mile_per_hour, si::dim_speed, si::internatio
inline namespace literals {
// mi/h
constexpr auto operator"" _q_mi_per_h(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::speed<mile_per_hour, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mi_per_h(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::speed<mile_per_hour, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mi_per_h(long double l) { return si::speed<mile_per_hour, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si::international
@ -54,8 +58,9 @@ constexpr auto operator"" _q_mi_per_h(long double l) { return si::speed<mile_per
namespace units::aliases::isq::si::international::inline speed {
template<Representation Rep = double> using mi_per_h = units::isq::si::speed<units::isq::si::international::mile_per_hour, Rep>;
template<Representation Rep = double>
using mi_per_h = units::isq::si::speed<units::isq::si::international::mile_per_hour, Rep>;
} // namespace units::aliases::isq::si::international::inline speed
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -42,12 +42,16 @@ struct cubic_foot : derived_unit<cubic_foot, si::dim_volume, si::international::
inline namespace literals {
// ft3
constexpr auto operator"" _q_ft3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::volume<cubic_foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::volume<cubic_foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft3(long double l) { return si::volume<cubic_foot, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -63,7 +67,7 @@ using namespace volume_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::international
@ -71,8 +75,9 @@ using namespace volume_references;
namespace units::aliases::isq::si::international::inline volume {
template<Representation Rep = double> using ft3 = units::isq::si::volume<units::isq::si::international::cubic_foot, Rep>;
template<Representation Rep = double>
using ft3 = units::isq::si::volume<units::isq::si::international::cubic_foot, Rep>;
} // namespace units::aliases::isq::si::international::inline volume
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -35,7 +35,8 @@
namespace units::isq::si::typographic {
// TODO Conflicts with (https://en.wikipedia.org/wiki/Pica_(typography)), verify correctness of below conversion factors and provide hyperlinks to definitions
// TODO Conflicts with (https://en.wikipedia.org/wiki/Pica_(typography)), verify correctness of below conversion factors
// and provide hyperlinks to definitions
struct pica_comp : named_scaled_unit<pica_comp, "pica(comp)", no_prefix, ratio(4233333, 1000000, -3), si::metre> {};
struct pica_prn : named_scaled_unit<pica_prn, "pica(prn)", no_prefix, ratio(2108759, 500000, -3), si::metre> {};
struct point_comp : named_scaled_unit<point_comp, "point(comp)", no_prefix, ratio(1763889, 500000, -4), si::metre> {};
@ -46,24 +47,40 @@ struct point_prn : named_scaled_unit<point_prn, "point(prn)", no_prefix, ratio(1
inline namespace literals {
// pica comp
constexpr auto operator"" _q_pica_comp(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<pica_comp, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pica_comp(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<pica_comp, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pica_comp(long double l) { return si::length<pica_comp, long double>(l); }
// pica prn
constexpr auto operator"" _q_pica_prn(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<pica_prn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pica_prn(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<pica_prn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pica_prn(long double l) { return si::length<pica_prn, long double>(l); }
// point comp
constexpr auto operator"" _q_point_comp(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<point_comp, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_point_comp(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<point_comp, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_point_comp(long double l) { return si::length<point_comp, long double>(l); }
// point prn
constexpr auto operator"" _q_point_prn(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<point_prn, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_point_prn(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<point_prn, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_point_prn(long double l) { return si::length<point_prn, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -82,7 +99,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::typographic
@ -90,11 +107,15 @@ using namespace length_references;
namespace units::aliases::isq::si::typographic::inline length {
template<Representation Rep = double> using pica_comp = units::isq::si::length<units::isq::si::typographic::pica_comp, Rep>;
template<Representation Rep = double> using pica_prn = units::isq::si::length<units::isq::si::typographic::pica_prn, Rep>;
template<Representation Rep = double> using point_comp = units::isq::si::length<units::isq::si::typographic::point_comp, Rep>;
template<Representation Rep = double> using point_prn = units::isq::si::length<units::isq::si::typographic::point_prn, Rep>;
template<Representation Rep = double>
using pica_comp = units::isq::si::length<units::isq::si::typographic::pica_comp, Rep>;
template<Representation Rep = double>
using pica_prn = units::isq::si::length<units::isq::si::typographic::pica_prn, Rep>;
template<Representation Rep = double>
using point_comp = units::isq::si::length<units::isq::si::typographic::point_comp, Rep>;
template<Representation Rep = double>
using point_prn = units::isq::si::length<units::isq::si::typographic::point_prn, Rep>;
} // namespace units::aliases::isq::si::typographic::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -50,20 +50,35 @@ struct mile : named_scaled_unit<mile, "mi(us)", no_prefix, ratio(5280), foot> {}
inline namespace literals {
// ft
constexpr auto operator"" _q_ft_us(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<units::isq::si::uscs::foot, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ft_us(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<units::isq::si::uscs::foot, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ft_us(long double l) { return si::length<units::isq::si::uscs::foot, long double>(l); }
// fathom
constexpr auto operator"" _q_fathom_us(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<units::isq::si::uscs::fathom, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fathom_us(long double l) { return si::length<units::isq::si::uscs::fathom, long double>(l); }
constexpr auto operator"" _q_fathom_us(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<units::isq::si::uscs::fathom, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fathom_us(long double l)
{
return si::length<units::isq::si::uscs::fathom, long double>(l);
}
// mi
constexpr auto operator"" _q_mi_us(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return si::length<units::isq::si::uscs::mile, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mi_us(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return si::length<units::isq::si::uscs::mile, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mi_us(long double l) { return si::length<units::isq::si::uscs::mile, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -81,7 +96,7 @@ using namespace length_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si::uscs
@ -89,10 +104,13 @@ using namespace length_references;
namespace units::aliases::isq::si::uscs::inline length {
template<Representation Rep = double> using ft = units::isq::si::length<units::isq::si::uscs::foot, Rep>;
template<Representation Rep = double> using fathom = units::isq::si::length<units::isq::si::uscs::fathom, Rep>;
template<Representation Rep = double> using mi = units::isq::si::length<units::isq::si::uscs::mile, Rep>;
template<Representation Rep = double>
using ft = units::isq::si::length<units::isq::si::uscs::foot, Rep>;
template<Representation Rep = double>
using fathom = units::isq::si::length<units::isq::si::uscs::fathom, Rep>;
template<Representation Rep = double>
using mi = units::isq::si::length<units::isq::si::uscs::mile, Rep>;
} // namespace units::aliases::isq::si::uscs::inline length
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -30,8 +30,8 @@
// IWYU pragma: end_exports
#include <units/isq/si/amount_of_substance.h>
#include <units/isq/si/time.h>
#include <units/isq/si/prefixes.h>
#include <units/isq/si/time.h>
#include <units/unit.h>
namespace units::isq::si {
@ -60,7 +60,8 @@ struct yottakatal : prefixed_unit<yottakatal, yotta, katal> {};
struct enzyme_unit : named_scaled_unit<enzyme_unit, "U", prefix, ratio(1, 60, -6), katal> {};
struct dim_catalytic_activity : isq::dim_catalytic_activity<dim_catalytic_activity, katal, dim_time, dim_amount_of_substance> {};
struct dim_catalytic_activity :
isq::dim_catalytic_activity<dim_catalytic_activity, katal, dim_time, dim_amount_of_substance> {};
template<UnitOf<dim_catalytic_activity> U, Representation Rep = double>
using catalytic_activity = quantity<dim_catalytic_activity, U, Rep>;
@ -70,96 +71,184 @@ using catalytic_activity = quantity<dim_catalytic_activity, U, Rep>;
inline namespace literals {
// kat
constexpr auto operator"" _q_kat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<katal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<katal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kat(long double l) { return catalytic_activity<katal, long double>(l); }
// ykat
constexpr auto operator"" _q_ykat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<yoctokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ykat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<yoctokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ykat(long double l) { return catalytic_activity<yoctokatal, long double>(l); }
// zkat
constexpr auto operator"" _q_zkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<zeptokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_zkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<zeptokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_zkat(long double l) { return catalytic_activity<zeptokatal, long double>(l); }
// akat
constexpr auto operator"" _q_akat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<attokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_akat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<attokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_akat(long double l) { return catalytic_activity<attokatal, long double>(l); }
// fkat
constexpr auto operator"" _q_fkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<femtokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_fkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<femtokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_fkat(long double l) { return catalytic_activity<femtokatal, long double>(l); }
// pkat
constexpr auto operator"" _q_pkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<picokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_pkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<picokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_pkat(long double l) { return catalytic_activity<picokatal, long double>(l); }
// nkat
constexpr auto operator"" _q_nkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<nanokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_nkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<nanokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_nkat(long double l) { return catalytic_activity<nanokatal, long double>(l); }
// ukat
constexpr auto operator"" _q_ukat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<microkatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ukat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<microkatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ukat(long double l) { return catalytic_activity<microkatal, long double>(l); }
// mkat
constexpr auto operator"" _q_mkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<millikatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_mkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<millikatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_mkat(long double l) { return catalytic_activity<millikatal, long double>(l); }
// ckat
constexpr auto operator"" _q_ckat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<centikatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_ckat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<centikatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_ckat(long double l) { return catalytic_activity<centikatal, long double>(l); }
// dkat
constexpr auto operator"" _q_dkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<decikatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<decikatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dkat(long double l) { return catalytic_activity<decikatal, long double>(l); }
// dakat
constexpr auto operator"" _q_dakat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<decakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_dakat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<decakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_dakat(long double l) { return catalytic_activity<decakatal, long double>(l); }
// hkat
constexpr auto operator"" _q_hkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<hectokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_hkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<hectokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_hkat(long double l) { return catalytic_activity<hectokatal, long double>(l); }
// kkat
constexpr auto operator"" _q_kkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<kilokatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_kkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<kilokatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_kkat(long double l) { return catalytic_activity<kilokatal, long double>(l); }
// Mkat
constexpr auto operator"" _q_Mkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<megakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Mkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<megakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Mkat(long double l) { return catalytic_activity<megakatal, long double>(l); }
// Gkat
constexpr auto operator"" _q_Gkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<gigakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Gkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<gigakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Gkat(long double l) { return catalytic_activity<gigakatal, long double>(l); }
// Tkat
constexpr auto operator"" _q_Tkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<terakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Tkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<terakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Tkat(long double l) { return catalytic_activity<terakatal, long double>(l); }
// Pkat
constexpr auto operator"" _q_Pkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<petakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Pkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<petakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Pkat(long double l) { return catalytic_activity<petakatal, long double>(l); }
// Ekat
constexpr auto operator"" _q_Ekat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<exakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ekat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<exakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ekat(long double l) { return catalytic_activity<exakatal, long double>(l); }
// Zkat
constexpr auto operator"" _q_Zkat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<zettakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Zkat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<zettakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Zkat(long double l) { return catalytic_activity<zettakatal, long double>(l); }
// Ykat
constexpr auto operator"" _q_Ykat(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<yottakatal, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_Ykat(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<yottakatal, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_Ykat(long double l) { return catalytic_activity<yottakatal, long double>(l); }
// U
constexpr auto operator"" _q_U(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return catalytic_activity<enzyme_unit, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_U(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return catalytic_activity<enzyme_unit, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_U(long double l) { return catalytic_activity<enzyme_unit, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
#ifndef UNITS_NO_REFERENCES
@ -196,7 +285,7 @@ using namespace catalytic_activity_references;
} // namespace references
#endif // UNITS_NO_REFERENCES
#endif // UNITS_NO_REFERENCES
} // namespace units::isq::si
@ -204,29 +293,51 @@ using namespace catalytic_activity_references;
namespace units::aliases::isq::si::inline catalytic_activity {
template<Representation Rep = double> using kat = units::isq::si::catalytic_activity<units::isq::si::katal, Rep>;
template<Representation Rep = double> using ykat = units::isq::si::catalytic_activity<units::isq::si::yoctokatal, Rep>;
template<Representation Rep = double> using zkat = units::isq::si::catalytic_activity<units::isq::si::zeptokatal, Rep>;
template<Representation Rep = double> using akat = units::isq::si::catalytic_activity<units::isq::si::attokatal, Rep>;
template<Representation Rep = double> using fkat = units::isq::si::catalytic_activity<units::isq::si::femtokatal, Rep>;
template<Representation Rep = double> using pkat = units::isq::si::catalytic_activity<units::isq::si::picokatal, Rep>;
template<Representation Rep = double> using nkat = units::isq::si::catalytic_activity<units::isq::si::nanokatal, Rep>;
template<Representation Rep = double> using ukat = units::isq::si::catalytic_activity<units::isq::si::microkatal, Rep>;
template<Representation Rep = double> using mkat = units::isq::si::catalytic_activity<units::isq::si::millikatal, Rep>;
template<Representation Rep = double> using ckat = units::isq::si::catalytic_activity<units::isq::si::centikatal, Rep>;
template<Representation Rep = double> using dkat = units::isq::si::catalytic_activity<units::isq::si::decikatal, Rep>;
template<Representation Rep = double> using dakat = units::isq::si::catalytic_activity<units::isq::si::decakatal, Rep>;
template<Representation Rep = double> using hkat = units::isq::si::catalytic_activity<units::isq::si::hectokatal, Rep>;
template<Representation Rep = double> using kkat = units::isq::si::catalytic_activity<units::isq::si::kilokatal, Rep>;
template<Representation Rep = double> using Mkat = units::isq::si::catalytic_activity<units::isq::si::megakatal, Rep>;
template<Representation Rep = double> using Gkat = units::isq::si::catalytic_activity<units::isq::si::gigakatal, Rep>;
template<Representation Rep = double> using Tkat = units::isq::si::catalytic_activity<units::isq::si::terakatal, Rep>;
template<Representation Rep = double> using Pkat = units::isq::si::catalytic_activity<units::isq::si::petakatal, Rep>;
template<Representation Rep = double> using Ekat = units::isq::si::catalytic_activity<units::isq::si::exakatal, Rep>;
template<Representation Rep = double> using Zkat = units::isq::si::catalytic_activity<units::isq::si::zettakatal, Rep>;
template<Representation Rep = double> using Ykat = units::isq::si::catalytic_activity<units::isq::si::yottakatal, Rep>;
template<Representation Rep = double> using U = units::isq::si::catalytic_activity<units::isq::si::enzyme_unit, Rep>;
template<Representation Rep = double>
using kat = units::isq::si::catalytic_activity<units::isq::si::katal, Rep>;
template<Representation Rep = double>
using ykat = units::isq::si::catalytic_activity<units::isq::si::yoctokatal, Rep>;
template<Representation Rep = double>
using zkat = units::isq::si::catalytic_activity<units::isq::si::zeptokatal, Rep>;
template<Representation Rep = double>
using akat = units::isq::si::catalytic_activity<units::isq::si::attokatal, Rep>;
template<Representation Rep = double>
using fkat = units::isq::si::catalytic_activity<units::isq::si::femtokatal, Rep>;
template<Representation Rep = double>
using pkat = units::isq::si::catalytic_activity<units::isq::si::picokatal, Rep>;
template<Representation Rep = double>
using nkat = units::isq::si::catalytic_activity<units::isq::si::nanokatal, Rep>;
template<Representation Rep = double>
using ukat = units::isq::si::catalytic_activity<units::isq::si::microkatal, Rep>;
template<Representation Rep = double>
using mkat = units::isq::si::catalytic_activity<units::isq::si::millikatal, Rep>;
template<Representation Rep = double>
using ckat = units::isq::si::catalytic_activity<units::isq::si::centikatal, Rep>;
template<Representation Rep = double>
using dkat = units::isq::si::catalytic_activity<units::isq::si::decikatal, Rep>;
template<Representation Rep = double>
using dakat = units::isq::si::catalytic_activity<units::isq::si::decakatal, Rep>;
template<Representation Rep = double>
using hkat = units::isq::si::catalytic_activity<units::isq::si::hectokatal, Rep>;
template<Representation Rep = double>
using kkat = units::isq::si::catalytic_activity<units::isq::si::kilokatal, Rep>;
template<Representation Rep = double>
using Mkat = units::isq::si::catalytic_activity<units::isq::si::megakatal, Rep>;
template<Representation Rep = double>
using Gkat = units::isq::si::catalytic_activity<units::isq::si::gigakatal, Rep>;
template<Representation Rep = double>
using Tkat = units::isq::si::catalytic_activity<units::isq::si::terakatal, Rep>;
template<Representation Rep = double>
using Pkat = units::isq::si::catalytic_activity<units::isq::si::petakatal, Rep>;
template<Representation Rep = double>
using Ekat = units::isq::si::catalytic_activity<units::isq::si::exakatal, Rep>;
template<Representation Rep = double>
using Zkat = units::isq::si::catalytic_activity<units::isq::si::zettakatal, Rep>;
template<Representation Rep = double>
using Ykat = units::isq::si::catalytic_activity<units::isq::si::yottakatal, Rep>;
template<Representation Rep = double>
using U = units::isq::si::catalytic_activity<units::isq::si::enzyme_unit, Rep>;
} // namespace units::aliases::isq::si::inline catalytic_activity
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -38,8 +38,11 @@ namespace units::isq::si {
struct coulomb_per_metre_cub : unit<coulomb_per_metre_cub> {};
struct coulomb_per_metre_sq : unit<coulomb_per_metre_sq> {};
struct dim_charge_density : isq::dim_charge_density<dim_charge_density, coulomb_per_metre_cub, dim_electric_charge, dim_length> {};
struct dim_surface_charge_density : isq::dim_surface_charge_density<dim_surface_charge_density, coulomb_per_metre_sq, dim_electric_charge, dim_length> {};
struct dim_charge_density :
isq::dim_charge_density<dim_charge_density, coulomb_per_metre_cub, dim_electric_charge, dim_length> {};
struct dim_surface_charge_density :
isq::dim_surface_charge_density<dim_surface_charge_density, coulomb_per_metre_sq, dim_electric_charge, dim_length> {
};
template<UnitOf<dim_charge_density> U, Representation Rep = double>
using charge_density = quantity<dim_charge_density, U, Rep>;
@ -52,16 +55,27 @@ using surface_charge_density = quantity<dim_surface_charge_density, U, Rep>;
inline namespace literals {
// C/m³
constexpr auto operator"" _q_C_per_m3(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return charge_density<coulomb_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_C_per_m3(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return charge_density<coulomb_per_metre_cub, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_C_per_m3(long double l) { return charge_density<coulomb_per_metre_cub, long double>(l); }
// C/m²
constexpr auto operator"" _q_C_per_m2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return surface_charge_density<coulomb_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_C_per_m2(long double l) { return surface_charge_density<coulomb_per_metre_sq, long double>(l); }
constexpr auto operator"" _q_C_per_m2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return surface_charge_density<coulomb_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_C_per_m2(long double l)
{
return surface_charge_density<coulomb_per_metre_sq, long double>(l);
}
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si
@ -69,9 +83,11 @@ constexpr auto operator"" _q_C_per_m2(long double l) { return surface_charge_den
namespace units::aliases::isq::si::inline charge_density {
template<Representation Rep = double> using C_per_m3 = units::isq::si::charge_density<units::isq::si::coulomb_per_metre_cub, Rep>;
template<Representation Rep = double> using C_per_m2 = units::isq::si::surface_charge_density<units::isq::si::coulomb_per_metre_sq, Rep>;
template<Representation Rep = double>
using C_per_m3 = units::isq::si::charge_density<units::isq::si::coulomb_per_metre_cub, Rep>;
template<Representation Rep = double>
using C_per_m2 = units::isq::si::surface_charge_density<units::isq::si::coulomb_per_metre_sq, Rep>;
} // namespace units::aliases::isq::si::inline charge_density
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

View File

@ -23,12 +23,12 @@
#pragma once
#include <units/isq/si/amount_of_substance.h>
#include <units/isq/si/thermodynamic_temperature.h>
#include <units/isq/si/electric_charge.h>
#include <units/isq/si/energy.h>
#include <units/isq/si/frequency.h>
#include <units/isq/si/power.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/thermodynamic_temperature.h>
namespace units::isq::si::si2019 {

View File

@ -37,7 +37,8 @@ namespace units::isq::si {
struct ampere_per_metre_sq : unit<ampere_per_metre_sq> {};
struct dim_current_density : isq::dim_current_density<dim_current_density, ampere_per_metre_sq, dim_electric_current, dim_length> {};
struct dim_current_density :
isq::dim_current_density<dim_current_density, ampere_per_metre_sq, dim_electric_current, dim_length> {};
template<UnitOf<dim_current_density> U, Representation Rep = double>
using current_density = quantity<dim_current_density, U, Rep>;
@ -47,12 +48,16 @@ using current_density = quantity<dim_current_density, U, Rep>;
inline namespace literals {
// A / m²
constexpr auto operator"" _q_A_per_m2(unsigned long long l) { gsl_ExpectsAudit(std::in_range<std::int64_t>(l)); return current_density<ampere_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l)); }
constexpr auto operator"" _q_A_per_m2(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return current_density<ampere_per_metre_sq, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_A_per_m2(long double l) { return current_density<ampere_per_metre_sq, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
#endif // UNITS_NO_LITERALS
} // namespace units::isq::si
@ -60,8 +65,9 @@ constexpr auto operator"" _q_A_per_m2(long double l) { return current_density<am
namespace units::aliases::isq::si::inline current_density {
template<Representation Rep = double> using A_per_m2 = units::isq::si::current_density<units::isq::si::ampere_per_metre_sq, Rep>;
template<Representation Rep = double>
using A_per_m2 = units::isq::si::current_density<units::isq::si::ampere_per_metre_sq, Rep>;
} // namespace units::aliases::isq::si::inline current_density
#endif // UNITS_NO_ALIASES
#endif // UNITS_NO_ALIASES

Some files were not shown because too many files have changed in this diff Show More