mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-04 12:54:25 +02:00
quantity refactored and quantity_test enabled
This commit is contained in:
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <units/bits/fixed_string.h>
|
||||
#include <units/bits/unit_concept.h>
|
||||
#include <units/unit.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace units {
|
||||
@@ -46,7 +45,7 @@ namespace units {
|
||||
*/
|
||||
template<basic_fixed_string Name, Unit U>
|
||||
struct base_dimension {
|
||||
using base_type = base_dimension;
|
||||
using base_type_workaround = base_dimension; // TODO Replace with is_derived_from_instantiation when fixed
|
||||
static constexpr auto name = Name;
|
||||
using coherent_unit = U;
|
||||
};
|
||||
@@ -63,7 +62,7 @@ inline constexpr bool is_base_dimension<base_dimension<Name, Params...>> = true;
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
concept BaseDimension = detail::is_base_dimension<typename T::base_type>;
|
||||
concept BaseDimension = detail::is_base_dimension<typename T::base_type_workaround>;
|
||||
|
||||
// base_dimension_less
|
||||
// TODO Remove the below when https://bugs.llvm.org/show_bug.cgi?id=32208 is fixed
|
||||
|
@@ -1,115 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
|
||||
namespace units {
|
||||
|
||||
// treat_as_floating_point
|
||||
|
||||
template<typename Rep> // TODO Conceptify that
|
||||
inline constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;
|
||||
|
||||
// isnan
|
||||
namespace isnan_impl {
|
||||
|
||||
// non-ADL lookup block
|
||||
void isnan(); // undefined
|
||||
|
||||
template<typename>
|
||||
inline constexpr bool has_customization = false;
|
||||
|
||||
template<typename T>
|
||||
requires requires(const T& t) {
|
||||
{ isnan(t) } -> bool;
|
||||
}
|
||||
inline constexpr bool has_customization<T> = true;
|
||||
|
||||
struct fn {
|
||||
template<typename T>
|
||||
constexpr bool operator()(const T&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires treat_as_floating_point<T>
|
||||
constexpr bool operator()(const T& value) const
|
||||
{
|
||||
return std::isnan(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires treat_as_floating_point<T> && has_customization<T>
|
||||
constexpr bool operator()(const T& value) const
|
||||
{
|
||||
return isnan(value); // uses ADL
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline constexpr isnan_impl::fn isnan{};
|
||||
|
||||
// isfinite
|
||||
namespace isfinite_impl {
|
||||
|
||||
// non-ADL lookup block
|
||||
void isfinite(); // undefined
|
||||
|
||||
template<typename>
|
||||
inline constexpr bool has_customization = false;
|
||||
|
||||
template<typename T>
|
||||
requires requires(const T& t) {
|
||||
{ isfinite(t) } -> bool;
|
||||
}
|
||||
inline constexpr bool has_customization<T> = true;
|
||||
|
||||
struct fn {
|
||||
template<typename T>
|
||||
constexpr bool operator()(const T&) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires treat_as_floating_point<T>
|
||||
constexpr bool operator()(const T& value) const
|
||||
{
|
||||
return std::isfinite(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
requires treat_as_floating_point<T> && has_customization<T>
|
||||
constexpr bool operator()(const T& value) const
|
||||
{
|
||||
return isfinite(value); // uses ADL
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline constexpr isfinite_impl::fn isfinite{};
|
||||
|
||||
}
|
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <units/bits/hacks.h>
|
||||
#include <units/bits/numeric_concepts.h>
|
||||
#include <units/bits/customization_points.h>
|
||||
#include <units/customization_points.h>
|
||||
#include <units/ratio.h>
|
||||
|
||||
namespace units {
|
115
src/include/units/customization_points.h
Normal file
115
src/include/units/customization_points.h
Normal file
@@ -0,0 +1,115 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <cmath>
|
||||
|
||||
namespace units {
|
||||
|
||||
// treat_as_floating_point
|
||||
|
||||
template<typename Rep> // TODO Conceptify that
|
||||
inline constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;
|
||||
|
||||
// // isnan
|
||||
// namespace isnan_impl {
|
||||
|
||||
// // non-ADL lookup block
|
||||
// void isnan(); // undefined
|
||||
|
||||
// template<typename>
|
||||
// inline constexpr bool has_customization = false;
|
||||
|
||||
// template<typename T>
|
||||
// requires requires(const T& t) {
|
||||
// { isnan(t) } -> bool;
|
||||
// }
|
||||
// inline constexpr bool has_customization<T> = true;
|
||||
|
||||
// struct fn {
|
||||
// template<typename T>
|
||||
// constexpr bool operator()(const T&) const
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// template<typename T>
|
||||
// requires treat_as_floating_point<T>
|
||||
// constexpr bool operator()(const T& value) const
|
||||
// {
|
||||
// return std::isnan(value);
|
||||
// }
|
||||
|
||||
// template<typename T>
|
||||
// requires treat_as_floating_point<T> && has_customization<T>
|
||||
// constexpr bool operator()(const T& value) const
|
||||
// {
|
||||
// return isnan(value); // uses ADL
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// inline constexpr isnan_impl::fn isnan{};
|
||||
|
||||
// // isfinite
|
||||
// namespace isfinite_impl {
|
||||
|
||||
// // non-ADL lookup block
|
||||
// void isfinite(); // undefined
|
||||
|
||||
// template<typename>
|
||||
// inline constexpr bool has_customization = false;
|
||||
|
||||
// template<typename T>
|
||||
// requires requires(const T& t) {
|
||||
// { isfinite(t) } -> bool;
|
||||
// }
|
||||
// inline constexpr bool has_customization<T> = true;
|
||||
|
||||
// struct fn {
|
||||
// template<typename T>
|
||||
// constexpr bool operator()(const T&) const
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// template<typename T>
|
||||
// requires treat_as_floating_point<T>
|
||||
// constexpr bool operator()(const T& value) const
|
||||
// {
|
||||
// return std::isfinite(value);
|
||||
// }
|
||||
|
||||
// template<typename T>
|
||||
// requires treat_as_floating_point<T> && has_customization<T>
|
||||
// constexpr bool operator()(const T& value) const
|
||||
// {
|
||||
// return isfinite(value); // uses ADL
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// inline constexpr isfinite_impl::fn isfinite{};
|
||||
|
||||
}
|
@@ -277,10 +277,14 @@ struct dim_invert_impl<derived_dimension<Es...>> {
|
||||
using type = downcast<derived_dimension<exp_invert<Es>...>>;
|
||||
};
|
||||
|
||||
template<DerivedDimension D>
|
||||
struct dim_invert_impl<D> : dim_invert_impl<downcast_base_t<D>> {
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<Dimension D>
|
||||
using dim_invert = detail::dim_invert_impl<downcast_base_t<D>>::type;
|
||||
using dim_invert = detail::dim_invert_impl<D>::type;
|
||||
|
||||
// dimension_multiply
|
||||
namespace detail {
|
||||
@@ -377,7 +381,7 @@ struct dimension_pow_impl;
|
||||
|
||||
template<BaseDimension D, std::size_t N>
|
||||
struct dimension_pow_impl<D, N> {
|
||||
using type = derived_dimension<exp<D, N>>;
|
||||
using type = downcast<derived_dimension<exp<D, N>>>;
|
||||
};
|
||||
|
||||
template<BaseDimension D, std::size_t N>
|
||||
@@ -387,7 +391,7 @@ struct dimension_pow_impl<exp<D, 1, N>, N> {
|
||||
|
||||
template<DerivedDimension D, std::size_t N>
|
||||
struct dimension_pow_impl<D, N> {
|
||||
using type = dimension_pow_impl<typename D::base_type, N>;
|
||||
using type = dimension_pow_impl<downcast_base<D>, N>;
|
||||
};
|
||||
|
||||
template<typename... Es, std::size_t N>
|
||||
|
@@ -1,64 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/length.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct area : derived_dimension<area, exp<length, 2>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Area = QuantityOf<T, area>;
|
||||
|
||||
struct square_metre : coherent_derived_unit<square_metre, area> {};
|
||||
struct square_millimetre : deduced_derived_unit<square_millimetre, area, millimetre> {};
|
||||
struct square_centimetre : deduced_derived_unit<square_centimetre, area, centimetre> {};
|
||||
struct square_kilometre : deduced_derived_unit<square_kilometre, area, kilometre> {};
|
||||
struct square_foot : deduced_derived_unit<square_foot, area, foot> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// sq_m
|
||||
constexpr auto operator""sq_m(unsigned long long l) { return quantity<square_metre, std::int64_t>(l); }
|
||||
constexpr auto operator""sq_m(long double l) { return quantity<square_metre, long double>(l); }
|
||||
|
||||
// sq_mm
|
||||
constexpr auto operator""sq_mm(unsigned long long l) { return quantity<square_millimetre, std::int64_t>(l); }
|
||||
constexpr auto operator""sq_mm(long double l) { return quantity<square_millimetre, long double>(l); }
|
||||
|
||||
// sq_cm
|
||||
constexpr auto operator""sq_cm(unsigned long long l) { return quantity<square_centimetre, std::int64_t>(l); }
|
||||
constexpr auto operator""sq_cm(long double l) { return quantity<square_centimetre, long double>(l); }
|
||||
|
||||
// sq_km
|
||||
constexpr auto operator""sq_km(unsigned long long l) { return quantity<square_kilometre, std::int64_t>(l); }
|
||||
constexpr auto operator""sq_km(long double l) { return quantity<square_kilometre, long double>(l); }
|
||||
|
||||
// sq_ft
|
||||
constexpr auto operator""sq_ft(unsigned long long l) { return quantity<square_foot, std::int64_t>(l); }
|
||||
constexpr auto operator""sq_ft(long double l) { return quantity<square_foot, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units
|
@@ -1,71 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/si_base_dimensions.h>
|
||||
#include <units/dimensions/si_prefixes.h>
|
||||
#include <units/dimensions/time.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct frequency : derived_dimension<frequency, exp<time, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Frequency = QuantityOf<T, frequency>;
|
||||
|
||||
struct hertz : named_coherent_derived_unit<hertz, frequency, "Hz", si_prefix> {};
|
||||
struct millihertz : prefixed_derived_unit<millihertz, milli, hertz> {};
|
||||
struct kilohertz : prefixed_derived_unit<kilohertz, kilo, hertz> {};
|
||||
struct megahertz : prefixed_derived_unit<megahertz, mega, hertz> {};
|
||||
struct gigahertz : prefixed_derived_unit<gigahertz, giga, hertz> {};
|
||||
struct terahertz : prefixed_derived_unit<terahertz, tera, hertz> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// Hz
|
||||
constexpr auto operator""Hz(unsigned long long l) { return quantity<hertz, std::int64_t>(l); }
|
||||
constexpr auto operator""Hz(long double l) { return quantity<hertz, long double>(l); }
|
||||
|
||||
// mHz
|
||||
constexpr auto operator""mHz(unsigned long long l) { return quantity<millihertz, std::int64_t>(l); }
|
||||
constexpr auto operator""mHz(long double l) { return quantity<millihertz, long double>(l); }
|
||||
|
||||
// kHz
|
||||
constexpr auto operator""kHz(unsigned long long l) { return quantity<kilohertz, std::int64_t>(l); }
|
||||
constexpr auto operator""kHz(long double l) { return quantity<kilohertz, long double>(l); }
|
||||
|
||||
// MHz
|
||||
constexpr auto operator""MHz(unsigned long long l) { return quantity<megahertz, std::int64_t>(l); }
|
||||
constexpr auto operator""MHz(long double l) { return quantity<megahertz, long double>(l); }
|
||||
|
||||
// GHz
|
||||
constexpr auto operator""GHz(unsigned long long l) { return quantity<gigahertz, std::int64_t>(l); }
|
||||
constexpr auto operator""GHz(long double l) { return quantity<gigahertz, long double>(l); }
|
||||
|
||||
// THz
|
||||
constexpr auto operator""THz(unsigned long long l) { return quantity<terahertz, std::int64_t>(l); }
|
||||
constexpr auto operator""THz(long double l) { return quantity<terahertz, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units
|
@@ -1,88 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/si_base_dimensions.h>
|
||||
#include <units/dimensions/si_prefixes.h>
|
||||
#include <units/quantity.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct length : derived_dimension<length, exp<base_dim_length, 1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Length = QuantityOf<T, length>;
|
||||
|
||||
// SI units
|
||||
struct metre : named_coherent_derived_unit<metre, length, "m", si_prefix> {};
|
||||
struct millimetre : prefixed_derived_unit<millimetre, milli, metre> {};
|
||||
struct centimetre : prefixed_derived_unit<centimetre, centi, metre> {};
|
||||
struct kilometre : prefixed_derived_unit<kilometre, kilo, metre> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// m
|
||||
constexpr auto operator""m(unsigned long long l) { return quantity<metre, std::int64_t>(l); }
|
||||
constexpr auto operator""m(long double l) { return quantity<metre, long double>(l); }
|
||||
|
||||
// mm
|
||||
constexpr auto operator""mm(unsigned long long l) { return quantity<millimetre, std::int64_t>(l); }
|
||||
constexpr auto operator""mm(long double l) { return quantity<millimetre, long double>(l); }
|
||||
|
||||
// cm
|
||||
constexpr auto operator""cm(unsigned long long l) { return quantity<centimetre, std::int64_t>(l); }
|
||||
constexpr auto operator""cm(long double l) { return quantity<centimetre, long double>(l); }
|
||||
|
||||
// km
|
||||
constexpr auto operator""km(unsigned long long l) { return quantity<kilometre, std::int64_t>(l); }
|
||||
constexpr auto operator""km(long double l) { return quantity<kilometre, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
// US customary units
|
||||
struct yard : named_scaled_derived_unit<yard, length, "yd", ratio<9'144, 10'000>> {};
|
||||
struct foot : named_scaled_derived_unit<foot, length, "ft", ratio_divide<yard::ratio, ratio<3>>> {};
|
||||
struct inch : named_scaled_derived_unit<inch, length, "in", ratio_divide<foot::ratio, ratio<12>>> {};
|
||||
struct mile : named_scaled_derived_unit<mile, length, "mi", ratio_multiply<ratio<1'760>, yard::ratio>> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// yd
|
||||
constexpr auto operator""yd(unsigned long long l) { return quantity<yard, std::int64_t>(l); }
|
||||
constexpr auto operator""yd(long double l) { return quantity<yard, long double>(l); }
|
||||
|
||||
// ft
|
||||
constexpr auto operator""ft(unsigned long long l) { return quantity<foot, std::int64_t>(l); }
|
||||
constexpr auto operator""ft(long double l) { return quantity<foot, long double>(l); }
|
||||
|
||||
// in
|
||||
constexpr auto operator""in(unsigned long long l) { return quantity<inch, std::int64_t>(l); }
|
||||
constexpr auto operator""in(long double l) { return quantity<inch, long double>(l); }
|
||||
|
||||
// mi
|
||||
constexpr auto operator""mi(unsigned long long l) { return quantity<mile, std::int64_t>(l); }
|
||||
constexpr auto operator""mi(long double l) { return quantity<mile, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units
|
124
src/include/units/dimensions/physical.h
Normal file
124
src/include/units/dimensions/physical.h
Normal file
@@ -0,0 +1,124 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/si_base_dimensions.h>
|
||||
#include <units/dimensions/si_prefixes.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
// base dimension
|
||||
|
||||
template<basic_fixed_string Name>
|
||||
struct base_dimension {
|
||||
static constexpr auto name = Name;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept BaseDimension = true;
|
||||
|
||||
// base dimension
|
||||
|
||||
template<basic_fixed_string Symbol, BaseDimension Dim, PrefixType PT, Ratio R = ratio<1>>
|
||||
struct base_unit {
|
||||
static constexpr auto symbol = Symbol;
|
||||
using dimension = Dim;
|
||||
using prefix_type = PT;
|
||||
using ratio = R;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept BaseUnit = true;
|
||||
|
||||
template<typename T, typename Dim>
|
||||
concept BaseUnitOf = BaseUnit<T> && BaseDimension<Dim> && std::same_as<typename T::dimension, Dim>;
|
||||
|
||||
|
||||
|
||||
namespace physical {
|
||||
|
||||
// base dimensions
|
||||
struct base_dim_length : base_dimension<"length"> {};
|
||||
struct base_dim_mass : base_dimension<"mass"> {};
|
||||
struct base_dim_time : base_dimension<"time"> {};
|
||||
struct base_dim_current : base_dimension<"current"> {};
|
||||
struct base_dim_temperature : base_dimension<"temperature"> {};
|
||||
struct base_dim_substance : base_dimension<"substance"> {};
|
||||
struct base_dim_luminous_intensity : base_dimension<"luminous intensity"> {};
|
||||
|
||||
|
||||
// dimensions
|
||||
template<UnitOf<base_dim_length> L>
|
||||
struct length : derived_dimension<length, exp<L, 1>> {};
|
||||
|
||||
template<UnitOf<base_dim_mass> M>
|
||||
struct mass : derived_dimension<mass, exp<M, 1>> {};
|
||||
|
||||
template<UnitOf<base_dim_time> T>
|
||||
struct time : derived_dimension<time, exp<T, 1>> {};
|
||||
|
||||
template<UnitOf<base_dim_length> L, UnitOf<base_dim_time> T>
|
||||
struct velocity : derived_dimension<velocity, exp<L, 1>, exp<T, -1>> {};
|
||||
|
||||
template<UnitOf<base_dim_length> L, UnitOf<base_dim_time> T>
|
||||
struct acceleration : derived_dimension<acceleration, exp<L, 1>, exp<T, -2>> {};
|
||||
|
||||
template<UnitOf<base_dim_mass> M, UnitOf<acceleration> A>
|
||||
struct force : derived_dimension<force, exp<M, 1>, exp<A, 1>> {};
|
||||
|
||||
} // physical
|
||||
|
||||
// SI
|
||||
namespace si {
|
||||
struct si_prefix;
|
||||
|
||||
// length
|
||||
struct metre : base_unit<"m", base_dim_length, si_prefix> {};
|
||||
struct length : physical::length<metre> {};
|
||||
|
||||
// mass
|
||||
struct kilogram : base_unit<"kg", base_dim_mass, si_prefix> {};
|
||||
struct mass : physical::mass<kilogram> {};
|
||||
|
||||
// time
|
||||
struct second : base_unit<"s", base_dim_time, si_prefix> {};
|
||||
struct time : physical::time<second> {};
|
||||
|
||||
struct nanosecond : prefixed_derived_unit<nanosecond, nano, second> {};
|
||||
struct microsecond : prefixed_derived_unit<microsecond, micro, second> {};
|
||||
struct millisecond : prefixed_derived_unit<millisecond, milli, second> {};
|
||||
struct minute : named_derived_unit<minute, time, "min", ratio<60>> {};
|
||||
struct hour : named_derived_unit<hour, time, "h", ratio<3600>> {};
|
||||
|
||||
// velocity
|
||||
struct velocity : physical::velocity<metre, second>;
|
||||
|
||||
// acceleration
|
||||
struct acceleration : physical::acceleration<metre, second>;
|
||||
|
||||
// acceleration
|
||||
struct acceleration : physical::acceleration<metre, second>;
|
||||
|
||||
}
|
||||
|
||||
} // namespace units
|
@@ -1,37 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimension.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct base_dim_length : base_dimension<"length", "m"> {};
|
||||
struct base_dim_mass : base_dimension<"mass", "kg"> {};
|
||||
struct base_dim_time : base_dimension<"time", "s"> {};
|
||||
struct base_dim_current : base_dimension<"current", "A"> {};
|
||||
struct base_dim_temperature : base_dimension<"temperature", "K"> {};
|
||||
struct base_dim_substance : base_dimension<"substance", "mol"> {};
|
||||
struct base_dim_luminous_intensity : base_dimension<"luminous intensity", "cd"> {};
|
||||
|
||||
} // namespace units
|
@@ -1,71 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/si_base_dimensions.h>
|
||||
#include <units/dimensions/si_prefixes.h>
|
||||
#include <units/quantity.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct time : derived_dimension<time, exp<base_dim_time, 1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Time = QuantityOf<T, time>;
|
||||
|
||||
struct second : named_coherent_derived_unit<second, time, "s", si_prefix> {};
|
||||
struct nanosecond : prefixed_derived_unit<nanosecond, nano, second> {};
|
||||
struct microsecond : prefixed_derived_unit<microsecond, micro, second> {};
|
||||
struct millisecond : prefixed_derived_unit<millisecond, milli, second> {};
|
||||
struct minute : named_scaled_derived_unit<minute, time, "min", ratio<60>> {};
|
||||
struct hour : named_scaled_derived_unit<hour, time, "h", ratio<3600>> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// ns
|
||||
constexpr auto operator""ns(unsigned long long l) { return quantity<nanosecond, std::int64_t>(l); }
|
||||
constexpr auto operator""ns(long double l) { return quantity<nanosecond, long double>(l); }
|
||||
|
||||
// us
|
||||
constexpr auto operator""us(unsigned long long l) { return quantity<microsecond, std::int64_t>(l); }
|
||||
constexpr auto operator""us(long double l) { return quantity<microsecond, long double>(l); }
|
||||
|
||||
// ms
|
||||
constexpr auto operator""ms(unsigned long long l) { return quantity<millisecond, std::int64_t>(l); }
|
||||
constexpr auto operator""ms(long double l) { return quantity<millisecond, long double>(l); }
|
||||
|
||||
// s
|
||||
constexpr auto operator""s(unsigned long long l) { return quantity<second, std::int64_t>(l); }
|
||||
constexpr auto operator""s(long double l) { return quantity<second, long double>(l); }
|
||||
|
||||
// min
|
||||
constexpr auto operator""min(unsigned long long l) { return quantity<minute, std::int64_t>(l); }
|
||||
constexpr auto operator""min(long double l) { return quantity<minute, long double>(l); }
|
||||
|
||||
// h
|
||||
constexpr auto operator""h(unsigned long long l) { return quantity<hour, std::int64_t>(l); }
|
||||
constexpr auto operator""h(long double l) { return quantity<hour, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units
|
@@ -1,55 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/dimensions/length.h>
|
||||
#include <units/dimensions/time.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
struct velocity : derived_dimension<velocity, exp<length, 1>, exp<time, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Velocity = QuantityOf<T, velocity>;
|
||||
|
||||
struct metre_per_second : coherent_derived_unit<metre_per_second, velocity> {};
|
||||
struct kilometre_per_hour : deduced_derived_unit<kilometre_per_hour, velocity, kilometre, hour> {};
|
||||
struct mile_per_hour : deduced_derived_unit<mile_per_hour, velocity, mile, hour> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// mps
|
||||
constexpr auto operator""mps(unsigned long long l) { return quantity<metre_per_second, std::int64_t>(l); }
|
||||
constexpr auto operator""mps(long double l) { return quantity<metre_per_second, long double>(l); }
|
||||
|
||||
// kmph
|
||||
constexpr auto operator""kmph(unsigned long long l) { return quantity<kilometre_per_hour, std::int64_t>(l); }
|
||||
constexpr auto operator""kmph(long double l) { return quantity<kilometre_per_hour, long double>(l); }
|
||||
|
||||
// mph
|
||||
constexpr auto operator""mph(unsigned long long l) { return quantity<mile_per_hour, std::int64_t>(l); }
|
||||
constexpr auto operator""mph(long double l) { return quantity<mile_per_hour, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units
|
@@ -27,27 +27,27 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
template<std::size_t N, typename U, typename Rep>
|
||||
template<std::size_t N, typename D, typename U, typename Rep>
|
||||
requires N == 0
|
||||
inline Rep AUTO pow(const quantity<U, Rep>&) noexcept
|
||||
inline Rep AUTO pow(const quantity<D, U, Rep>&) noexcept
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<std::size_t N, typename U, typename Rep>
|
||||
inline Quantity AUTO pow(const quantity<U, Rep>& q) noexcept
|
||||
template<std::size_t N, typename D, typename U, typename Rep>
|
||||
inline Quantity AUTO pow(const quantity<D, U, Rep>& q) noexcept
|
||||
{
|
||||
using dim = dimension_pow<typename U::dimension, N>;
|
||||
using dim = dimension_pow<D, N>;
|
||||
using r = ratio_pow<typename U::ratio, N>;
|
||||
return quantity<downcast<unit<dim, r>>, Rep>(static_cast<Rep>(std::pow(q.count(), N)));
|
||||
return quantity<dim, downcast<detail::reference_unit<typename dim::coherent_unit::reference, r>>, Rep>(static_cast<Rep>(std::pow(q.count(), N)));
|
||||
}
|
||||
|
||||
template<typename U, typename Rep>
|
||||
inline Quantity AUTO sqrt(const quantity<U, Rep>& q) noexcept
|
||||
template<typename D, typename U, typename Rep>
|
||||
inline Quantity AUTO sqrt(const quantity<D, U, Rep>& q) noexcept
|
||||
{
|
||||
using dim = dimension_sqrt<typename U::dimension>;
|
||||
using r = ratio_sqrt<typename U::ratio>;
|
||||
return quantity<downcast<unit<dim, r>>, Rep>(static_cast<Rep>(std::sqrt(q.count())));
|
||||
return quantity<dim, downcast<detail::reference_unit<typename dim::coherent_unit::reference, r>>, Rep>(static_cast<Rep>(std::sqrt(q.count())));
|
||||
}
|
||||
|
||||
} // namespace units
|
||||
|
151
src/include/units/physical/dimensions.h
Normal file
151
src/include/units/physical/dimensions.h
Normal file
@@ -0,0 +1,151 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/base_dimension.h>
|
||||
#include <units/bits/type_traits.h>
|
||||
#include <units/quantity.h>
|
||||
#include <units/unit.h>
|
||||
|
||||
namespace units {
|
||||
|
||||
inline namespace physical {
|
||||
|
||||
template<typename Dim, template<typename...> typename DimTemplate>
|
||||
concept DimensionOf = (Dimension<Dim> || BaseDimension<Dim>) && is_derived_from_instantiation<Dim, DimTemplate>;
|
||||
|
||||
template<typename Q, template<typename...> typename DimTemplate>
|
||||
concept QuantityOf = Quantity<Q> && is_derived_from_instantiation<Q::dimension, DimTemplate>;
|
||||
|
||||
// ------------------------ base dimensions -----------------------------
|
||||
|
||||
// length
|
||||
template<Unit U>
|
||||
struct dim_length : base_dimension<"length", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Length = QuantityOf<T, dim_length>;
|
||||
|
||||
// mass
|
||||
template<Unit U>
|
||||
struct dim_mass : base_dimension<"mass", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Mass = QuantityOf<T, dim_mass>;
|
||||
|
||||
// time
|
||||
template<Unit U>
|
||||
struct dim_time : base_dimension<"time", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Time = QuantityOf<T, dim_time>;
|
||||
|
||||
// current
|
||||
template<Unit U>
|
||||
struct dim_current : base_dimension<"current", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Current = QuantityOf<T, dim_current>;
|
||||
|
||||
// temperature
|
||||
template<Unit U>
|
||||
struct dim_temperature : base_dimension<"temperature", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Temperature = QuantityOf<T, dim_temperature>;
|
||||
|
||||
// substance
|
||||
template<Unit U>
|
||||
struct dim_substance : base_dimension<"substance", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept Substance = QuantityOf<T, dim_substance>;
|
||||
|
||||
// luminous intensity
|
||||
template<Unit U>
|
||||
struct dim_luminous_intensity : base_dimension<"luminous intensity", U> {};
|
||||
|
||||
template<typename T>
|
||||
concept LuminousIntensity = QuantityOf<T, dim_luminous_intensity>;
|
||||
|
||||
// ------------------------ derived dimensions -----------------------------
|
||||
|
||||
// frequency
|
||||
template<typename Child, Unit U, DimensionOf<dim_time> T>
|
||||
struct dim_frequency : derived_dimension<Child, U, exp<T, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Frequency = QuantityOf<T, dim_frequency>;
|
||||
|
||||
// area
|
||||
template<typename Child, Unit U, DimensionOf<dim_length> L>
|
||||
struct dim_area : derived_dimension<Child, U, exp<L, 2>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Area = QuantityOf<T, dim_area>;
|
||||
|
||||
// velocity
|
||||
template<typename Child, Unit U, DimensionOf<dim_length> L, DimensionOf<dim_time> T>
|
||||
struct dim_velocity : derived_dimension<Child, U, exp<L, 1>, exp<T, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Velocity = QuantityOf<T, dim_velocity>;
|
||||
|
||||
// acceleration
|
||||
template<typename Child, Unit U, DimensionOf<dim_length> L, DimensionOf<dim_time> T>
|
||||
struct dim_acceleration : derived_dimension<Child, U, exp<L, 1>, exp<T, -2>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Acceleration = QuantityOf<T, dim_acceleration>;
|
||||
|
||||
// force
|
||||
template<typename Child, Unit U, DimensionOf<dim_mass> M, DimensionOf<dim_acceleration> A>
|
||||
struct dim_force : derived_dimension<Child, U, exp<M, 1>, exp<A, 1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Force = QuantityOf<T, dim_force>;
|
||||
|
||||
// energy
|
||||
template<typename Child, Unit U, DimensionOf<dim_force> F, DimensionOf<dim_length> L>
|
||||
struct dim_energy : derived_dimension<Child, U, exp<F, 1>, exp<L, 1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Energy = QuantityOf<T, dim_energy>;
|
||||
|
||||
// power
|
||||
template<typename Child, Unit U, DimensionOf<dim_energy> E, DimensionOf<dim_time> T>
|
||||
struct dim_power : derived_dimension<Child, U, exp<E, 1>, exp<T, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Power = QuantityOf<T, dim_power>;
|
||||
|
||||
// pressure
|
||||
template<typename Child, Unit U, DimensionOf<dim_force> F, DimensionOf<dim_area> A>
|
||||
struct dim_pressure : derived_dimension<Child, U, exp<F, 1>, exp<A, -1>> {};
|
||||
|
||||
template<typename T>
|
||||
concept Pressure = QuantityOf<T, dim_pressure>;
|
||||
|
||||
} // namespace physical
|
||||
|
||||
} // namespace units
|
65
src/include/units/physical/si/area.h
Normal file
65
src/include/units/physical/si/area.h
Normal file
@@ -0,0 +1,65 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/physical/dimensions.h>
|
||||
#include <units/physical/si/length.h>
|
||||
|
||||
namespace units::si {
|
||||
|
||||
struct square_metre : unit<square_metre> {};
|
||||
struct dim_area : physical::dim_area<dim_area, square_metre, dim_length> {};
|
||||
|
||||
struct square_millimetre : deduced_unit<square_millimetre, dim_area, millimetre> {};
|
||||
struct square_centimetre : deduced_unit<square_centimetre, dim_area, centimetre> {};
|
||||
struct square_kilometre : deduced_unit<square_kilometre, dim_area, kilometre> {};
|
||||
struct square_foot : deduced_unit<square_foot, dim_area, foot> {};
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using area = quantity<dim_area, U, Rep>;
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// sq_m
|
||||
constexpr auto operator"" sq_m(unsigned long long l) { return area<square_metre, std::int64_t>(l); }
|
||||
constexpr auto operator"" sq_m(long double l) { return area<square_metre, long double>(l); }
|
||||
|
||||
// sq_mm
|
||||
constexpr auto operator"" sq_mm(unsigned long long l) { return area<square_millimetre, std::int64_t>(l); }
|
||||
constexpr auto operator"" sq_mm(long double l) { return area<square_millimetre, long double>(l); }
|
||||
|
||||
// sq_cm
|
||||
constexpr auto operator"" sq_cm(unsigned long long l) { return area<square_centimetre, std::int64_t>(l); }
|
||||
constexpr auto operator"" sq_cm(long double l) { return area<square_centimetre, long double>(l); }
|
||||
|
||||
// sq_km
|
||||
constexpr auto operator"" sq_km(unsigned long long l) { return area<square_kilometre, std::int64_t>(l); }
|
||||
constexpr auto operator"" sq_km(long double l) { return area<square_kilometre, long double>(l); }
|
||||
|
||||
// sq_ft
|
||||
constexpr auto operator"" sq_ft(unsigned long long l) { return area<square_foot, std::int64_t>(l); }
|
||||
constexpr auto operator"" sq_ft(long double l) { return area<square_foot, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units::si
|
70
src/include/units/physical/si/frequency.h
Normal file
70
src/include/units/physical/si/frequency.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/physical/dimensions.h>
|
||||
#include <units/physical/si/time.h>
|
||||
|
||||
namespace units::si {
|
||||
|
||||
struct hertz : named_unit<hertz, "Hz", prefix> {};
|
||||
struct millihertz : prefixed_unit<millihertz, milli, hertz> {};
|
||||
struct kilohertz : prefixed_unit<kilohertz, kilo, hertz> {};
|
||||
struct megahertz : prefixed_unit<megahertz, mega, hertz> {};
|
||||
struct gigahertz : prefixed_unit<gigahertz, giga, hertz> {};
|
||||
struct terahertz : prefixed_unit<terahertz, tera, hertz> {};
|
||||
|
||||
struct dim_frequency : physical::dim_frequency<dim_frequency, hertz, dim_time> {};
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using frequency = quantity<dim_frequency, U, Rep>;
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// Hz
|
||||
constexpr auto operator"" Hz(unsigned long long l) { return frequency<hertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" Hz(long double l) { return frequency<hertz, long double>(l); }
|
||||
|
||||
// mHz
|
||||
constexpr auto operator"" mHz(unsigned long long l) { return frequency<millihertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" mHz(long double l) { return frequency<millihertz, long double>(l); }
|
||||
|
||||
// kHz
|
||||
constexpr auto operator"" kHz(unsigned long long l) { return frequency<kilohertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" kHz(long double l) { return frequency<kilohertz, long double>(l); }
|
||||
|
||||
// MHz
|
||||
constexpr auto operator"" MHz(unsigned long long l) { return frequency<megahertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" MHz(long double l) { return frequency<megahertz, long double>(l); }
|
||||
|
||||
// GHz
|
||||
constexpr auto operator"" GHz(unsigned long long l) { return frequency<gigahertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" GHz(long double l) { return frequency<gigahertz, long double>(l); }
|
||||
|
||||
// THz
|
||||
constexpr auto operator"" THz(unsigned long long l) { return frequency<terahertz, std::int64_t>(l); }
|
||||
constexpr auto operator"" THz(long double l) { return frequency<terahertz, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units::si
|
86
src/include/units/physical/si/length.h
Normal file
86
src/include/units/physical/si/length.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/physical/dimensions.h>
|
||||
#include <units/physical/si/prefixes.h>
|
||||
|
||||
namespace units::si {
|
||||
|
||||
struct metre : named_unit<metre, "m", prefix> {};
|
||||
struct millimetre : prefixed_unit<millimetre, milli, metre> {};
|
||||
struct centimetre : prefixed_unit<centimetre, centi, metre> {};
|
||||
struct kilometre : prefixed_unit<kilometre, kilo, metre> {};
|
||||
|
||||
struct dim_length : physical::dim_length<metre> {};
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using length = quantity<dim_length, U, Rep>;
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// m
|
||||
constexpr auto operator"" m(unsigned long long l) { return length<metre, std::int64_t>(l); }
|
||||
constexpr auto operator"" m(long double l) { return length<metre, long double>(l); }
|
||||
|
||||
// mm
|
||||
constexpr auto operator"" mm(unsigned long long l) { return length<millimetre, std::int64_t>(l); }
|
||||
constexpr auto operator"" mm(long double l) { return length<millimetre, long double>(l); }
|
||||
|
||||
// cm
|
||||
constexpr auto operator"" cm(unsigned long long l) { return length<centimetre, std::int64_t>(l); }
|
||||
constexpr auto operator"" cm(long double l) { return length<centimetre, long double>(l); }
|
||||
|
||||
// km
|
||||
constexpr auto operator"" km(unsigned long long l) { return length<kilometre, std::int64_t>(l); }
|
||||
constexpr auto operator"" km(long double l) { return length<kilometre, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
// US customary units
|
||||
struct yard : scaled_unit<yard, "yd", no_prefix, ratio<9'144, 10'000>, metre> {};
|
||||
struct foot : scaled_unit<foot, "ft", no_prefix, ratio<1, 3>, yard> {};
|
||||
struct inch : scaled_unit<inch, "in", no_prefix, ratio<1, 12>, foot> {};
|
||||
struct mile : scaled_unit<mile, "mi", no_prefix, ratio<1'760>, yard> {};
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// yd
|
||||
constexpr auto operator"" yd(unsigned long long l) { return length<yard, std::int64_t>(l); }
|
||||
constexpr auto operator"" yd(long double l) { return length<yard, long double>(l); }
|
||||
|
||||
// ft
|
||||
constexpr auto operator"" ft(unsigned long long l) { return length<foot, std::int64_t>(l); }
|
||||
constexpr auto operator"" ft(long double l) { return length<foot, long double>(l); }
|
||||
|
||||
// in
|
||||
constexpr auto operator"" in(unsigned long long l) { return length<inch, std::int64_t>(l); }
|
||||
constexpr auto operator"" in(long double l) { return length<inch, long double>(l); }
|
||||
|
||||
// mi
|
||||
constexpr auto operator"" mi(unsigned long long l) { return length<mile, std::int64_t>(l); }
|
||||
constexpr auto operator"" mi(long double l) { return length<mile, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units::si
|
70
src/include/units/physical/si/time.h
Normal file
70
src/include/units/physical/si/time.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/physical/dimensions.h>
|
||||
#include <units/physical/si/prefixes.h>
|
||||
|
||||
namespace units::si {
|
||||
|
||||
struct second : named_unit<second, "s", prefix> {};
|
||||
struct nanosecond : prefixed_unit<nanosecond, nano, second> {};
|
||||
struct microsecond : prefixed_unit<microsecond, micro, second> {};
|
||||
struct millisecond : prefixed_unit<millisecond, milli, second> {};
|
||||
struct minute : scaled_unit<minute, "min", no_prefix, ratio<60>, second> {};
|
||||
struct hour : scaled_unit<hour, "h", no_prefix, ratio<3600>, second> {};
|
||||
|
||||
struct dim_time : physical::dim_time<second> {};
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using time = quantity<dim_time, U, Rep>;
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// ns
|
||||
constexpr auto operator""ns(unsigned long long l) { return time<nanosecond, std::int64_t>(l); }
|
||||
constexpr auto operator""ns(long double l) { return time<nanosecond, long double>(l); }
|
||||
|
||||
// us
|
||||
constexpr auto operator""us(unsigned long long l) { return time<microsecond, std::int64_t>(l); }
|
||||
constexpr auto operator""us(long double l) { return time<microsecond, long double>(l); }
|
||||
|
||||
// ms
|
||||
constexpr auto operator""ms(unsigned long long l) { return time<millisecond, std::int64_t>(l); }
|
||||
constexpr auto operator""ms(long double l) { return time<millisecond, long double>(l); }
|
||||
|
||||
// s
|
||||
constexpr auto operator""s(unsigned long long l) { return time<second, std::int64_t>(l); }
|
||||
constexpr auto operator""s(long double l) { return time<second, long double>(l); }
|
||||
|
||||
// min
|
||||
constexpr auto operator""min(unsigned long long l) { return time<minute, std::int64_t>(l); }
|
||||
constexpr auto operator""min(long double l) { return time<minute, long double>(l); }
|
||||
|
||||
// h
|
||||
constexpr auto operator""h(unsigned long long l) { return time<hour, std::int64_t>(l); }
|
||||
constexpr auto operator""h(long double l) { return time<hour, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units::si
|
56
src/include/units/physical/si/velocity.h
Normal file
56
src/include/units/physical/si/velocity.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/physical/dimensions.h>
|
||||
#include <units/physical/si/length.h>
|
||||
#include <units/physical/si/time.h>
|
||||
|
||||
namespace units::si {
|
||||
|
||||
struct metre_per_second : unit<metre_per_second> {};
|
||||
struct dim_velocity : physical::dim_velocity<dim_velocity, metre_per_second, dim_length, dim_time> {};
|
||||
|
||||
struct kilometre_per_hour : deduced_unit<kilometre_per_hour, dim_velocity, kilometre, hour> {};
|
||||
struct mile_per_hour : deduced_unit<mile_per_hour, dim_velocity, mile, hour> {};
|
||||
|
||||
template<Unit U, Scalar Rep = double>
|
||||
using velocity = quantity<dim_velocity, U, Rep>;
|
||||
|
||||
inline namespace literals {
|
||||
|
||||
// mps
|
||||
constexpr auto operator"" mps(unsigned long long l) { return velocity<metre_per_second, std::int64_t>(l); }
|
||||
constexpr auto operator"" mps(long double l) { return velocity<metre_per_second, long double>(l); }
|
||||
|
||||
// kmph
|
||||
constexpr auto operator"" kmph(unsigned long long l) { return velocity<kilometre_per_hour, std::int64_t>(l); }
|
||||
constexpr auto operator"" kmph(long double l) { return velocity<kilometre_per_hour, long double>(l); }
|
||||
|
||||
// mph
|
||||
constexpr auto operator"" mph(unsigned long long l) { return velocity<mile_per_hour, std::int64_t>(l); }
|
||||
constexpr auto operator"" mph(long double l) { return velocity<mile_per_hour, long double>(l); }
|
||||
|
||||
} // namespace literals
|
||||
|
||||
} // namespace units::si
|
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,13 @@ struct reference_unit : downcast_base<reference_unit<U, R>> {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// UnitOf
|
||||
template<typename U, typename D>
|
||||
concept UnitOf =
|
||||
Unit<U> &&
|
||||
Dimension<D> &&
|
||||
std::same_as<typename U::reference, typename D::coherent_unit::reference>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// same_reference_units
|
||||
@@ -49,8 +56,7 @@ template<DerivedDimension D, Unit... Us>
|
||||
inline constexpr bool same_reference_units = false;
|
||||
|
||||
template<typename... Es, Unit... Us>
|
||||
inline constexpr bool same_reference_units<derived_dimension<Es...>, Us...> =
|
||||
(std::same_as<typename Es::dimension::coherent_unit::reference, typename Us::reference> && ...);
|
||||
inline constexpr bool same_reference_units<derived_dimension<Es...>, Us...> = (UnitOf<Us, typename Es::dimension> && ...);
|
||||
|
||||
// deduced_unit
|
||||
template<typename Result, int UnitExpNum, int UnitExpDen, typename UnitRatio>
|
||||
|
@@ -27,7 +27,7 @@ add_library(unit_tests_static
|
||||
# fixed_string_test.cpp
|
||||
# math_test.cpp
|
||||
# new_design.cpp
|
||||
# quantity_test.cpp
|
||||
quantity_test.cpp
|
||||
ratio_test.cpp
|
||||
# si_test.cpp
|
||||
type_list_test.cpp
|
||||
|
@@ -20,299 +20,319 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "units/dimensions/velocity.h"
|
||||
#include "units/dimensions/frequency.h"
|
||||
#include "units/dimensions/area.h"
|
||||
#include "units/math.h"
|
||||
#include <utility>
|
||||
#include "units/physical/si/area.h"
|
||||
#include "units/physical/si/frequency.h"
|
||||
#include "units/physical/si/velocity.h"
|
||||
#include <chrono>
|
||||
#include <utility>
|
||||
|
||||
using namespace units;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
class my_value {
|
||||
T value_{};
|
||||
public:
|
||||
my_value() = default;
|
||||
constexpr my_value(T v) : value_(std::move(v)) {}
|
||||
[[nodiscard]] constexpr my_value operator-() const { return my_value(-value_); }
|
||||
template<typename T>
|
||||
class my_value {
|
||||
T value_{};
|
||||
|
||||
[[nodiscard]] friend constexpr my_value operator+(my_value lhs, my_value rhs) { return my_value(lhs.value_ + rhs.value_); }
|
||||
[[nodiscard]] friend constexpr my_value operator-(my_value lhs, my_value rhs) { return my_value(lhs.value_ - rhs.value_); }
|
||||
[[nodiscard]] friend constexpr my_value operator*(my_value lhs, my_value rhs) { return my_value(lhs.value_ * rhs.value_); }
|
||||
[[nodiscard]] friend constexpr my_value operator/(my_value lhs, my_value rhs) { return my_value(lhs.value_ / rhs.value_); }
|
||||
public:
|
||||
my_value() = default;
|
||||
constexpr my_value(T v) : value_(std::move(v)) {}
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(my_value lhs, my_value rhs) { return lhs.value_ == rhs.value_; }
|
||||
[[nodiscard]] friend constexpr bool operator!=(my_value lhs, my_value rhs) { return !(lhs == rhs); }
|
||||
[[nodiscard]] friend constexpr bool operator<(my_value lhs, my_value rhs) { return lhs.value_ < rhs.value_; }
|
||||
[[nodiscard]] friend constexpr bool operator>(my_value lhs, my_value rhs) { return rhs < lhs; }
|
||||
[[nodiscard]] friend constexpr bool operator<=(my_value lhs, my_value rhs) { return !(rhs < lhs); }
|
||||
[[nodiscard]] friend constexpr bool operator>=(my_value lhs, my_value rhs) { return !(lhs < rhs); }
|
||||
// constexpr my_value& operator+=(my_value other) { value_ += other.value_; return *this; }
|
||||
// constexpr my_value& operator-=(my_value other) { value_ -= other.value_; return *this; }
|
||||
// constexpr my_value& operator*=(my_value other) { value_ *= other.value_; return *this; }
|
||||
// constexpr my_value& operator/=(my_value other) { value_ /= other.value_; return *this; }
|
||||
|
||||
constexpr operator const T&() const & { return value_; }
|
||||
};
|
||||
[[nodiscard]] constexpr my_value operator-() const { return my_value(-value_); }
|
||||
|
||||
[[nodiscard]] friend constexpr my_value operator+(my_value lhs, my_value rhs) {
|
||||
return my_value(lhs.value_ + rhs.value_);
|
||||
}
|
||||
[[nodiscard]] friend constexpr my_value operator-(my_value lhs, my_value rhs) {
|
||||
return my_value(lhs.value_ - rhs.value_);
|
||||
}
|
||||
[[nodiscard]] friend constexpr my_value operator*(my_value lhs, my_value rhs) {
|
||||
return my_value(lhs.value_ * rhs.value_);
|
||||
}
|
||||
[[nodiscard]] friend constexpr my_value operator/(my_value lhs, my_value rhs) {
|
||||
return my_value(lhs.value_ / rhs.value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(my_value lhs, my_value rhs) { return lhs.value_ == rhs.value_; }
|
||||
[[nodiscard]] friend constexpr bool operator!=(my_value lhs, my_value rhs) { return !(lhs == rhs); }
|
||||
[[nodiscard]] friend constexpr bool operator<(my_value lhs, my_value rhs) { return lhs.value_ < rhs.value_; }
|
||||
[[nodiscard]] friend constexpr bool operator>(my_value lhs, my_value rhs) { return rhs < lhs; }
|
||||
[[nodiscard]] friend constexpr bool operator<=(my_value lhs, my_value rhs) { return !(rhs < lhs); }
|
||||
[[nodiscard]] friend constexpr bool operator>=(my_value lhs, my_value rhs) { return !(lhs < rhs); }
|
||||
|
||||
constexpr operator const T&() const& { return value_; }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace units {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool treat_as_floating_point<my_value<T>> = std::is_floating_point_v<T>;
|
||||
template<typename T>
|
||||
inline constexpr bool treat_as_floating_point<my_value<T>> = std::is_floating_point_v<T>;
|
||||
|
||||
template<typename T>
|
||||
struct quantity_values<my_value<T>> {
|
||||
static constexpr my_value<T> zero() { return my_value<T>(0); }
|
||||
static constexpr my_value<T> max() { return std::numeric_limits<T>::max(); }
|
||||
static constexpr my_value<T> min() { return std::numeric_limits<T>::lowest(); }
|
||||
};
|
||||
template<typename T>
|
||||
struct quantity_values<my_value<T>> {
|
||||
static constexpr my_value<T> zero() { return my_value<T>(0); }
|
||||
static constexpr my_value<T> max() { return std::numeric_limits<T>::max(); }
|
||||
static constexpr my_value<T> min() { return std::numeric_limits<T>::lowest(); }
|
||||
};
|
||||
|
||||
} // namespace units
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename T, typename U>
|
||||
struct common_type<my_value<T>, my_value<U>> : std::type_identity<my_value<common_type_t<T, U>>> {
|
||||
};
|
||||
template<typename T, typename U>
|
||||
struct common_type<my_value<T>, my_value<U>> : std::type_identity<my_value<common_type_t<T, U>>> {};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct common_type<my_value<T>, U> : common_type<T, U> {
|
||||
};
|
||||
template<typename T, typename U>
|
||||
struct common_type<my_value<T>, U> : common_type<T, U> {};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct common_type<T, my_value<U>> : common_type<T, U> {
|
||||
};
|
||||
template<typename T, typename U>
|
||||
struct common_type<T, my_value<U>> : common_type<T, U> {};
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace {
|
||||
|
||||
static_assert(units::Scalar<my_value<float>>);
|
||||
static_assert(std::convertible_to<my_value<float>, float>);
|
||||
static_assert(std::convertible_to<float, my_value<float>>);
|
||||
static_assert(units::Scalar<my_value<float>>);
|
||||
static_assert(std::convertible_to<my_value<float>, float>);
|
||||
static_assert(std::convertible_to<float, my_value<float>>);
|
||||
|
||||
using namespace units;
|
||||
using namespace units;
|
||||
using namespace units::si;
|
||||
|
||||
// class invariants
|
||||
// class invariants
|
||||
|
||||
// constexpr quantity<length, second, int> q; // should a static_assert
|
||||
// constexpr quantity<length, metre, quantity<metre, int>> error(0m); // should trigger a static_assert
|
||||
// constexpr quantity<int, int, double> error(0); // should trigger a static_assert
|
||||
// constexpr quantity<length, unit<length, std::ratio<-1, 1>>, int> error(0); // should trigger a static_assert
|
||||
// constexpr quantity<dim_length, metre, int> q(1); // should not compile
|
||||
// constexpr quantity<length, metre, quantity<metre, int>> error(0m); // should trigger a static_assert
|
||||
// constexpr quantity<int, int, double> error(0); // should trigger a static_assert
|
||||
// constexpr quantity<length, unit<length, std::ratio<-1, 1>>, int> error(0); // should trigger a static_assert
|
||||
|
||||
// member types
|
||||
// member types
|
||||
|
||||
static_assert(std::is_same_v<quantity<metre, int>::rep, int>);
|
||||
static_assert(std::is_same_v<quantity<metre, double>::rep, double>);
|
||||
static_assert(std::is_same_v<quantity<metre, int>::unit, metre>);
|
||||
static_assert(std::is_same_v<quantity<kilometre, int>::unit, kilometre>);
|
||||
static_assert(std::is_same_v<length<metre, int>::rep, int>);
|
||||
static_assert(std::is_same_v<length<metre, double>::rep, double>);
|
||||
static_assert(std::is_same_v<length<metre, int>::unit, metre>);
|
||||
static_assert(std::is_same_v<length<kilometre, int>::unit, kilometre>);
|
||||
|
||||
// constructors
|
||||
// constructors
|
||||
|
||||
using my_int = my_value<int>;
|
||||
using my_double = my_value<double>;
|
||||
using my_int = my_value<int>;
|
||||
using my_double = my_value<double>;
|
||||
|
||||
static_assert(quantity<metre, int>().count() == 0);
|
||||
constexpr quantity<metre, int> km{1000};
|
||||
static_assert(km.count() == 1000);
|
||||
static_assert(quantity<metre, int>(km).count() == km.count());
|
||||
static_assert(length<metre, int>().count() == 0);
|
||||
constexpr length<metre, int> km{1000};
|
||||
static_assert(km.count() == 1000);
|
||||
static_assert(length<metre, int>(km).count() == km.count());
|
||||
|
||||
static_assert(quantity<metre, int>(1).count() == 1);
|
||||
static_assert(quantity<metre, int>(my_value(1)).count() == 1);
|
||||
static_assert(quantity<metre, my_int>(1).count() == my_int{1});
|
||||
// static_assert(quantity<metre, int>(1.0).count() == 1); // should not compile
|
||||
// static_assert(quantity<metre, int>(my_value(1.0)).count() == 1); // should not compile
|
||||
// static_assert(quantity<metre, my_value>(1.0).count() == 1); // should not compile
|
||||
static_assert(quantity<metre, double>(1.0).count() == 1.0);
|
||||
static_assert(quantity<metre, double>(my_value(1.0)).count() == 1.0);
|
||||
static_assert(quantity<metre, double>(1).count() == 1.0);
|
||||
static_assert(quantity<metre, double>(my_value(1)).count() == 1.0);
|
||||
static_assert(quantity<metre, double>(3.14).count() == 3.14);
|
||||
static_assert(quantity<metre, my_double>(1.0).count() == my_double{1.0});
|
||||
static_assert(quantity<metre, my_double>(1).count() == my_double{1.0});
|
||||
static_assert(quantity<metre, my_double>(3.14).count() == my_double{3.14});
|
||||
static_assert(length<metre, int>(1).count() == 1);
|
||||
static_assert(length<metre, int>(my_value(1)).count() == 1);
|
||||
static_assert(length<metre, my_int>(1).count() == my_int{1});
|
||||
// static_assert(length<metre, int>(1.0).count() == 1); // should not compile
|
||||
// static_assert(length<metre, int>(my_value(1.0)).count() == 1); // should not compile
|
||||
// static_assert(length<metre, my_value>(1.0).count() == 1); // should not compile
|
||||
static_assert(length<metre, double>(1.0).count() == 1.0);
|
||||
static_assert(length<metre, double>(my_value(1.0)).count() == 1.0);
|
||||
static_assert(length<metre, double>(1).count() == 1.0);
|
||||
static_assert(length<metre, double>(my_value(1)).count() == 1.0);
|
||||
static_assert(length<metre, double>(3.14).count() == 3.14);
|
||||
static_assert(length<metre, my_double>(1.0).count() == my_double{1.0});
|
||||
static_assert(length<metre, my_double>(1).count() == my_double{1.0});
|
||||
static_assert(length<metre, my_double>(3.14).count() == my_double{3.14});
|
||||
|
||||
static_assert(quantity<metre, int>(km).count() == 1000);
|
||||
// static_assert(quantity<metre, int>(quantity<metre, double>(3.14)).count() == 3); // should not compile
|
||||
static_assert(quantity<metre, int>(quantity_cast<quantity<metre, my_int>>(3.14m)).count() == 3);
|
||||
// static_assert(quantity<metre, int>(quantity<metre, my_double>(1000.0)).count() == 1000); // should not compile
|
||||
// static_assert(quantity<metre, my_value>(1000.0m).count() == 1000); // should not compile
|
||||
static_assert(quantity<metre, double>(1000.0m).count() == 1000.0);
|
||||
static_assert(quantity<metre, double>(quantity<metre, my_double>(1000.0)).count() == 1000.0);
|
||||
static_assert(quantity<metre, my_double>(1000.0m).count() == my_double{1000.0});
|
||||
static_assert(quantity<metre, double>(km).count() == 1000.0);
|
||||
static_assert(quantity<metre, my_double>(km).count() == my_double{1000.0});
|
||||
static_assert(quantity<metre, int>(1km).count() == 1000);
|
||||
// static_assert(quantity<metre, int>(1_s).count() == 1); // should not compile
|
||||
// static_assert(quantity<kilometre, int>(1010m).count() == 1); // should not compile
|
||||
static_assert(quantity<kilometre, int>(quantity_cast<quantity<kilometre, my_int>>(1010m)).count() == 1);
|
||||
static_assert(length<metre, int>(km).count() == 1000);
|
||||
// static_assert(length<metre, int>(length<metre, double>(3.14)).count() == 3); // should not compile
|
||||
static_assert(length<metre, int>(quantity_cast<length<metre, my_int>>(3.14m)).count() == 3);
|
||||
// static_assert(length<metre, int>(length<metre, my_double>(1000.0)).count() == 1000); // should not compile
|
||||
// static_assert(length<metre, my_value>(1000.0m).count() == 1000); // should not compile
|
||||
static_assert(length<metre, double>(1000.0m).count() == 1000.0);
|
||||
static_assert(length<metre, double>(length<metre, my_double>(1000.0)).count() == 1000.0);
|
||||
static_assert(length<metre, my_double>(1000.0m).count() == my_double{1000.0});
|
||||
static_assert(length<metre, double>(km).count() == 1000.0);
|
||||
static_assert(length<metre, my_double>(km).count() == my_double{1000.0});
|
||||
static_assert(length<metre, int>(1km).count() == 1000);
|
||||
// static_assert(length<metre, int>(1_s).count() == 1); // should not compile
|
||||
// static_assert(length<kilometre, int>(1010m).count() == 1); // should not compile
|
||||
static_assert(length<kilometre, int>(quantity_cast<length<kilometre, my_int>>(1010m)).count() == 1);
|
||||
|
||||
// assignment operator
|
||||
// assignment operator
|
||||
|
||||
static_assert([]() {
|
||||
quantity<metre, int> l1(1), l2(2);
|
||||
return l2 = l1;
|
||||
}().count() == 1);
|
||||
static_assert([]() {
|
||||
length<metre, int> l1(1), l2(2);
|
||||
return l2 = l1;
|
||||
}()
|
||||
.count() == 1);
|
||||
|
||||
// static member functions
|
||||
// static member functions
|
||||
|
||||
static_assert(quantity<metre, int>::zero().count() == 0);
|
||||
static_assert(quantity<metre, int>::min().count() == std::numeric_limits<int>::lowest());
|
||||
static_assert(quantity<metre, int>::max().count() == std::numeric_limits<int>::max());
|
||||
static_assert(quantity<metre, double>::zero().count() == 0.0);
|
||||
static_assert(quantity<metre, double>::min().count() == std::numeric_limits<double>::lowest());
|
||||
static_assert(quantity<metre, double>::max().count() == std::numeric_limits<double>::max());
|
||||
static_assert(quantity<metre, my_int>::zero().count() == my_int{0});
|
||||
static_assert(quantity<metre, my_int>::min().count() == my_int{std::numeric_limits<int>::lowest()});
|
||||
static_assert(quantity<metre, my_int>::max().count() == my_int{std::numeric_limits<int>::max()});
|
||||
static_assert(quantity<metre, my_double>::zero().count() == my_double{0.0});
|
||||
static_assert(quantity<metre, my_double>::min().count() == my_double{std::numeric_limits<double>::lowest()});
|
||||
static_assert(quantity<metre, my_double>::max().count() == my_double{std::numeric_limits<double>::max()});
|
||||
static_assert(length<metre, int>::zero().count() == 0);
|
||||
static_assert(length<metre, int>::min().count() == std::numeric_limits<int>::lowest());
|
||||
static_assert(length<metre, int>::max().count() == std::numeric_limits<int>::max());
|
||||
static_assert(length<metre, double>::zero().count() == 0.0);
|
||||
static_assert(length<metre, double>::min().count() == std::numeric_limits<double>::lowest());
|
||||
static_assert(length<metre, double>::max().count() == std::numeric_limits<double>::max());
|
||||
static_assert(length<metre, my_int>::zero().count() == my_int{0});
|
||||
static_assert(length<metre, my_int>::min().count() == my_int{std::numeric_limits<int>::lowest()});
|
||||
static_assert(length<metre, my_int>::max().count() == my_int{std::numeric_limits<int>::max()});
|
||||
static_assert(length<metre, my_double>::zero().count() == my_double{0.0});
|
||||
static_assert(length<metre, my_double>::min().count() == my_double{std::numeric_limits<double>::lowest()});
|
||||
static_assert(length<metre, my_double>::max().count() == my_double{std::numeric_limits<double>::max()});
|
||||
|
||||
// unary member operators
|
||||
// unary member operators
|
||||
|
||||
static_assert((+km).count() == 1000);
|
||||
static_assert((-km).count() == -1000);
|
||||
static_assert((+(-km)).count() == -1000);
|
||||
static_assert((-(-km)).count() == 1000);
|
||||
static_assert((+km).count() == 1000);
|
||||
static_assert((-km).count() == -1000);
|
||||
static_assert((+(-km)).count() == -1000);
|
||||
static_assert((-(-km)).count() == 1000);
|
||||
|
||||
// binary member operators
|
||||
// binary member operators
|
||||
|
||||
static_assert([](auto v) {
|
||||
auto vv = v++;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(quantity<metre, int>(1001), quantity<metre, int>(1000)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = ++v;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(quantity<metre, int>(1001), quantity<metre, int>(1001)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = v--;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(quantity<metre, int>(999), quantity<metre, int>(1000)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = --v;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(quantity<metre, int>(999), quantity<metre, int>(999)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = v++;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(length<metre, int>(1001), length<metre, int>(1000)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = ++v;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(length<metre, int>(1001), length<metre, int>(1001)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = v--;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(length<metre, int>(999), length<metre, int>(1000)));
|
||||
static_assert([](auto v) {
|
||||
auto vv = --v;
|
||||
return std::make_pair(v, vv);
|
||||
}(km) == std::make_pair(length<metre, int>(999), length<metre, int>(999)));
|
||||
|
||||
// compound assignment
|
||||
// compound assignment
|
||||
|
||||
static_assert((1m += 1m).count() == 2);
|
||||
static_assert((2m -= 1m).count() == 1);
|
||||
static_assert((1m *= 2).count() == 2);
|
||||
static_assert((2m /= 2).count() == 1);
|
||||
static_assert((7m %= 2).count() == 1);
|
||||
static_assert((7m %= 2m).count() == 1);
|
||||
static_assert((1m += 1m).count() == 2);
|
||||
static_assert((2m -= 1m).count() == 1);
|
||||
static_assert((1m *= 2).count() == 2);
|
||||
static_assert((2m /= 2).count() == 1);
|
||||
static_assert((7m %= 2).count() == 1);
|
||||
static_assert((7m %= 2m).count() == 1);
|
||||
// static_assert((7.m %= 2.).count() == 1); // should not compile
|
||||
// static_assert((7.m %= 2).count() == 1); // should not compile
|
||||
// static_assert((7m %= 2.).count() == 1); // should not compile
|
||||
static_assert((7m %= 2m).count() == 1);
|
||||
static_assert((7m %= 2m).count() == 1);
|
||||
// static_assert((7.m %= 2.m).count() == 1); // should not compile
|
||||
// static_assert((7.m %= 2m).count() == 1); // should not compile
|
||||
// static_assert((7m %= 2.m).count() == 1); // should not compile
|
||||
|
||||
// non-member arithmetic operators
|
||||
// non-member arithmetic operators
|
||||
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() + quantity<metre, double>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() + quantity<metre, double>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<kilometre, int>() + quantity<metre, double>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, double>() - quantity<metre, int>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<kilometre, double>() - quantity<metre, int>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() * 1.0), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(1.0 * quantity<metre, int>()), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre_per_second, int>() * quantity<second, int>()), quantity<metre, int>>);
|
||||
static_assert(std::is_same_v<decltype(1 / quantity<second, int>()), quantity<hertz, int>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() / 1.0), quantity<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() / quantity<metre, double>()), double>);
|
||||
static_assert(std::is_same_v<decltype(quantity<kilometre, int>() / quantity<metre, double>()), double>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() / quantity<second, int>()), quantity<metre_per_second, int>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() % short(1)), quantity<metre, int>>);
|
||||
static_assert(std::is_same_v<decltype(quantity<metre, int>() % quantity<metre, short>(1)), quantity<metre, int>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() + length<metre, double>()), length<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() + length<metre, double>()), length<metre, double>>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(length<kilometre, int>() + length<metre, double>()), length<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, double>() - length<metre, int>()), length<metre, double>>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(length<kilometre, double>() - length<metre, int>()), length<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() * 1.0), length<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(1.0 * length<metre, int>()), length<metre, double>>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(velocity<metre_per_second, int>() * si::time<second, int>()), length<metre, int>>);
|
||||
static_assert(std::is_same_v<decltype(1 / si::time<second, int>()), frequency<hertz, int>>);
|
||||
static_assert(std::is_same_v<decltype(1 / frequency<hertz, int>()), si::time<second, int>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() / 1.0), length<metre, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() / length<metre, double>()), double>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometre, int>() / length<metre, double>()), double>);
|
||||
static_assert(
|
||||
std::is_same_v<decltype(length<metre, int>() / si::time<second, int>()), velocity<metre_per_second, int>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() % short(1)), length<metre, int>>);
|
||||
static_assert(std::is_same_v<decltype(length<metre, int>() % length<metre, short>(1)), length<metre, int>>);
|
||||
|
||||
static_assert((1m + km).count() == 1001);
|
||||
static_assert((1m + 1km).count() == 1001);
|
||||
static_assert((km - 1m).count() == 999);
|
||||
static_assert((1km - 1m).count() == 999);
|
||||
static_assert((2m * 2).count() == 4);
|
||||
static_assert((3 * 3m).count() == 9);
|
||||
static_assert((4m / 2).count() == 2);
|
||||
static_assert(4m / 2m == 2);
|
||||
static_assert(4km / 2000m == 2);
|
||||
static_assert((7m % 2).count() == 1);
|
||||
static_assert((7m % 2m).count() == 1);
|
||||
static_assert((7km % 2000m).count() == 1000);
|
||||
static_assert((1m + km).count() == 1001);
|
||||
static_assert((1m + 1km).count() == 1001);
|
||||
static_assert((km - 1m).count() == 999);
|
||||
static_assert((1km - 1m).count() == 999);
|
||||
static_assert((2m * 2).count() == 4);
|
||||
static_assert((3 * 3m).count() == 9);
|
||||
static_assert((4m / 2).count() == 2);
|
||||
static_assert(4m / 2m == 2);
|
||||
static_assert(4km / 2000m == 2);
|
||||
static_assert((7m % 2).count() == 1);
|
||||
static_assert((7m % 2m).count() == 1);
|
||||
static_assert((7km % 2000m).count() == 1000);
|
||||
|
||||
// comparators
|
||||
// comparators
|
||||
|
||||
static_assert(2m + 1m == 3m);
|
||||
static_assert(!(2m + 2m == 3m));
|
||||
static_assert(2m + 2m != 3m);
|
||||
static_assert(!(2m + 2m != 4m));
|
||||
static_assert(2m > 1m);
|
||||
static_assert(!(1m > 1m));
|
||||
static_assert(1m < 2m);
|
||||
static_assert(!(2m < 2m));
|
||||
static_assert(2m >= 1m);
|
||||
static_assert(2m >= 2m);
|
||||
static_assert(!(2m >= 3m));
|
||||
static_assert(1m <= 2m);
|
||||
static_assert(2m <= 2m);
|
||||
static_assert(!(3m <= 2m));
|
||||
static_assert(2m + 1m == 3m);
|
||||
static_assert(!(2m + 2m == 3m));
|
||||
static_assert(2m + 2m != 3m);
|
||||
static_assert(!(2m + 2m != 4m));
|
||||
static_assert(2m > 1m);
|
||||
static_assert(!(1m > 1m));
|
||||
static_assert(1m < 2m);
|
||||
static_assert(!(2m < 2m));
|
||||
static_assert(2m >= 1m);
|
||||
static_assert(2m >= 2m);
|
||||
static_assert(!(2m >= 3m));
|
||||
static_assert(1m <= 2m);
|
||||
static_assert(2m <= 2m);
|
||||
static_assert(!(3m <= 2m));
|
||||
|
||||
static_assert(3m == 3.0m);
|
||||
static_assert(3m != 3.14m);
|
||||
static_assert(2m > 1.0m);
|
||||
static_assert(1.0m < 2m);
|
||||
static_assert(2.0m >= 1m);
|
||||
static_assert(1m <= 2.0m);
|
||||
static_assert(3m == 3.0m);
|
||||
static_assert(3m != 3.14m);
|
||||
static_assert(2m > 1.0m);
|
||||
static_assert(1.0m < 2m);
|
||||
static_assert(2.0m >= 1m);
|
||||
static_assert(1m <= 2.0m);
|
||||
|
||||
static_assert(1000m == 1km);
|
||||
static_assert(1001m != 1km);
|
||||
static_assert(1001m > 1km);
|
||||
static_assert(999m < 1km);
|
||||
static_assert(1000m >= 1km);
|
||||
static_assert(1000m <= 1km);
|
||||
static_assert(1000m == 1km);
|
||||
static_assert(1001m != 1km);
|
||||
static_assert(1001m > 1km);
|
||||
static_assert(999m < 1km);
|
||||
static_assert(1000m >= 1km);
|
||||
static_assert(1000m <= 1km);
|
||||
|
||||
// is_quantity
|
||||
// is_quantity
|
||||
|
||||
static_assert(Quantity<quantity<millimetre, int>>);
|
||||
static_assert(Quantity<length<millimetre, int>>);
|
||||
|
||||
// common_quantity
|
||||
// common_quantity
|
||||
|
||||
static_assert(std::is_same_v<common_quantity<quantity<metre, int>, quantity<kilometre, int>>, quantity<metre, int>>);
|
||||
static_assert(std::is_same_v<common_quantity<quantity<kilometre, long long>, quantity<metre, int>>, quantity<metre, long long>>);
|
||||
static_assert(std::is_same_v<common_quantity<quantity<kilometre, long long>, quantity<millimetre, double>>, quantity<millimetre, double>>);
|
||||
static_assert(std::is_same_v<common_quantity<length<metre, int>, length<kilometre, int>>, length<metre, int>>);
|
||||
static_assert(
|
||||
std::is_same_v<common_quantity<length<kilometre, long long>, length<metre, int>>, length<metre, long long>>);
|
||||
static_assert(std::is_same_v<common_quantity<length<kilometre, long long>, length<millimetre, double>>,
|
||||
length<millimetre, double>>);
|
||||
|
||||
// quantity_cast
|
||||
// quantity_cast
|
||||
|
||||
static_assert(std::is_same_v<decltype(quantity_cast<unit<length, ratio<1>>>(2km))::unit, metre>);
|
||||
static_assert(std::is_same_v<decltype(quantity_cast<unit<dimension<units::exp<base_dim_length, 1>>, ratio<1>>>(2km))::unit, metre>);
|
||||
static_assert(std::is_same_v<decltype(quantity_cast<detail::reference_unit<metre, ratio<1>>>(2km))::unit, metre>);
|
||||
|
||||
// static_assert(quantity_cast<int>(2km).count() == 2000); // should not compile
|
||||
static_assert(quantity_cast<quantity<metre, int>>(2km).count() == 2000);
|
||||
static_assert(quantity_cast<quantity<kilometre, int>>(2000m).count() == 2);
|
||||
// static_assert(quantity_cast<int>(2km).count() == 2000); // should not compile
|
||||
static_assert(quantity_cast<length<metre, int>>(2km).count() == 2000);
|
||||
static_assert(quantity_cast<length<kilometre, int>>(2000m).count() == 2);
|
||||
|
||||
// time
|
||||
// time
|
||||
|
||||
// static_assert(1s == 1m); // should not compile
|
||||
static_assert(1h == 3600s);
|
||||
// static_assert(1s == 1m); // should not compile
|
||||
static_assert(1h == 3600s);
|
||||
|
||||
// length
|
||||
// length
|
||||
|
||||
static_assert(1km == 1000m);
|
||||
static_assert(1km + 1m == 1001m);
|
||||
static_assert(10km / 5km == 2);
|
||||
static_assert(10km / 2 == 5km);
|
||||
static_assert(1km == 1000m);
|
||||
static_assert(1km + 1m == 1001m);
|
||||
static_assert(10km / 5km == 2);
|
||||
static_assert(10km / 2 == 5km);
|
||||
|
||||
// velocity
|
||||
// velocity
|
||||
|
||||
static_assert(10m / 5s == 2mps);
|
||||
static_assert(10 / 5s * 1m == 2mps);
|
||||
static_assert(1km / 1s == 1000mps);
|
||||
static_assert(2kmph * 2h == 4km);
|
||||
static_assert(2km / 2kmph == 1h);
|
||||
static_assert(10m / 5s == 2mps);
|
||||
static_assert(10 / 5s * 1m == 2mps);
|
||||
static_assert(1km / 1s == 1000mps);
|
||||
static_assert(2kmph * 2h == 4km);
|
||||
static_assert(2km / 2kmph == 1h);
|
||||
|
||||
static_assert(std::is_same_v<decltype(pow<2>(2m)), decltype(4sq_m)>);
|
||||
static_assert(std::is_same_v<decltype(pow<2>(2m)), decltype(4sq_m)>);
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user