Merge branch 'master' into feature/more-value-casts
This commit is contained in:
102 files changed
+1293
-1021
No files matched your search
+16
-12
@@ -83,26 +83,29 @@ check_cxx_feature_supported(__cpp_lib_format ${projectPrefix}LIB_FORMAT_SUPPORTE
|
||||
check_cxx_feature_supported("__cpp_constexpr >= 202211L" ${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
||||
check_cxx_feature_supported(__cpp_explicit_this_parameter ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
|
||||
# libc++ has a basic supports for std::format but does not set __cpp_lib_format
|
||||
# https://github.com/llvm/llvm-project/issues/77773
|
||||
if(NOT ${projectPrefix}LIB_FORMAT_SUPPORTED
|
||||
AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
|
||||
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "17"
|
||||
AND ${projectPrefix}LIBCXX
|
||||
)
|
||||
message(STATUS "Clang 17+ with libc++ detected, overriding `std::format` support")
|
||||
set(${projectPrefix}LIB_FORMAT_SUPPORTED 1)
|
||||
endif()
|
||||
|
||||
# validate settings
|
||||
if(NOT ${projectPrefix}API_FREESTANDING
|
||||
AND ${projectPrefix}API_STD_FORMAT STREQUAL "TRUE"
|
||||
AND NOT
|
||||
(${projectPrefix}LIB_FORMAT_SUPPORTED
|
||||
# libc++ has a basic supports for std::format but does not set __cpp_lib_format
|
||||
# https://github.com/llvm/llvm-project/issues/77773
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "17"
|
||||
AND ${projectPrefix}LIBCXX))
|
||||
if(NOT ${projectPrefix}API_FREESTANDING AND "${projectPrefix}API_STD_FORMAT" AND NOT
|
||||
${projectPrefix}LIB_FORMAT_SUPPORTED
|
||||
)
|
||||
message(FATAL_ERROR "`std::format` enabled but not supported")
|
||||
endif()
|
||||
|
||||
if(${projectPrefix}API_STRING_VIEW_RET STREQUAL "TRUE" AND NOT
|
||||
${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS
|
||||
)
|
||||
if("${projectPrefix}API_STRING_VIEW_RET" AND NOT ${projectPrefix}STATIC_CONSTEXPR_VARS_IN_CONSTEXPR_FUNCTIONS)
|
||||
message(FATAL_ERROR "`std::string_view` returns enabled but not supported")
|
||||
endif()
|
||||
|
||||
if(${projectPrefix}API_NO_CRTP STREQUAL "TRUE" AND NOT ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
if("${projectPrefix}API_NO_CRTP" AND NOT ${projectPrefix}EXPLICIT_THIS_PARAMETER_SUPPORTED)
|
||||
message(FATAL_ERROR "`NO_CRTP` mode enabled but explicit `this` parameter is not supported")
|
||||
endif()
|
||||
|
||||
@@ -116,6 +119,7 @@ else()
|
||||
endif()
|
||||
|
||||
# components/modules
|
||||
include(MPUnitsContracts)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(systems)
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# 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.
|
||||
|
||||
add_library(mp-units-contracts INTERFACE)
|
||||
|
||||
if(${projectPrefix}API_CONTRACTS STREQUAL "NONE")
|
||||
target_compile_definitions(mp-units-contracts INTERFACE ${projectPrefix}API_CONTRACTS=0)
|
||||
elseif(${projectPrefix}API_CONTRACTS STREQUAL "GSL-LITE")
|
||||
if(NOT TARGET gsl::gsl-lite)
|
||||
find_package(gsl-lite REQUIRED)
|
||||
endif()
|
||||
target_link_libraries(mp-units-contracts INTERFACE gsl::gsl-lite)
|
||||
target_compile_definitions(mp-units-contracts INTERFACE ${projectPrefix}API_CONTRACTS=2)
|
||||
elseif(${projectPrefix}API_CONTRACTS STREQUAL "MS-GSL")
|
||||
if(NOT TARGET Microsoft.GSL::GSL)
|
||||
find_package(Microsoft.GSL REQUIRED)
|
||||
endif()
|
||||
target_link_libraries(mp-units-contracts INTERFACE Microsoft.GSL::GSL)
|
||||
target_compile_definitions(mp-units-contracts INTERFACE ${projectPrefix}API_CONTRACTS=3)
|
||||
endif()
|
||||
|
||||
install(TARGETS mp-units-contracts EXPORT mp-unitsTargets)
|
||||
+7
-20
@@ -23,8 +23,7 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
|
||||
function(set_feature_flag name)
|
||||
set(val_list "TRUE" "FALSE")
|
||||
if(${projectPrefix}${name} IN_LIST val_list)
|
||||
if(NOT ${projectPrefix}${name} STREQUAL "AUTO")
|
||||
target_compile_definitions(
|
||||
mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}${name}=$<BOOL:${${projectPrefix}${name}}>
|
||||
)
|
||||
@@ -36,15 +35,16 @@ add_mp_units_module(
|
||||
core mp-units-core
|
||||
HEADERS include/mp-units/bits/core_gmf.h
|
||||
include/mp-units/bits/get_associated_quantity.h
|
||||
include/mp-units/bits/get_common_base.h
|
||||
include/mp-units/bits/hacks.h
|
||||
include/mp-units/bits/math_concepts.h
|
||||
include/mp-units/bits/module_macros.h
|
||||
include/mp-units/bits/quantity_spec_hierarchy.h
|
||||
include/mp-units/bits/ratio.h
|
||||
include/mp-units/bits/sudo_cast.h
|
||||
include/mp-units/bits/text_tools.h
|
||||
include/mp-units/bits/type_list.h
|
||||
include/mp-units/ext/algorithm.h
|
||||
include/mp-units/ext/contracts.h
|
||||
include/mp-units/ext/fixed_string.h
|
||||
include/mp-units/ext/prime.h
|
||||
include/mp-units/ext/type_name.h
|
||||
@@ -86,6 +86,7 @@ if(NOT ${projectPrefix}API_FREESTANDING)
|
||||
FILES
|
||||
include/mp-units/bits/fmt.h
|
||||
include/mp-units/bits/requires_hosted.h
|
||||
include/mp-units/ext/format.h
|
||||
include/mp-units/math.h
|
||||
include/mp-units/ostream.h
|
||||
include/mp-units/format.h
|
||||
@@ -99,8 +100,8 @@ set_feature_flag(API_NO_CRTP)
|
||||
|
||||
# Text formatting
|
||||
if(NOT ${projectPrefix}API_FREESTANDING
|
||||
AND (${projectPrefix}API_STD_FORMAT STREQUAL "FALSE" OR (${projectPrefix}API_STD_FORMAT STREQUAL "AUTO"
|
||||
AND NOT ${projectPrefix}LIB_FORMAT_SUPPORTED))
|
||||
AND (NOT ${projectPrefix}API_STD_FORMAT OR (${projectPrefix}API_STD_FORMAT STREQUAL "AUTO"
|
||||
AND NOT ${projectPrefix}LIB_FORMAT_SUPPORTED))
|
||||
)
|
||||
if(NOT TARGET fmt::fmt)
|
||||
find_package(fmt REQUIRED)
|
||||
@@ -109,21 +110,7 @@ if(NOT ${projectPrefix}API_FREESTANDING
|
||||
endif()
|
||||
|
||||
# Contracts checking
|
||||
if(${projectPrefix}API_CONTRACTS STREQUAL "NONE")
|
||||
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=0)
|
||||
elseif(${projectPrefix}API_CONTRACTS STREQUAL "GSL-LITE")
|
||||
if(NOT TARGET gsl::gsl-lite)
|
||||
find_package(gsl-lite REQUIRED)
|
||||
endif()
|
||||
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} gsl::gsl-lite)
|
||||
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=2)
|
||||
elseif(${projectPrefix}API_CONTRACTS STREQUAL "MS-GSL")
|
||||
if(NOT TARGET Microsoft.GSL::GSL)
|
||||
find_package(Microsoft.GSL REQUIRED)
|
||||
endif()
|
||||
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} Microsoft.GSL::GSL)
|
||||
target_compile_definitions(mp-units-core ${${projectPrefix}TARGET_SCOPE} ${projectPrefix}API_CONTRACTS=3)
|
||||
endif()
|
||||
target_link_libraries(mp-units-core ${${projectPrefix}TARGET_SCOPE} mp-units-contracts)
|
||||
|
||||
# C++20 modules
|
||||
if(${projectPrefix}BUILD_CXX_MODULES)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <mp-units/bits/hacks.h>
|
||||
#include <mp-units/compat_macros.h>
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <array>
|
||||
#include <compare>
|
||||
#include <concepts>
|
||||
@@ -44,23 +45,13 @@
|
||||
#include <utility>
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/ext/format.h>
|
||||
#include <cmath>
|
||||
#include <locale>
|
||||
#include <ostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#if MP_UNITS_USE_FMTLIB
|
||||
MP_UNITS_DIAGNOSTIC_PUSH
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
#include <fmt/format.h>
|
||||
MP_UNITS_DIAGNOSTIC_POP
|
||||
#else
|
||||
#include <format>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if __cpp_lib_text_encoding
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <mp-units/ext/algorithm.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <mp-units/ext/format.h>
|
||||
#include <array>
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
|
||||
+20
-5
@@ -56,7 +56,7 @@ template<QuantitySpec A, QuantitySpec B>
|
||||
}
|
||||
|
||||
template<QuantitySpec A, QuantitySpec B>
|
||||
[[nodiscard]] consteval auto have_common_base(A a, B b)
|
||||
[[nodiscard]] consteval bool have_common_base(A a, B b)
|
||||
{
|
||||
constexpr std::size_t a_length = hierarchy_path_length(A{});
|
||||
constexpr std::size_t b_length = hierarchy_path_length(B{});
|
||||
@@ -68,7 +68,7 @@ template<QuantitySpec A, QuantitySpec B>
|
||||
|
||||
template<QuantitySpec A, QuantitySpec B>
|
||||
requires(have_common_base_in_hierarchy_of_equal_length(A{}, B{}))
|
||||
[[nodiscard]] consteval auto get_common_base_for_hierarchy_of_equal_length(A a, B b)
|
||||
[[nodiscard]] consteval QuantitySpec auto get_common_base_for_hierarchy_of_equal_length(A a, B b)
|
||||
{
|
||||
if constexpr (is_same_v<A, B>)
|
||||
return a;
|
||||
@@ -78,14 +78,29 @@ template<QuantitySpec A, QuantitySpec B>
|
||||
|
||||
template<QuantitySpec A, QuantitySpec B>
|
||||
requires(have_common_base(A{}, B{}))
|
||||
[[nodiscard]] consteval auto get_common_base(A a, B b)
|
||||
[[nodiscard]] consteval QuantitySpec auto get_common_base(A a, B b)
|
||||
{
|
||||
constexpr int a_length = hierarchy_path_length(A{});
|
||||
constexpr int b_length = hierarchy_path_length(B{});
|
||||
constexpr std::size_t a_length = hierarchy_path_length(A{});
|
||||
constexpr std::size_t b_length = hierarchy_path_length(B{});
|
||||
if constexpr (a_length > b_length)
|
||||
return get_common_base_for_hierarchy_of_equal_length(hierarchy_path_advance<a_length - b_length>(a), b);
|
||||
else
|
||||
return get_common_base_for_hierarchy_of_equal_length(a, hierarchy_path_advance<b_length - a_length>(b));
|
||||
}
|
||||
|
||||
template<QuantitySpec Child, QuantitySpec Parent>
|
||||
[[nodiscard]] consteval bool is_child_of(Child ch, Parent p)
|
||||
{
|
||||
if constexpr (Child{} == Parent{})
|
||||
return std::true_type{};
|
||||
else {
|
||||
constexpr std::size_t child_length = hierarchy_path_length(Child{});
|
||||
constexpr std::size_t parent_length = hierarchy_path_length(Parent{});
|
||||
if constexpr (parent_length > child_length)
|
||||
return false;
|
||||
else
|
||||
return hierarchy_path_advance<child_length - parent_length>(ch) == p;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mp_units::detail
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <mp-units/compat_macros.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <compare> // IWYU pragma: export
|
||||
#include <cstdint>
|
||||
#include <numeric>
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
|
||||
#define QUANTITY_SPEC(name, ...) \
|
||||
inline constexpr struct name : ::mp_units::quantity_spec<__VA_ARGS__> { \
|
||||
#define QUANTITY_SPEC(name, ...) \
|
||||
inline constexpr struct name final : ::mp_units::quantity_spec<__VA_ARGS__> { \
|
||||
} name
|
||||
|
||||
#else
|
||||
|
||||
#define QUANTITY_SPEC(name, ...) \
|
||||
inline constexpr struct name : ::mp_units::quantity_spec<name, __VA_ARGS__> { \
|
||||
#define QUANTITY_SPEC(name, ...) \
|
||||
inline constexpr struct name final : ::mp_units::quantity_spec<name, __VA_ARGS__> { \
|
||||
} name
|
||||
|
||||
#endif
|
||||
@@ -83,26 +83,12 @@
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#if MP_UNITS_USE_FMTLIB
|
||||
MP_UNITS_DIAGNOSTIC_PUSH
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
#include <fmt/format.h>
|
||||
MP_UNITS_DIAGNOSTIC_POP
|
||||
#else
|
||||
#include <format>
|
||||
#endif
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MP_UNITS_HOSTED
|
||||
|
||||
#if MP_UNITS_API_CONTRACTS == 2 || __has_include(<gsl/gsl-lite.hpp>)
|
||||
|
||||
#include <gsl/gsl-lite.hpp>
|
||||
|
||||
#define MP_UNITS_EXPECTS(expr) gsl_Expects(expr)
|
||||
#define MP_UNITS_EXPECTS_DEBUG(expr) gsl_ExpectsDebug(expr)
|
||||
#define MP_UNITS_ASSERT(expr) gsl_Assert(expr)
|
||||
@@ -110,9 +96,6 @@ MP_UNITS_DIAGNOSTIC_POP
|
||||
|
||||
#elif MP_UNITS_API_CONTRACTS == 3 || __has_include(<gsl/gsl>)
|
||||
|
||||
#include <gsl/gsl>
|
||||
#include <cassert>
|
||||
|
||||
#define MP_UNITS_EXPECTS(expr) Expects(expr)
|
||||
#if defined NDEBUG
|
||||
#define MP_UNITS_EXPECTS_DEBUG(expr) static_cast<void>(0)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
|
||||
#include <mp-units/bits/hacks.h>
|
||||
#include <mp-units/compat_macros.h>
|
||||
|
||||
#if MP_UNITS_API_CONTRACTS == 2 || __has_include(<gsl/gsl-lite.hpp>)
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <gsl/gsl-lite.hpp>
|
||||
#else
|
||||
#include <mp-units/bits/requires_hosted.h>
|
||||
#endif
|
||||
|
||||
#elif MP_UNITS_API_CONTRACTS == 3 || __has_include(<gsl/gsl>)
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <gsl/gsl>
|
||||
#include <cassert>
|
||||
#else
|
||||
#include <mp-units/bits/requires_hosted.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MP_UNITS_IN_MODULE_INTERFACE
|
||||
@@ -32,12 +32,14 @@
|
||||
#include <mp-units/ext/type_traits.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <compare> // IWYU pragma: export
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <ranges>
|
||||
#include <string_view>
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/ext/format.h>
|
||||
#include <ostream>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// 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
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
|
||||
#include <mp-units/bits/requires_hosted.h>
|
||||
//
|
||||
#include <mp-units/bits/hacks.h>
|
||||
#include <mp-units/compat_macros.h>
|
||||
|
||||
#if MP_UNITS_USE_FMTLIB
|
||||
MP_UNITS_DIAGNOSTIC_PUSH
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW
|
||||
#include <fmt/format.h>
|
||||
MP_UNITS_DIAGNOSTIC_POP
|
||||
#else
|
||||
#include <format>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <mp-units/framework/symbol_text.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -61,9 +62,9 @@ namespace mp_units {
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
|
||||
* inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
|
||||
* inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
|
||||
* inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
|
||||
* inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
|
||||
* inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -86,6 +87,9 @@ struct base_dimension_less : std::bool_constant<(Lhs::symbol < Rhs::symbol)> {};
|
||||
template<typename T1, typename T2>
|
||||
using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
|
||||
|
||||
template<detail::DerivedDimensionExpr... Expr>
|
||||
struct derived_dimension_impl : detail::expr_fractions<detail::is_dimension_one, Expr...> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
@@ -131,7 +135,7 @@ using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
|
||||
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
|
||||
*/
|
||||
template<detail::DerivedDimensionExpr... Expr>
|
||||
struct derived_dimension : detail::expr_fractions<detail::is_dimension_one, Expr...> {};
|
||||
struct derived_dimension final : detail::derived_dimension_impl<Expr...> {};
|
||||
|
||||
/**
|
||||
* @brief Dimension one
|
||||
@@ -140,7 +144,7 @@ struct derived_dimension : detail::expr_fractions<detail::is_dimension_one, Expr
|
||||
* dimensions are zero. It is a dimension of a quantity of dimension one also known as
|
||||
* "dimensionless".
|
||||
*/
|
||||
MP_UNITS_EXPORT inline constexpr struct dimension_one : derived_dimension<> {
|
||||
MP_UNITS_EXPORT inline constexpr struct dimension_one final : detail::derived_dimension_impl<> {
|
||||
} dimension_one;
|
||||
|
||||
namespace detail {
|
||||
@@ -279,13 +283,13 @@ constexpr Out dimension_symbol_impl(Out out, const type_list<Nums...>& nums, con
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
|
||||
constexpr Out dimension_symbol_impl(Out out, const derived_dimension<Expr...>&, const dimension_symbol_formatting& fmt,
|
||||
bool negative_power)
|
||||
constexpr Out dimension_symbol_impl(Out out, const derived_dimension_impl<Expr...>&,
|
||||
const dimension_symbol_formatting& fmt, bool negative_power)
|
||||
{
|
||||
(void)negative_power;
|
||||
MP_UNITS_EXPECTS(negative_power == false);
|
||||
return dimension_symbol_impl<CharT>(out, typename derived_dimension<Expr...>::_num_{},
|
||||
typename derived_dimension<Expr...>::_den_{}, fmt);
|
||||
return dimension_symbol_impl<CharT>(out, typename derived_dimension_impl<Expr...>::_num_{},
|
||||
typename derived_dimension_impl<Expr...>::_den_{}, fmt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,20 +42,13 @@ template<typename T>
|
||||
inline constexpr bool is_derived_from_specialization_of_base_dimension =
|
||||
requires(T* t) { to_base_specialization_of_base_dimension(t); };
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_base_dimension = false;
|
||||
|
||||
template<symbol_text Symbol>
|
||||
inline constexpr bool is_specialization_of_base_dimension<base_dimension<Symbol>> = true;
|
||||
|
||||
/**
|
||||
* @brief A concept matching all named base dimensions in the library.
|
||||
*
|
||||
* Satisfied by all dimension types derived from a specialization of `base_dimension`.
|
||||
*/
|
||||
template<typename T>
|
||||
concept BaseDimension =
|
||||
is_derived_from_specialization_of_base_dimension<T> && (!is_specialization_of_base_dimension<T>);
|
||||
concept BaseDimension = is_derived_from_specialization_of_base_dimension<T> && std::is_final_v<T>;
|
||||
|
||||
template<typename T>
|
||||
struct is_dimension_one : std::false_type {};
|
||||
@@ -91,7 +84,8 @@ namespace detail {
|
||||
* being the `dimension_one`.
|
||||
*/
|
||||
template<typename T>
|
||||
concept DerivedDimension = is_specialization_of<T, derived_dimension> || is_dimension_one<T>::value;
|
||||
concept DerivedDimension =
|
||||
(is_specialization_of<T, derived_dimension> || is_dimension_one<T>::value) && std::is_final_v<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
@@ -517,8 +517,7 @@ template<typename T, auto... Ms>
|
||||
constexpr T get_value(const magnitude<Ms...>&)
|
||||
{
|
||||
// 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>(Ms) * ... * T{1}));
|
||||
|
||||
constexpr T result = detail::checked_static_cast<T>((detail::compute_base_power<T>(Ms) * ... * T{1}));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -677,16 +676,6 @@ template<auto... Ms>
|
||||
|
||||
[[nodiscard]] consteval auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); }
|
||||
|
||||
// TODO This probably should not be exported but is used in chrono.h
|
||||
MP_UNITS_EXPORT constexpr ratio as_ratio(Magnitude auto m)
|
||||
requires(is_rational(decltype(m){}))
|
||||
{
|
||||
return ratio{
|
||||
get_value<std::intmax_t>(numerator(m)),
|
||||
get_value<std::intmax_t>(denominator(m)),
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Common Magnitude.
|
||||
//
|
||||
@@ -758,7 +747,7 @@ template<auto H1, auto... T1, auto H2, auto... T2>
|
||||
template<auto... Ms>
|
||||
[[nodiscard]] consteval auto common_magnitude_type_impl(magnitude<Ms...>)
|
||||
{
|
||||
return (decltype(get_base_value(Ms)){} * ... * std::intmax_t{});
|
||||
return (std::intmax_t{} * ... * decltype(get_base_value(Ms)){});
|
||||
}
|
||||
|
||||
// Returns the most precise type to express the magnitude factor
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <mp-units/framework/unit_concepts.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <compare> // IWYU pragma: export
|
||||
#include <utility>
|
||||
#endif
|
||||
@@ -45,16 +46,21 @@ namespace mp_units {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<auto UFrom, auto UTo>
|
||||
concept IntegralConversionFactor = Unit<decltype(UFrom)> && Unit<decltype(UTo)> &&
|
||||
is_integral(get_canonical_unit(UFrom).mag / get_canonical_unit(UTo).mag);
|
||||
template<Unit UFrom, Unit UTo>
|
||||
[[nodiscard]] consteval bool integral_conversion_factor(UFrom from, UTo to)
|
||||
{
|
||||
if constexpr (is_same_v<UFrom, UTo>)
|
||||
return true;
|
||||
else
|
||||
return is_integral(get_canonical_unit(from).mag / get_canonical_unit(to).mag);
|
||||
}
|
||||
|
||||
template<typename QFrom, typename QTo>
|
||||
concept QuantityConvertibleTo =
|
||||
Quantity<QFrom> && Quantity<QTo> && implicitly_convertible(QFrom::quantity_spec, QTo::quantity_spec) &&
|
||||
convertible(QFrom::unit, QTo::unit) &&
|
||||
(treat_as_floating_point<typename QTo::rep> ||
|
||||
(!treat_as_floating_point<typename QFrom::rep> && IntegralConversionFactor<QFrom::unit, QTo::unit>)) &&
|
||||
(!treat_as_floating_point<typename QFrom::rep> && (integral_conversion_factor(QFrom::unit, QTo::unit)))) &&
|
||||
// TODO consider providing constraints of sudo_cast here rather than testing if it can be called (its return type is
|
||||
// deduced thus the function is evaluated here and may emit truncating conversion or other warnings)
|
||||
requires(QFrom q) { detail::sudo_cast<QTo>(q); };
|
||||
|
||||
@@ -35,11 +35,10 @@
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT template<typename Derived, QuantitySpec auto QS>
|
||||
MP_UNITS_EXPORT template<QuantitySpec auto QS>
|
||||
// NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility)
|
||||
struct absolute_point_origin {
|
||||
static constexpr QuantitySpec auto quantity_spec = QS;
|
||||
using _type_ = absolute_point_origin;
|
||||
};
|
||||
|
||||
MP_UNITS_EXPORT template<QuantityPoint auto QP>
|
||||
@@ -56,7 +55,7 @@ struct relative_point_origin {
|
||||
};
|
||||
|
||||
template<QuantitySpec auto QS>
|
||||
struct zeroth_point_origin_ : absolute_point_origin<zeroth_point_origin_<QS>, QS> {};
|
||||
struct zeroth_point_origin_ final : absolute_point_origin<QS> {};
|
||||
|
||||
MP_UNITS_EXPORT template<QuantitySpec auto QS>
|
||||
inline constexpr zeroth_point_origin_<QS> zeroth_point_origin;
|
||||
@@ -81,9 +80,8 @@ MP_UNITS_EXPORT template<PointOrigin PO1, PointOrigin PO2>
|
||||
[[nodiscard]] consteval bool operator==(PO1 po1, PO2 po2)
|
||||
{
|
||||
if constexpr (detail::AbsolutePointOrigin<PO1> && detail::AbsolutePointOrigin<PO2>)
|
||||
return is_same_v<typename PO1::_type_, typename PO2::_type_> ||
|
||||
(detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) &&
|
||||
interconvertible(po1.quantity_spec, po2.quantity_spec));
|
||||
return is_same_v<PO1, PO2> || (detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) &&
|
||||
interconvertible(po1.quantity_spec, po2.quantity_spec));
|
||||
else if constexpr (detail::RelativePointOrigin<PO1> && detail::RelativePointOrigin<PO2>)
|
||||
return PO1::quantity_point == PO2::quantity_point;
|
||||
else if constexpr (detail::RelativePointOrigin<PO1>)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT template<typename Derived, QuantitySpec auto QS>
|
||||
MP_UNITS_EXPORT template<QuantitySpec auto QS>
|
||||
struct absolute_point_origin;
|
||||
|
||||
namespace detail {
|
||||
@@ -40,22 +40,15 @@ namespace detail {
|
||||
template<typename T>
|
||||
inline constexpr bool is_quantity_point = false;
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_absolute_point_origin = false;
|
||||
|
||||
template<typename D, auto Q>
|
||||
inline constexpr bool is_specialization_of_absolute_point_origin<absolute_point_origin<D, Q>> = true;
|
||||
|
||||
template<typename D, auto Q>
|
||||
void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin<D, Q>*);
|
||||
template<auto Q>
|
||||
void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin<Q>*);
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_derived_from_specialization_of_absolute_point_origin =
|
||||
requires(T* t) { to_base_specialization_of_absolute_point_origin(t); };
|
||||
|
||||
template<typename T>
|
||||
concept AbsolutePointOrigin =
|
||||
is_derived_from_specialization_of_absolute_point_origin<T> && !is_specialization_of_absolute_point_origin<T>;
|
||||
concept AbsolutePointOrigin = is_derived_from_specialization_of_absolute_point_origin<T> && std::is_final_v<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -72,12 +65,6 @@ struct relative_point_origin;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_relative_point_origin = false;
|
||||
|
||||
template<auto QP>
|
||||
inline constexpr bool is_specialization_of_relative_point_origin<relative_point_origin<QP>> = true;
|
||||
|
||||
template<auto QP>
|
||||
void to_base_specialization_of_relative_point_origin(const volatile relative_point_origin<QP>*);
|
||||
|
||||
@@ -86,8 +73,7 @@ inline constexpr bool is_derived_from_specialization_of_relative_point_origin =
|
||||
requires(T* t) { to_base_specialization_of_relative_point_origin(t); };
|
||||
|
||||
template<typename T>
|
||||
concept RelativePointOrigin =
|
||||
is_derived_from_specialization_of_relative_point_origin<T> && !is_specialization_of_relative_point_origin<T>;
|
||||
concept RelativePointOrigin = is_derived_from_specialization_of_relative_point_origin<T> && std::is_final_v<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#pragma once
|
||||
|
||||
// IWYU pragma: private, include <mp-units/framework.h>
|
||||
#include <mp-units/bits/get_common_base.h>
|
||||
#include <mp-units/bits/hacks.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/bits/quantity_spec_hierarchy.h>
|
||||
#include <mp-units/compat_macros.h>
|
||||
#include <mp-units/ext/algorithm.h>
|
||||
#include <mp-units/ext/type_name.h>
|
||||
@@ -199,13 +199,13 @@ MP_UNITS_EXPORT_END
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
|
||||
* inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
|
||||
* inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
|
||||
* inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
|
||||
* inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
|
||||
* inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
|
||||
*
|
||||
* inline constexpr struct length : quantity_spec<dim_length> {} length;
|
||||
* inline constexpr struct mass : quantity_spec<dim_mass> {} mass;
|
||||
* inline constexpr struct time : quantity_spec<dim_time> {} time;
|
||||
* inline constexpr struct length final : quantity_spec<dim_length> {} length;
|
||||
* inline constexpr struct mass final : quantity_spec<dim_mass> {} mass;
|
||||
* inline constexpr struct time final : quantity_spec<dim_time> {} time;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -225,6 +225,7 @@ template<typename Self, detail::BaseDimension auto Dim, one_of<quantity_characte
|
||||
requires(... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self> {
|
||||
#endif
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr detail::BaseDimension auto dimension = Dim;
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(quantity_character::scalar);
|
||||
};
|
||||
@@ -243,12 +244,12 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct area : quantity_spec<pow<2>(length)> {} area;
|
||||
* inline constexpr struct volume : quantity_spec<pow<3>(length)> {} volume;
|
||||
* inline constexpr struct velocity : quantity_spec<position_vector / duration> {} velocity;
|
||||
* inline constexpr struct speed : quantity_spec<length / time> {} speed;
|
||||
* inline constexpr struct force : quantity_spec<mass * acceleration, quantity_character::vector> {} force;
|
||||
* inline constexpr struct power : quantity_spec<force * velocity, quantity_character::scalar> {} power;
|
||||
* inline constexpr struct area final : quantity_spec<pow<2>(length)> {} area;
|
||||
* inline constexpr struct volume final : quantity_spec<pow<3>(length)> {} volume;
|
||||
* inline constexpr struct velocity final : quantity_spec<position_vector / duration> {} velocity;
|
||||
* inline constexpr struct speed final : quantity_spec<length / time> {} speed;
|
||||
* inline constexpr struct force final : quantity_spec<mass * acceleration, quantity_character::vector> {} force;
|
||||
* inline constexpr struct power final : quantity_spec<force * velocity, quantity_character::scalar> {} power;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -260,19 +261,32 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
*/
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<detail::IntermediateDerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
||||
template<detail::DerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
||||
requires(... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<Eq, Args...> : detail::quantity_spec_interface {
|
||||
#else
|
||||
template<typename Self, detail::IntermediateDerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
||||
template<typename Self, detail::DerivedQuantitySpec auto Eq, one_of<quantity_character> auto... Args>
|
||||
requires(... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self> {
|
||||
#endif
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr auto _equation_ = Eq;
|
||||
static constexpr Dimension auto dimension = Eq.dimension;
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<QuantitySpec auto Q, bool = requires { Q._equation_; }>
|
||||
struct propagate_equation {};
|
||||
|
||||
template<QuantitySpec auto Q>
|
||||
struct propagate_equation<Q, true> {
|
||||
static constexpr auto _equation_ = Q._equation_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Specialization defining a leaf quantity in the hierarchy
|
||||
*
|
||||
@@ -285,10 +299,10 @@ struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self>
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct width : quantity_spec<length> {} width;
|
||||
* inline constexpr struct height : quantity_spec<length> {} height;
|
||||
* inline constexpr struct diameter : quantity_spec<width> {} diameter;
|
||||
* inline constexpr struct position_vector : quantity_spec<length, quantity_character::vector> {} position_vector;
|
||||
* inline constexpr struct width final : quantity_spec<length> {} width;
|
||||
* inline constexpr struct height final : quantity_spec<length> {} height;
|
||||
* inline constexpr struct diameter final : quantity_spec<width> {} diameter;
|
||||
* inline constexpr struct position_vector final : quantity_spec<length, quantity_character::vector> {} position_vector;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -303,13 +317,15 @@ struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self>
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<detail::NamedQuantitySpec auto QS, one_of<quantity_character, struct is_kind> auto... Args>
|
||||
requires(... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<QS, Args...> : decltype(QS) {
|
||||
struct quantity_spec<QS, Args...> : detail::propagate_equation<QS>, detail::quantity_spec_interface {
|
||||
#else
|
||||
template<typename Self, detail::NamedQuantitySpec auto QS, one_of<quantity_character, struct is_kind> auto... Args>
|
||||
requires(... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<Self, QS, Args...> : decltype(QS) {
|
||||
struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail::quantity_spec_interface<Self> {
|
||||
#endif
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr auto _parent_ = QS;
|
||||
static constexpr Dimension auto dimension = _parent_.dimension;
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(QS.character);
|
||||
|
||||
#ifndef MP_UNITS_API_NO_CRTP
|
||||
@@ -330,6 +346,7 @@ struct quantity_spec<Self, QS, Args...> : decltype(QS) {
|
||||
#endif
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
/**
|
||||
* @brief Specialization defining a leaf derived quantity in the hierarchy and refining paren't equation
|
||||
*
|
||||
@@ -343,10 +360,10 @@ struct quantity_spec<Self, QS, Args...> : decltype(QS) {
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct angular_measure : quantity_spec<dimensionless, arc_length / radius, is_kind> {}
|
||||
* angular_measure; inline constexpr struct velocity : quantity_spec<speed, position_vector / duration> {} velocity;
|
||||
* inline constexpr struct weight : quantity_spec<force, mass * acceleration_of_free_fall> {} weight;
|
||||
* inline constexpr struct kinetic_energy : quantity_spec<mechanical_energy, mass * pow<2>(speed)> {} kinetic_energy;
|
||||
* inline constexpr struct angular_measure final : quantity_spec<dimensionless, arc_length / radius, is_kind> {} angular_measure;
|
||||
* inline constexpr struct velocity final : quantity_spec<speed, position_vector / duration> {} velocity;
|
||||
* inline constexpr struct weight final : quantity_spec<force, mass * acceleration_of_free_fall> {} weight;
|
||||
* inline constexpr struct kinetic_energy final : quantity_spec<mechanical_energy, mass * pow<2>(speed)> {} kinetic_energy;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -358,25 +375,50 @@ struct quantity_spec<Self, QS, Args...> : decltype(QS) {
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||
*/
|
||||
// clang-format on
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
|
||||
template<detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq,
|
||||
one_of<quantity_character, struct is_kind> auto... Args>
|
||||
requires(!requires { QS._equation_; } || (requires {
|
||||
QS._equation_;
|
||||
} && (explicitly_convertible(Eq, QS._equation_)))) && (... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<QS, Eq, Args...> : quantity_spec<QS, Args...> {
|
||||
struct quantity_spec<QS, Eq, Args...> : detail::quantity_spec_interface {
|
||||
#else
|
||||
template<typename Self, detail::NamedQuantitySpec auto QS, detail::IntermediateDerivedQuantitySpec auto Eq,
|
||||
template<typename Self, detail::NamedQuantitySpec auto QS, detail::DerivedQuantitySpec auto Eq,
|
||||
one_of<quantity_character, struct is_kind> auto... Args>
|
||||
requires(!requires { QS._equation_; } || (requires {
|
||||
QS._equation_;
|
||||
} && (explicitly_convertible(Eq, QS._equation_)))) && (... && !QuantitySpec<decltype(Args)>)
|
||||
struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
|
||||
struct quantity_spec<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Self> {
|
||||
#endif
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr auto _parent_ = QS;
|
||||
static constexpr auto _equation_ = Eq;
|
||||
static constexpr Dimension auto dimension = _parent_.dimension;
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<detail::DerivedQuantitySpecExpr... Expr>
|
||||
struct derived_quantity_spec_impl :
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
detail::quantity_spec_interface,
|
||||
#else
|
||||
detail::quantity_spec_interface<derived_quantity_spec<Expr...>>,
|
||||
#endif
|
||||
detail::expr_fractions<detail::is_dimensionless, Expr...> {
|
||||
using _base_type_ = derived_quantity_spec_impl;
|
||||
using _base_ = detail::expr_fractions<detail::is_dimensionless, Expr...>;
|
||||
|
||||
static constexpr Dimension auto dimension =
|
||||
detail::expr_map<detail::to_dimension, derived_dimension, struct dimension_one,
|
||||
detail::type_list_of_base_dimension_less>(_base_{});
|
||||
static constexpr quantity_character character =
|
||||
detail::derived_quantity_character(typename _base_::_num_{}, typename _base_::_den_{});
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief A specification of a derived quantity
|
||||
@@ -421,22 +463,8 @@ struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
|
||||
* @note User should not instantiate this type! It is not exported from the C++ module. The library will
|
||||
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
|
||||
*/
|
||||
template<detail::IntermediateDerivedQuantitySpecExpr... Expr>
|
||||
struct derived_quantity_spec :
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
detail::quantity_spec_interface,
|
||||
#else
|
||||
detail::quantity_spec_interface<derived_quantity_spec<Expr...>>,
|
||||
#endif
|
||||
detail::expr_fractions<detail::is_dimensionless, Expr...> {
|
||||
using _base_ = detail::expr_fractions<detail::is_dimensionless, Expr...>;
|
||||
|
||||
static constexpr Dimension auto dimension =
|
||||
detail::expr_map<detail::to_dimension, derived_dimension, struct dimension_one,
|
||||
detail::type_list_of_base_dimension_less>(_base_{});
|
||||
static constexpr quantity_character character =
|
||||
detail::derived_quantity_character(typename _base_::_num_{}, typename _base_::_den_{});
|
||||
};
|
||||
template<detail::DerivedQuantitySpecExpr... Expr>
|
||||
struct derived_quantity_spec final : detail::derived_quantity_spec_impl<Expr...> {};
|
||||
|
||||
/**
|
||||
* @brief Quantity of dimension one
|
||||
@@ -446,6 +474,13 @@ struct derived_quantity_spec :
|
||||
*/
|
||||
MP_UNITS_EXPORT QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{});
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<>
|
||||
struct is_dimensionless<struct dimensionless> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Quantity kind specifier
|
||||
*
|
||||
@@ -454,7 +489,7 @@ MP_UNITS_EXPORT QUANTITY_SPEC(dimensionless, derived_quantity_spec<>{});
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
concept QuantitySpecWithNoSpecifiers = detail::NamedQuantitySpec<T> || detail::IntermediateDerivedQuantitySpec<T>;
|
||||
concept QuantitySpecWithNoSpecifiers = detail::NamedQuantitySpec<T> || detail::DerivedQuantitySpec<T>;
|
||||
|
||||
template<QuantitySpec Q>
|
||||
[[nodiscard]] consteval QuantitySpec auto get_kind_tree_root(Q q);
|
||||
@@ -464,7 +499,8 @@ template<QuantitySpec Q>
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<typename Q>
|
||||
requires detail::QuantitySpecWithNoSpecifiers<Q> && (detail::get_kind_tree_root(Q{}) == Q{})
|
||||
struct kind_of_<Q> : Q {
|
||||
struct kind_of_<Q> final : Q::_base_type_ {
|
||||
using _base_type_ = kind_of_;
|
||||
static constexpr auto _quantity_spec_ = Q{};
|
||||
};
|
||||
#else
|
||||
@@ -476,7 +512,8 @@ template<typename Q>
|
||||
template<detail::QuantitySpecWithNoSpecifiers Q>
|
||||
requires(detail::get_kind_tree_root(Q{}) == Q{})
|
||||
#endif
|
||||
struct kind_of_<Q> : quantity_spec<kind_of_<Q>, Q{}> {
|
||||
struct kind_of_<Q> final : quantity_spec<kind_of_<Q>, Q{}>::_base_type_ {
|
||||
using _base_type_ = kind_of_;
|
||||
static constexpr auto _quantity_spec_ = Q{};
|
||||
};
|
||||
#endif
|
||||
@@ -487,9 +524,6 @@ inline constexpr kind_of_<MP_UNITS_REMOVE_CONST(decltype(Q))> kind_of;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<>
|
||||
struct is_dimensionless<struct dimensionless> : std::true_type {};
|
||||
|
||||
template<QuantitySpec auto... From, QuantitySpec Q>
|
||||
[[nodiscard]] consteval QuantitySpec auto clone_kind_of(Q q)
|
||||
{
|
||||
@@ -556,7 +590,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q>
|
||||
return dimensionless;
|
||||
else if constexpr (detail::ratio{Num, Den} == 1)
|
||||
return q;
|
||||
else if constexpr (detail::IntermediateDerivedQuantitySpec<Q>)
|
||||
else if constexpr (detail::DerivedQuantitySpec<Q>)
|
||||
return detail::clone_kind_of<Q{}>(
|
||||
detail::expr_pow<Num, Den, derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>(
|
||||
detail::remove_kind(q)));
|
||||
@@ -590,8 +624,6 @@ MP_UNITS_EXPORT_END
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class specs_convertible_result : std::int8_t { no, cast, explicit_conversion, yes };
|
||||
|
||||
template<QuantitySpec Q>
|
||||
[[nodiscard]] consteval int get_complexity(Q);
|
||||
|
||||
@@ -616,7 +648,7 @@ template<typename Q>
|
||||
template<QuantitySpec Q>
|
||||
[[nodiscard]] consteval int get_complexity(Q)
|
||||
{
|
||||
if constexpr (detail::IntermediateDerivedQuantitySpec<Q>)
|
||||
if constexpr (detail::DerivedQuantitySpec<Q>)
|
||||
return get_complexity(typename Q::_num_{}) + get_complexity(typename Q::_den_{});
|
||||
else if constexpr (requires { Q::_equation_; })
|
||||
return 1 + get_complexity(Q::_equation_);
|
||||
@@ -659,6 +691,8 @@ template<QuantitySpec Q>
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class specs_convertible_result : std::int8_t { no, cast, explicit_conversion, yes };
|
||||
|
||||
template<QuantitySpec Q>
|
||||
struct explode_to_equation_result {
|
||||
Q equation;
|
||||
@@ -709,7 +743,7 @@ explode_result(Q) -> explode_result<Q>;
|
||||
|
||||
#endif
|
||||
|
||||
template<int Complexity, IntermediateDerivedQuantitySpec Q>
|
||||
template<int Complexity, DerivedQuantitySpec Q>
|
||||
[[nodiscard]] consteval auto explode(Q q);
|
||||
|
||||
template<int Complexity, NamedQuantitySpec Q>
|
||||
@@ -771,7 +805,7 @@ template<int Complexity, QuantitySpec Q>
|
||||
return explode_result{dimensionless};
|
||||
}
|
||||
|
||||
template<int Complexity, IntermediateDerivedQuantitySpec Q>
|
||||
template<int Complexity, DerivedQuantitySpec Q>
|
||||
[[nodiscard]] consteval auto explode(Q q)
|
||||
{
|
||||
constexpr auto c = get_complexity(Q{});
|
||||
@@ -1304,7 +1338,7 @@ template<typename... DensTo>
|
||||
return specs_convertible_result::yes;
|
||||
}
|
||||
|
||||
template<IntermediateDerivedQuantitySpec From, IntermediateDerivedQuantitySpec To>
|
||||
template<DerivedQuantitySpec From, DerivedQuantitySpec To>
|
||||
[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To)
|
||||
{
|
||||
return are_ingredients_convertible(type_list_sort<typename From::_num_, type_list_of_ingredients_less>{},
|
||||
@@ -1313,7 +1347,7 @@ template<IntermediateDerivedQuantitySpec From, IntermediateDerivedQuantitySpec T
|
||||
type_list_sort<typename To::_den_, type_list_of_ingredients_less>{});
|
||||
}
|
||||
|
||||
template<IntermediateDerivedQuantitySpec From, NamedQuantitySpec To>
|
||||
template<DerivedQuantitySpec From, NamedQuantitySpec To>
|
||||
[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To)
|
||||
{
|
||||
return are_ingredients_convertible(type_list_sort<typename From::_num_, type_list_of_ingredients_less>{},
|
||||
@@ -1321,7 +1355,7 @@ template<IntermediateDerivedQuantitySpec From, NamedQuantitySpec To>
|
||||
type_list<To>{}, type_list<>{});
|
||||
}
|
||||
|
||||
template<NamedQuantitySpec From, IntermediateDerivedQuantitySpec To>
|
||||
template<NamedQuantitySpec From, DerivedQuantitySpec To>
|
||||
[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(From, To)
|
||||
{
|
||||
return are_ingredients_convertible(type_list<From>{}, type_list<>{},
|
||||
@@ -1353,8 +1387,8 @@ template<NamedQuantitySpec From, NamedQuantitySpec To>
|
||||
using enum specs_convertible_result;
|
||||
|
||||
if constexpr (have_common_base(From{}, To{})) {
|
||||
if constexpr (std::derived_from<From, To>) return yes;
|
||||
if constexpr (std::derived_from<To, From>) return explicit_conversion;
|
||||
if constexpr (is_child_of(From{}, To{})) return yes;
|
||||
if constexpr (is_child_of(To{}, From{})) return explicit_conversion;
|
||||
if constexpr (get_kind(From{}) == get_kind(To{})) return cast;
|
||||
return no;
|
||||
} else if constexpr (get_kind(From{}) != get_kind(To{}))
|
||||
@@ -1385,9 +1419,9 @@ template<QuantitySpec From, QuantitySpec To>
|
||||
return yes;
|
||||
else if constexpr (NamedQuantitySpec<From> && NamedQuantitySpec<To>) {
|
||||
return convertible_named(from, to);
|
||||
} else if constexpr (IntermediateDerivedQuantitySpec<From> && IntermediateDerivedQuantitySpec<To>) {
|
||||
} else if constexpr (DerivedQuantitySpec<From> && DerivedQuantitySpec<To>) {
|
||||
return are_ingredients_convertible(from, to);
|
||||
} else if constexpr (IntermediateDerivedQuantitySpec<From>) {
|
||||
} else if constexpr (DerivedQuantitySpec<From>) {
|
||||
auto res = explode<get_complexity(to)>(from);
|
||||
if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
|
||||
return convertible_impl(res.quantity, to);
|
||||
@@ -1396,7 +1430,7 @@ template<QuantitySpec From, QuantitySpec To>
|
||||
return min(eq.result, convertible_impl(res.quantity, eq.equation));
|
||||
} else
|
||||
return are_ingredients_convertible(from, to);
|
||||
} else if constexpr (IntermediateDerivedQuantitySpec<To>) {
|
||||
} else if constexpr (DerivedQuantitySpec<To>) {
|
||||
auto res = explode<get_complexity(from)>(to);
|
||||
if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
|
||||
return min(res.result, convertible_impl(from, res.quantity));
|
||||
@@ -1473,7 +1507,7 @@ template<QuantitySpec Q>
|
||||
return q;
|
||||
} else if constexpr (requires { Q::_parent_; }) {
|
||||
return get_kind_tree_root(Q::_parent_);
|
||||
} else if constexpr (detail::IntermediateDerivedQuantitySpec<Q>) {
|
||||
} else if constexpr (detail::DerivedQuantitySpec<Q>) {
|
||||
return detail::expr_map<detail::to_kind, derived_quantity_spec, struct dimensionless,
|
||||
detail::type_list_of_quantity_spec_less>(q);
|
||||
} else {
|
||||
@@ -1511,11 +1545,11 @@ template<QuantitySpec Q1, QuantitySpec Q2>
|
||||
else if constexpr (detail::NestedQuantityKindSpecOf<Q2{}, Q1{}>)
|
||||
return detail::remove_kind(q2);
|
||||
else if constexpr ((detail::QuantityKindSpec<Q1> && !detail::QuantityKindSpec<Q2>) ||
|
||||
(detail::IntermediateDerivedQuantitySpec<QQ1> && detail::NamedQuantitySpec<QQ2> &&
|
||||
(detail::DerivedQuantitySpec<QQ1> && detail::NamedQuantitySpec<QQ2> &&
|
||||
implicitly_convertible(Q1{}, Q2{})))
|
||||
return q2;
|
||||
else if constexpr ((!detail::QuantityKindSpec<Q1> && detail::QuantityKindSpec<Q2>) ||
|
||||
(detail::NamedQuantitySpec<QQ1> && detail::IntermediateDerivedQuantitySpec<QQ2> &&
|
||||
(detail::NamedQuantitySpec<QQ1> && detail::DerivedQuantitySpec<QQ2> &&
|
||||
implicitly_convertible(Q2{}, Q1{})))
|
||||
return q1;
|
||||
else if constexpr (detail::have_common_base(Q1{}, Q2{}))
|
||||
|
||||
@@ -64,25 +64,14 @@ template<typename T>
|
||||
inline constexpr bool is_derived_from_specialization_of_quantity_spec =
|
||||
requires(T* t) { to_base_specialization_of_quantity_spec(t); };
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_quantity_spec = false;
|
||||
|
||||
#ifdef MP_UNITS_API_NO_CRTP
|
||||
template<auto... Args>
|
||||
inline constexpr bool is_specialization_of_quantity_spec<quantity_spec<Args...>> = true;
|
||||
#else
|
||||
template<typename T, auto... Args>
|
||||
inline constexpr bool is_specialization_of_quantity_spec<quantity_spec<T, Args...>> = true;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Concept matching all named quantity specification types
|
||||
*
|
||||
* Satisfied by all types that derive from `quantity_spec`.
|
||||
*/
|
||||
template<typename T>
|
||||
concept NamedQuantitySpec = is_derived_from_specialization_of_quantity_spec<T> &&
|
||||
(!is_specialization_of_quantity_spec<T>)&&(!QuantityKindSpec<T>);
|
||||
concept NamedQuantitySpec =
|
||||
is_derived_from_specialization_of_quantity_spec<T> && std::is_final_v<T> && (!QuantityKindSpec<T>);
|
||||
|
||||
template<typename T>
|
||||
struct is_dimensionless : std::false_type {};
|
||||
@@ -101,13 +90,12 @@ inline constexpr bool is_per_of_quantity_specs<per<Ts...>> =
|
||||
(... && (NamedQuantitySpec<Ts> || is_dimensionless<Ts>::value || is_power_of_quantity_spec<Ts>));
|
||||
|
||||
template<typename T>
|
||||
concept IntermediateDerivedQuantitySpecExpr =
|
||||
detail::NamedQuantitySpec<T> || detail::is_dimensionless<T>::value || detail::is_power_of_quantity_spec<T> ||
|
||||
detail::is_per_of_quantity_specs<T>;
|
||||
concept DerivedQuantitySpecExpr = detail::NamedQuantitySpec<T> || detail::is_dimensionless<T>::value ||
|
||||
detail::is_power_of_quantity_spec<T> || detail::is_per_of_quantity_specs<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<detail::IntermediateDerivedQuantitySpecExpr... Expr>
|
||||
template<detail::DerivedQuantitySpecExpr... Expr>
|
||||
struct derived_quantity_spec;
|
||||
|
||||
namespace detail {
|
||||
@@ -121,7 +109,7 @@ namespace detail {
|
||||
* explicitly not supported here.
|
||||
*/
|
||||
template<typename T>
|
||||
concept IntermediateDerivedQuantitySpec =
|
||||
concept DerivedQuantitySpec =
|
||||
is_specialization_of<T, derived_quantity_spec> ||
|
||||
(QuantityKindSpec<T> &&
|
||||
is_specialization_of<std::remove_const_t<decltype(T::_quantity_spec_)>, derived_quantity_spec>);
|
||||
@@ -130,20 +118,21 @@ concept IntermediateDerivedQuantitySpec =
|
||||
|
||||
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
concept QuantitySpec =
|
||||
detail::NamedQuantitySpec<T> || detail::IntermediateDerivedQuantitySpec<T> || detail::QuantityKindSpec<T>;
|
||||
concept QuantitySpec = detail::NamedQuantitySpec<T> || detail::DerivedQuantitySpec<T> || detail::QuantityKindSpec<T>;
|
||||
|
||||
MP_UNITS_EXPORT template<QuantitySpec Q>
|
||||
[[nodiscard]] consteval detail::QuantityKindSpec auto get_kind(Q q);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<auto To, auto From>
|
||||
concept NestedQuantityKindSpecOf =
|
||||
QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> && get_kind(From) != get_kind(To) &&
|
||||
std::derived_from<decltype(To), std::remove_const_t<decltype(get_kind(From)._quantity_spec_)>>;
|
||||
template<QuantitySpec Child, QuantitySpec Parent>
|
||||
[[nodiscard]] consteval bool is_child_of(Child ch, Parent p);
|
||||
|
||||
}
|
||||
template<auto To, auto From>
|
||||
concept NestedQuantityKindSpecOf = QuantitySpec<decltype(From)> && QuantitySpec<decltype(To)> &&
|
||||
get_kind(From) != get_kind(To) && is_child_of(To, get_kind(From)._quantity_spec_);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
MP_UNITS_EXPORT template<typename T, auto QS>
|
||||
concept QuantitySpecOf =
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <mp-units/ext/fixed_string.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <compare> // IWYU pragma: export
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -45,10 +45,10 @@ namespace mp_units {
|
||||
* @code{.cpp}
|
||||
* // hypothetical natural system of units for c=1
|
||||
*
|
||||
* inline constexpr struct second : named_unit<"s"> {} second;
|
||||
* inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
|
||||
* inline constexpr struct gram : named_unit<"g"> {} gram;
|
||||
* inline constexpr struct kilogram : decltype(si::kilo<gram>) {} kilogram;
|
||||
* inline constexpr struct second final : named_unit<"s"> {} second;
|
||||
* inline constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute;
|
||||
* inline constexpr struct gram final : named_unit<"g"> {} gram;
|
||||
* inline constexpr auto kilogram = si::kilo<gram>;
|
||||
*
|
||||
* inline constexpr struct time : system_reference<isq::time, second> {} time;
|
||||
* inline constexpr struct length : system_reference<isq::length, second> {} length;
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <mp-units/framework/unit_concepts.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#include <mp-units/ext/contracts.h>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
@@ -62,6 +63,13 @@ struct propagate_point_origin<U, true> {
|
||||
static constexpr auto point_origin = U::point_origin;
|
||||
};
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
struct scaled_unit_impl : detail::propagate_point_origin<U> {
|
||||
using _base_type_ = scaled_unit_impl; // exposition only
|
||||
static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M;
|
||||
static constexpr U reference_unit{};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
@@ -74,10 +82,7 @@ struct propagate_point_origin<U, true> {
|
||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||
*/
|
||||
template<Magnitude auto M, Unit U>
|
||||
struct scaled_unit : detail::propagate_point_origin<U> {
|
||||
static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M;
|
||||
static constexpr U reference_unit{};
|
||||
};
|
||||
struct scaled_unit final : detail::scaled_unit_impl<M, U> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -100,12 +105,12 @@ inline constexpr bool is_specialization_of_scaled_unit<scaled_unit<M, U>> = true
|
||||
* For example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct second : named_unit<"s", time> {} second;
|
||||
* inline constexpr struct metre : named_unit<"m", length> {} metre;
|
||||
* inline constexpr struct hertz : named_unit<"Hz", inverse(second)> {} hertz;
|
||||
* inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
* inline constexpr struct degree_Celsius : named_unit<{u8"°C", "`C"}, kelvin> {} degree_Celsius;
|
||||
* inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
|
||||
* inline constexpr struct second final : named_unit<"s", kind_of<time>> {} second;
|
||||
* inline constexpr struct metre final : named_unit<"m", kind_of<length> {} metre;
|
||||
* inline constexpr struct hertz final : named_unit<"Hz", inverse(second), kind_of<frequency>> {} hertz;
|
||||
* inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
* inline constexpr struct degree_Celsius final : named_unit<{u8"°C", "`C"}, kelvin, zeroth_degree_Celsius> {}
|
||||
* degree_Celsius; inline constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -137,6 +142,7 @@ struct named_unit;
|
||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS>
|
||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||
struct named_unit<Symbol, QS> {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
};
|
||||
@@ -144,6 +150,7 @@ struct named_unit<Symbol, QS> {
|
||||
template<symbol_text Symbol, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
|
||||
struct named_unit<Symbol, QS, PO> {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
static constexpr auto point_origin = PO;
|
||||
@@ -162,6 +169,7 @@ struct named_unit<Symbol, QS, PO> {
|
||||
template<symbol_text Symbol>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol> {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique base unit identifier
|
||||
};
|
||||
|
||||
@@ -175,13 +183,15 @@ struct named_unit<Symbol> {
|
||||
*/
|
||||
template<symbol_text Symbol, Unit auto U>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol, U> : decltype(U) {
|
||||
struct named_unit<Symbol, U> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
};
|
||||
|
||||
template<symbol_text Symbol, Unit auto U, PointOrigin auto PO>
|
||||
requires(!Symbol.empty())
|
||||
struct named_unit<Symbol, U, PO> : decltype(U) {
|
||||
struct named_unit<Symbol, U, PO> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto point_origin = PO;
|
||||
};
|
||||
@@ -197,14 +207,16 @@ struct named_unit<Symbol, U, PO> : decltype(U) {
|
||||
*/
|
||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS>
|
||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||
struct named_unit<Symbol, U, QS> : decltype(U) {
|
||||
struct named_unit<Symbol, U, QS> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
};
|
||||
|
||||
template<symbol_text Symbol, AssociatedUnit auto U, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
|
||||
requires(!Symbol.empty()) && (QS.dimension == detail::get_associated_quantity(U).dimension)
|
||||
struct named_unit<Symbol, U, QS, PO> : decltype(U) {
|
||||
struct named_unit<Symbol, U, QS, PO> : decltype(U)::_base_type_ {
|
||||
using _base_type_ = named_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol; ///< Unique unit identifier
|
||||
static constexpr auto quantity_spec = QS;
|
||||
static constexpr auto point_origin = PO;
|
||||
@@ -225,7 +237,7 @@ struct named_unit<Symbol, U, QS, PO> : decltype(U) {
|
||||
* template<PrefixableUnit auto U>
|
||||
* inline constexpr kilo_<U> kilo;
|
||||
*
|
||||
* inline constexpr struct kilogram : decltype(si::kilo<gram>) {} kilogram;
|
||||
* inline constexpr auto kilogram = si::kilo<gram>;
|
||||
* @endcode
|
||||
*
|
||||
* @tparam Symbol a prefix text to prepend to a unit symbol
|
||||
@@ -234,7 +246,8 @@ struct named_unit<Symbol, U, QS, PO> : decltype(U) {
|
||||
*/
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol, Magnitude auto M, PrefixableUnit auto U>
|
||||
requires(!Symbol.empty())
|
||||
struct prefixed_unit : decltype(M * U) {
|
||||
struct prefixed_unit : decltype(M * U)::_base_type_ {
|
||||
using _base_type_ = prefixed_unit; // exposition only
|
||||
static constexpr auto symbol = Symbol + U.symbol;
|
||||
};
|
||||
|
||||
@@ -243,6 +256,11 @@ namespace detail {
|
||||
template<typename T>
|
||||
struct is_one : std::false_type {};
|
||||
|
||||
template<DerivedUnitExpr... Expr>
|
||||
struct derived_unit_impl : detail::expr_fractions<detail::is_one, Expr...> {
|
||||
using _base_type_ = derived_unit_impl; // exposition only
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
@@ -291,7 +309,7 @@ struct is_one : std::false_type {};
|
||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||
*/
|
||||
template<detail::DerivedUnitExpr... Expr>
|
||||
struct derived_unit : detail::expr_fractions<detail::is_one, Expr...> {};
|
||||
struct derived_unit final : detail::derived_unit_impl<Expr...> {};
|
||||
|
||||
/**
|
||||
* @brief Unit one
|
||||
@@ -299,7 +317,7 @@ struct derived_unit : detail::expr_fractions<detail::is_one, Expr...> {};
|
||||
* Unit of a dimensionless quantity.
|
||||
*/
|
||||
// clang-format off
|
||||
MP_UNITS_EXPORT inline constexpr struct one : derived_unit<> {} one;
|
||||
MP_UNITS_EXPORT inline constexpr struct one final : detail::derived_unit_impl<> {} one;
|
||||
// clang-format on
|
||||
|
||||
namespace detail {
|
||||
@@ -334,9 +352,6 @@ canonical_unit(M, U) -> canonical_unit<M, U>;
|
||||
|
||||
#endif
|
||||
|
||||
template<Unit T, symbol_text Symbol, detail::QuantityKindSpec auto Q, auto... Args>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Q, Args...>&);
|
||||
|
||||
template<Unit T, symbol_text Symbol, auto... Args>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Args...>&);
|
||||
|
||||
@@ -347,21 +362,15 @@ template<typename T, typename F, int Num, int... Den>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const power<F, Num, Den...>&);
|
||||
|
||||
template<Unit T, typename... Expr>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit<Expr...>&);
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit_impl<Expr...>&);
|
||||
|
||||
template<Unit T, auto M, typename U>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit<M, U>&)
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit_impl<M, U>&)
|
||||
{
|
||||
auto base = get_canonical_unit_impl(U{}, U{});
|
||||
return canonical_unit{M * base.mag, base.reference_unit};
|
||||
}
|
||||
|
||||
template<Unit T, symbol_text Symbol, detail::QuantityKindSpec auto Q, auto... Args>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Q, Args...>&)
|
||||
{
|
||||
return canonical_unit{mag<1>, t};
|
||||
}
|
||||
|
||||
template<Unit T, symbol_text Symbol, auto... Args>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Args...>&)
|
||||
{
|
||||
@@ -405,7 +414,7 @@ template<typename... Us>
|
||||
}
|
||||
|
||||
template<Unit T, typename... Expr>
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit<Expr...>&)
|
||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const derived_unit_impl<Expr...>&)
|
||||
{
|
||||
auto num = get_canonical_unit_impl(typename derived_unit<Expr...>::_num_{});
|
||||
auto den = get_canonical_unit_impl(typename derived_unit<Expr...>::_den_{});
|
||||
@@ -493,43 +502,13 @@ MP_UNITS_EXPORT_END
|
||||
|
||||
namespace detail {
|
||||
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(...) { return false; }
|
||||
|
||||
template<symbol_text Symbol, auto... D>
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const named_unit<Symbol, D...>&,
|
||||
const named_unit<Symbol, D...>&)
|
||||
template<Unit U1, Unit U2>
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit(U1 u1, U2 u2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename F1, typename F2, auto... Vs>
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const power<F1, Vs...>&, const power<F2, Vs...>&)
|
||||
{
|
||||
return have_same_canonical_reference_unit_impl(F1{}, F2{});
|
||||
}
|
||||
|
||||
template<typename... Us1, typename... Us2>
|
||||
requires(sizeof...(Us1) == sizeof...(Us2))
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const type_list<Us1...>&, const type_list<Us2...>&)
|
||||
{
|
||||
return (... && have_same_canonical_reference_unit_impl(Us1{}, Us2{}));
|
||||
}
|
||||
|
||||
template<typename... Expr1, typename... Expr2>
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit_impl(const derived_unit<Expr1...>&,
|
||||
const derived_unit<Expr2...>&)
|
||||
{
|
||||
return have_same_canonical_reference_unit_impl(typename derived_unit<Expr1...>::_num_{},
|
||||
typename derived_unit<Expr2...>::_num_{}) &&
|
||||
have_same_canonical_reference_unit_impl(typename derived_unit<Expr1...>::_den_{},
|
||||
typename derived_unit<Expr2...>::_den_{});
|
||||
}
|
||||
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit(Unit auto u1, Unit auto u2)
|
||||
{
|
||||
auto canonical_lhs = get_canonical_unit(u1);
|
||||
auto canonical_rhs = get_canonical_unit(u2);
|
||||
return have_same_canonical_reference_unit_impl(canonical_lhs.reference_unit, canonical_rhs.reference_unit);
|
||||
if constexpr (is_same_v<U1, U2>)
|
||||
return true;
|
||||
else
|
||||
return is_same_v<decltype(get_canonical_unit(u1).reference_unit), decltype(get_canonical_unit(u2).reference_unit)>;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
@@ -621,17 +600,21 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Unit U>
|
||||
|
||||
// common dimensionless units
|
||||
// clang-format off
|
||||
inline constexpr struct percent : named_unit<"%", mag_ratio<1, 100> * one> {} percent;
|
||||
inline constexpr struct per_mille : named_unit<symbol_text{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille;
|
||||
inline constexpr struct parts_per_million : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million;
|
||||
inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> {} percent;
|
||||
inline constexpr struct per_mille final : named_unit<symbol_text{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille;
|
||||
inline constexpr struct parts_per_million final : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million;
|
||||
inline constexpr auto ppm = parts_per_million;
|
||||
// clang-format on
|
||||
|
||||
|
||||
// convertible_to
|
||||
[[nodiscard]] consteval bool convertible(Unit auto from, Unit auto to)
|
||||
template<Unit U1, Unit U2>
|
||||
[[nodiscard]] consteval bool convertible(U1 from, U2 to)
|
||||
{
|
||||
return detail::have_same_canonical_reference_unit(from, to);
|
||||
if constexpr (is_same_v<U1, U2>)
|
||||
return true;
|
||||
else
|
||||
return detail::have_same_canonical_reference_unit(from, to);
|
||||
}
|
||||
|
||||
// Common unit
|
||||
@@ -641,10 +624,12 @@ template<Unit U1, Unit U2>
|
||||
[[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2)
|
||||
requires(detail::have_same_canonical_reference_unit(u1, u2))
|
||||
{
|
||||
if constexpr (U1{} == U2{}) {
|
||||
if constexpr (std::derived_from<U1, U2>)
|
||||
if constexpr (is_same_v<U1, U2>)
|
||||
return u1;
|
||||
else if constexpr (U1{} == U2{}) {
|
||||
if constexpr (std::derived_from<U1, typename U2::_base_type_>)
|
||||
return u1;
|
||||
else if constexpr (std::derived_from<U2, U1>)
|
||||
else if constexpr (std::derived_from<U2, typename U1::_base_type_>)
|
||||
return u2;
|
||||
else
|
||||
// TODO Check if there is a better choice here
|
||||
@@ -738,7 +723,7 @@ constexpr Out unit_symbol_impl(Out out, U, const unit_symbol_formatting& fmt, bo
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, auto M, typename U>
|
||||
constexpr Out unit_symbol_impl(Out out, const scaled_unit<M, U>& u, const unit_symbol_formatting& fmt,
|
||||
constexpr Out unit_symbol_impl(Out out, const scaled_unit_impl<M, U>& u, const unit_symbol_formatting& fmt,
|
||||
bool negative_power)
|
||||
{
|
||||
if constexpr (M == mag<1>) {
|
||||
@@ -807,13 +792,13 @@ constexpr Out unit_symbol_impl(Out out, const type_list<Nums...>& nums, const ty
|
||||
}
|
||||
|
||||
template<typename CharT, std::output_iterator<CharT> Out, typename... Expr>
|
||||
constexpr Out unit_symbol_impl(Out out, const derived_unit<Expr...>&, const unit_symbol_formatting& fmt,
|
||||
constexpr Out unit_symbol_impl(Out out, const derived_unit_impl<Expr...>&, const unit_symbol_formatting& fmt,
|
||||
bool negative_power)
|
||||
{
|
||||
(void)negative_power;
|
||||
MP_UNITS_EXPECTS(negative_power == false);
|
||||
return unit_symbol_impl<CharT>(out, typename derived_unit<Expr...>::_num_{}, typename derived_unit<Expr...>::_den_{},
|
||||
fmt);
|
||||
return unit_symbol_impl<CharT>(out, typename derived_unit_impl<Expr...>::_num_{},
|
||||
typename derived_unit_impl<Expr...>::_den_{}, fmt);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -33,9 +33,8 @@ namespace mp_units {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// do not refactor below to a variable template - GCC-11 does not like it
|
||||
template<typename T>
|
||||
struct is_unit : std::false_type {};
|
||||
inline constexpr bool is_unit = false;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -45,7 +44,7 @@ struct is_unit : std::false_type {};
|
||||
* Satisfied by all unit types provided by the library.
|
||||
*/
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
concept Unit = detail::is_unit<T>::value;
|
||||
concept Unit = detail::is_unit<T>;
|
||||
|
||||
template<Magnitude auto M, Unit U>
|
||||
struct scaled_unit;
|
||||
@@ -53,6 +52,8 @@ struct scaled_unit;
|
||||
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
||||
struct named_unit;
|
||||
|
||||
MP_UNITS_EXPORT struct one;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<symbol_text Symbol, auto... Args>
|
||||
@@ -127,25 +128,17 @@ void is_unit_impl(const scaled_unit<M, U>*);
|
||||
template<symbol_text Symbol, auto... Args>
|
||||
void is_unit_impl(const named_unit<Symbol, Args...>*);
|
||||
|
||||
template<symbol_text Symbol, auto M, auto U>
|
||||
void is_unit_impl(const prefixed_unit<Symbol, M, U>*);
|
||||
|
||||
template<typename... Expr>
|
||||
void is_unit_impl(const derived_unit<Expr...>*);
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_unit = false;
|
||||
|
||||
template<symbol_text Symbol, auto... Args>
|
||||
inline constexpr bool is_specialization_of_unit<named_unit<Symbol, Args...>> = true;
|
||||
void is_unit_impl(const one*);
|
||||
|
||||
template<typename T>
|
||||
inline constexpr bool is_specialization_of_prefixed_unit = false;
|
||||
|
||||
template<symbol_text Symbol, Magnitude auto M, PrefixableUnit auto U>
|
||||
inline constexpr bool is_specialization_of_prefixed_unit<prefixed_unit<Symbol, M, U>> = true;
|
||||
|
||||
template<typename T>
|
||||
requires requires(T* t) { is_unit_impl(t); } && (!is_specialization_of_named_unit<T>) &&
|
||||
(!is_specialization_of_prefixed_unit<T>)
|
||||
struct is_unit<T> : std::true_type {};
|
||||
requires requires(T* t) { is_unit_impl(t); } && std::is_final_v<T>
|
||||
inline constexpr bool is_unit<T> = true;
|
||||
|
||||
template<Unit U>
|
||||
[[nodiscard]] consteval bool has_associated_quantity(U);
|
||||
@@ -197,7 +190,8 @@ concept UnitOf =
|
||||
|
||||
namespace detail {
|
||||
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit(Unit auto u1, Unit auto u2);
|
||||
template<Unit U1, Unit U2>
|
||||
[[nodiscard]] consteval bool have_same_canonical_reference_unit(U1 u1, U2 u2);
|
||||
|
||||
}
|
||||
|
||||
@@ -210,7 +204,7 @@ namespace detail {
|
||||
MP_UNITS_EXPORT template<typename U, auto U2, auto QS>
|
||||
concept UnitCompatibleWith =
|
||||
Unit<U> && Unit<MP_UNITS_REMOVE_CONST(decltype(U2))> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> &&
|
||||
(!AssociatedUnit<U> || UnitOf<U, QS>)&&detail::have_same_canonical_reference_unit(U{}, U2);
|
||||
(!AssociatedUnit<U> || UnitOf<U, QS>)&&(detail::have_same_canonical_reference_unit(U{}, U2));
|
||||
|
||||
|
||||
} // namespace mp_units
|
||||
@@ -1,3 +1,25 @@
|
||||
// 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.
|
||||
|
||||
module;
|
||||
|
||||
#include <mp-units/bits/core_gmf.h>
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
// 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.
|
||||
|
||||
module;
|
||||
|
||||
export module mp_units;
|
||||
|
||||
@@ -34,15 +34,15 @@ MP_UNITS_EXPORT
|
||||
namespace mp_units::angular {
|
||||
|
||||
// clang-format off
|
||||
inline constexpr struct dim_angle : base_dimension<"A"> {} dim_angle;
|
||||
inline constexpr struct dim_angle final : base_dimension<"A"> {} dim_angle;
|
||||
QUANTITY_SPEC(angle, dim_angle);
|
||||
QUANTITY_SPEC(solid_angle, pow<2>(angle));
|
||||
|
||||
inline constexpr struct radian : named_unit<"rad", kind_of<angle>> {} radian;
|
||||
inline constexpr struct revolution : named_unit<"rev", mag<2> * mag_pi * radian> {} revolution;
|
||||
inline constexpr struct degree : named_unit<symbol_text{u8"°", "deg"}, mag_ratio<1, 360> * revolution> {} degree;
|
||||
inline constexpr struct gradian : named_unit<symbol_text{u8"ᵍ", "grad"}, mag_ratio<1, 400> * revolution> {} gradian;
|
||||
inline constexpr struct steradian : named_unit<"sr", square(radian)> {} steradian;
|
||||
inline constexpr struct radian final : named_unit<"rad", kind_of<angle>> {} radian;
|
||||
inline constexpr struct revolution final : named_unit<"rev", mag<2> * mag_pi * radian> {} revolution;
|
||||
inline constexpr struct degree final : named_unit<symbol_text{u8"°", "deg"}, mag_ratio<1, 360> * revolution> {} degree;
|
||||
inline constexpr struct gradian final : named_unit<symbol_text{u8"ᵍ", "grad"}, mag_ratio<1, 400> * revolution> {} gradian;
|
||||
inline constexpr struct steradian final : named_unit<"sr", square(radian)> {} steradian;
|
||||
// clang-format on
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
@@ -35,20 +35,16 @@ MP_UNITS_EXPORT
|
||||
namespace mp_units::cgs {
|
||||
|
||||
// clang-format off
|
||||
#if MP_UNITS_COMP_MSVC
|
||||
inline constexpr struct centimetre : si::centi_<si::metre> {} centimetre;
|
||||
#else
|
||||
inline constexpr struct centimetre : decltype(si::centi<si::metre>) {} centimetre;
|
||||
#endif
|
||||
inline constexpr struct gram : decltype(si::gram) {} gram;
|
||||
inline constexpr struct second : decltype(si::second) {} second;
|
||||
inline constexpr struct gal : named_unit<"Gal", centimetre / square(second)> {} gal;
|
||||
inline constexpr struct dyne : named_unit<"dyn", gram * centimetre / square(second)> {} dyne;
|
||||
inline constexpr struct erg : named_unit<"erg", dyne * centimetre> {} erg;
|
||||
inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square(second))> {} barye;
|
||||
inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise;
|
||||
inline constexpr struct stokes : named_unit<"St", square(centimetre) / second> {} stokes;
|
||||
inline constexpr struct kayser : named_unit<"K", one / centimetre> {} kayser;
|
||||
inline constexpr auto centimetre = si::centi<si::metre>;
|
||||
inline constexpr auto gram = si::gram;
|
||||
inline constexpr auto second = si::second;
|
||||
inline constexpr struct gal final : named_unit<"Gal", centimetre / square(second)> {} gal;
|
||||
inline constexpr struct dyne final : named_unit<"dyn", gram * centimetre / square(second)> {} dyne;
|
||||
inline constexpr struct erg final : named_unit<"erg", dyne * centimetre> {} erg;
|
||||
inline constexpr struct barye final : named_unit<"Ba", gram / (centimetre * square(second))> {} barye;
|
||||
inline constexpr struct poise final : named_unit<"P", gram / (centimetre * second)> {} poise;
|
||||
inline constexpr struct stokes final : named_unit<"St", square(centimetre) / second> {} stokes;
|
||||
inline constexpr struct kayser final : named_unit<"K", one / centimetre> {} kayser;
|
||||
// clang-format on
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
@@ -49,15 +49,15 @@ using si::electronvolt;
|
||||
// effective cross-sectional area according to EU council directive 80/181/EEC
|
||||
// https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:01980L0181-20090527#page=10
|
||||
// https://www.fedlex.admin.ch/eli/cc/1994/3109_3109_3109/de
|
||||
inline constexpr struct barn : named_unit<"b", mag_power<10, -28> * square(si::metre)> {} barn;
|
||||
inline constexpr struct barn final : named_unit<"b", mag_power<10, -28> * square(si::metre)> {} barn;
|
||||
|
||||
// mass
|
||||
inline constexpr struct electron_mass : named_unit<"m_e", mag_ratio<9'109'383'701'528, 1'000'000'000'000> * mag_power<10, -31> * si::kilogram> {} electron_mass;
|
||||
inline constexpr struct proton_mass : named_unit<"m_p", mag_ratio<1'672'621'923'695, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} proton_mass;
|
||||
inline constexpr struct neutron_mass : named_unit<"m_n", mag_ratio<1'674'927'498'049, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} neutron_mass;
|
||||
inline constexpr struct electron_mass final : named_unit<"m_e", mag_ratio<9'109'383'701'528, 1'000'000'000'000> * mag_power<10, -31> * si::kilogram> {} electron_mass;
|
||||
inline constexpr struct proton_mass final : named_unit<"m_p", mag_ratio<1'672'621'923'695, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} proton_mass;
|
||||
inline constexpr struct neutron_mass final : named_unit<"m_n", mag_ratio<1'674'927'498'049, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} neutron_mass;
|
||||
|
||||
// speed
|
||||
inline constexpr struct speed_of_light : decltype(si::si2019::speed_of_light_in_vacuum) {} speed_of_light;
|
||||
inline constexpr auto speed_of_light = si::si2019::speed_of_light_in_vacuum;
|
||||
// clang-format on
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
@@ -39,43 +39,43 @@ namespace mp_units::iau {
|
||||
|
||||
// clang-format off
|
||||
// time
|
||||
inline constexpr struct day : named_unit<"D", si::day> {} day;
|
||||
inline constexpr struct Julian_year : named_unit<"a", mag_ratio<365'25, 100> * day> {} Julian_year;
|
||||
inline constexpr struct day final : named_unit<"D", si::day> {} day;
|
||||
inline constexpr struct Julian_year final : named_unit<"a", mag_ratio<365'25, 100> * day> {} Julian_year;
|
||||
|
||||
// mass
|
||||
// https://en.wikipedia.org/wiki/Solar_mass
|
||||
// TODO What is the official mass of sun (every source in the Internet provides a different value)
|
||||
inline constexpr struct solar_mass : named_unit<symbol_text{u8"M_☉", "M_SUN"}, mag_ratio<198'847, 100'000> * mag_power<10, 30> * si::kilogram> {} solar_mass;
|
||||
inline constexpr struct Jupiter_mass : named_unit<"M_JUP", mag_ratio<1'898, 1'000> * mag_power<10, 27> * si::kilogram> {} Jupiter_mass;
|
||||
inline constexpr struct Earth_mass : named_unit<"M_EARTH", mag_ratio<59'742, 10'000> * mag_power<10, 24> * si::kilogram> {} Earth_mass;
|
||||
inline constexpr struct solar_mass final : named_unit<symbol_text{u8"M_☉", "M_SUN"}, mag_ratio<198'847, 100'000> * mag_power<10, 30> * si::kilogram> {} solar_mass;
|
||||
inline constexpr struct Jupiter_mass final : named_unit<"M_JUP", mag_ratio<1'898, 1'000> * mag_power<10, 27> * si::kilogram> {} Jupiter_mass;
|
||||
inline constexpr struct Earth_mass final : named_unit<"M_EARTH", mag_ratio<59'742, 10'000> * mag_power<10, 24> * si::kilogram> {} Earth_mass;
|
||||
|
||||
// length
|
||||
inline constexpr struct astronomical_unit : decltype(si::astronomical_unit) {} astronomical_unit;
|
||||
inline constexpr auto astronomical_unit = si::astronomical_unit;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Lunar_distance_(astronomy)
|
||||
inline constexpr struct lunar_distance : named_unit<"LD", mag<384'399> * si::kilo<si::metre>> {} lunar_distance;
|
||||
inline constexpr struct lunar_distance final : named_unit<"LD", mag<384'399> * si::kilo<si::metre>> {} lunar_distance;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Light-year
|
||||
inline constexpr struct light_year : named_unit<"ly", mag<9'460'730'472'580'800> * si::metre> {} light_year;
|
||||
inline constexpr struct light_year final : named_unit<"ly", mag<9'460'730'472'580'800> * si::metre> {} light_year;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Parsec
|
||||
inline constexpr struct parsec : named_unit<"pc", astronomical_unit / (mag_ratio<1, 3600> * si::degree)> {} parsec;
|
||||
inline constexpr struct parsec final : named_unit<"pc", astronomical_unit / (mag_ratio<1, 3600> * si::degree)> {} parsec;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Angstrom
|
||||
inline constexpr struct angstrom : named_unit<symbol_text{u8"Å", "A"}, mag_power<10, -10> * si::metre> {} angstrom;
|
||||
inline constexpr struct angstrom final : named_unit<symbol_text{u8"Å", "A"}, mag_power<10, -10> * si::metre> {} angstrom;
|
||||
|
||||
// selected constants
|
||||
// https://en.wikipedia.org/wiki/Astronomical_constant
|
||||
inline constexpr struct gaussian_gravitational_constant :
|
||||
inline constexpr struct gaussian_gravitational_constant final :
|
||||
named_unit<"k", mag_ratio<1'720'209'895, 100'000'000'000> * pow<3, 2>(astronomical_unit) / pow<1,2>(solar_mass) / day> {} gaussian_gravitational_constant;
|
||||
|
||||
inline constexpr struct speed_of_light :
|
||||
inline constexpr struct speed_of_light final :
|
||||
named_unit<symbol_text{u8"c₀", "c_0"}, si::si2019::speed_of_light_in_vacuum> {} speed_of_light;
|
||||
|
||||
inline constexpr struct constant_of_gravitation :
|
||||
inline constexpr struct constant_of_gravitation final :
|
||||
named_unit<"G", mag_ratio<667'430, 100'000> * mag_power<10, -11> * cubic(si::metre) / si::kilogram / square(si::second)> {} constant_of_gravitation;
|
||||
|
||||
inline constexpr struct hubble_constant :
|
||||
inline constexpr struct hubble_constant final :
|
||||
named_unit<symbol_text{u8"H₀", "H_0"}, mag_ratio<701, 10> * si::kilo<si::metre> / si::second / si::mega<parsec>> {} hubble_constant;
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
namespace mp_units::iec80000 {
|
||||
|
||||
// clang-format off
|
||||
template<PrefixableUnit U> struct kibi_ : prefixed_unit<"Ki", mag_power<2, 10>, U{}> {};
|
||||
template<PrefixableUnit U> struct mebi_ : prefixed_unit<"Mi", mag_power<2, 20>, U{}> {};
|
||||
template<PrefixableUnit U> struct gibi_ : prefixed_unit<"Gi", mag_power<2, 30>, U{}> {};
|
||||
template<PrefixableUnit U> struct tebi_ : prefixed_unit<"Ti", mag_power<2, 40>, U{}> {};
|
||||
template<PrefixableUnit U> struct pebi_ : prefixed_unit<"Pi", mag_power<2, 50>, U{}> {};
|
||||
template<PrefixableUnit U> struct exbi_ : prefixed_unit<"Ei", mag_power<2, 60>, U{}> {};
|
||||
template<PrefixableUnit U> struct zebi_ : prefixed_unit<"Zi", mag_power<2, 70>, U{}> {};
|
||||
template<PrefixableUnit U> struct yobi_ : prefixed_unit<"Yi", mag_power<2, 80>, U{}> {};
|
||||
template<PrefixableUnit U> struct kibi_ final : prefixed_unit<"Ki", mag_power<2, 10>, U{}> {};
|
||||
template<PrefixableUnit U> struct mebi_ final : prefixed_unit<"Mi", mag_power<2, 20>, U{}> {};
|
||||
template<PrefixableUnit U> struct gibi_ final : prefixed_unit<"Gi", mag_power<2, 30>, U{}> {};
|
||||
template<PrefixableUnit U> struct tebi_ final : prefixed_unit<"Ti", mag_power<2, 40>, U{}> {};
|
||||
template<PrefixableUnit U> struct pebi_ final : prefixed_unit<"Pi", mag_power<2, 50>, U{}> {};
|
||||
template<PrefixableUnit U> struct exbi_ final : prefixed_unit<"Ei", mag_power<2, 60>, U{}> {};
|
||||
template<PrefixableUnit U> struct zebi_ final : prefixed_unit<"Zi", mag_power<2, 70>, U{}> {};
|
||||
template<PrefixableUnit U> struct yobi_ final : prefixed_unit<"Yi", mag_power<2, 80>, U{}> {};
|
||||
|
||||
MP_UNITS_EXPORT_BEGIN
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace mp_units::iec80000 {
|
||||
|
||||
// dimensions of base quantities
|
||||
// clang-format off
|
||||
inline constexpr struct dim_traffic_intensity : base_dimension<"A"> {} dim_traffic_intensity;
|
||||
inline constexpr struct dim_traffic_intensity final : base_dimension<"A"> {} dim_traffic_intensity;
|
||||
// clang-format on
|
||||
|
||||
// quantities
|
||||
|
||||
@@ -34,11 +34,11 @@ MP_UNITS_EXPORT
|
||||
namespace mp_units::iec80000 {
|
||||
|
||||
// clang-format off
|
||||
inline constexpr struct erlang : named_unit<"E", kind_of<traffic_intensity>> {} erlang;
|
||||
inline constexpr struct bit : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
|
||||
inline constexpr struct octet : named_unit<"o", mag<8> * bit> {} octet;
|
||||
inline constexpr struct byte : named_unit<"B", mag<8> * bit> {} byte;
|
||||
inline constexpr struct baud : named_unit<"Bd", one / si::second, kind_of<modulation_rate>> {} baud;
|
||||
inline constexpr struct erlang final : named_unit<"E", kind_of<traffic_intensity>> {} erlang;
|
||||
inline constexpr struct bit final : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
|
||||
inline constexpr struct octet final : named_unit<"o", mag<8> * bit> {} octet;
|
||||
inline constexpr struct byte final : named_unit<"B", mag<8> * bit> {} byte;
|
||||
inline constexpr struct baud final : named_unit<"Bd", one / si::second, kind_of<modulation_rate>> {} baud;
|
||||
// clang-format on
|
||||
|
||||
} // namespace mp_units::iec80000
|
||||
@@ -39,38 +39,38 @@ using namespace international;
|
||||
|
||||
// clang-format off
|
||||
// https://en.wikipedia.org/wiki/Imperial_units#Length
|
||||
inline constexpr struct hand : named_unit<"hh", mag_ratio<1, 3> * foot> {} hand;
|
||||
inline constexpr struct barleycorn : named_unit<"Bc", mag_ratio<1, 3> * inch> {} barleycorn;
|
||||
inline constexpr struct thou : named_unit<"th", mag_ratio<1, 12'000> * foot> {} thou;
|
||||
inline constexpr struct chain : named_unit<"ch", mag<22> * yard> {} chain;
|
||||
inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
inline constexpr struct hand final : named_unit<"hh", mag_ratio<1, 3> * foot> {} hand;
|
||||
inline constexpr struct barleycorn final : named_unit<"Bc", mag_ratio<1, 3> * inch> {} barleycorn;
|
||||
inline constexpr struct thou final : named_unit<"th", mag_ratio<1, 12'000> * foot> {} thou;
|
||||
inline constexpr struct chain final : named_unit<"ch", mag<22> * yard> {} chain;
|
||||
inline constexpr struct furlong final : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
|
||||
// maritime units
|
||||
inline constexpr struct cable : named_unit<"cb", mag_ratio<1, 10> * nautical_mile> {} cable;
|
||||
inline constexpr struct fathom : named_unit<"ftm", mag_ratio<1, 1000> * nautical_mile> {} fathom;
|
||||
inline constexpr struct cable final : named_unit<"cb", mag_ratio<1, 10> * nautical_mile> {} cable;
|
||||
inline constexpr struct fathom final : named_unit<"ftm", mag_ratio<1, 1000> * nautical_mile> {} fathom;
|
||||
|
||||
// survey
|
||||
inline constexpr struct link : named_unit<"li", mag_ratio<1, 100> * chain> {} link;
|
||||
inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod;
|
||||
inline constexpr struct link final : named_unit<"li", mag_ratio<1, 100> * chain> {} link;
|
||||
inline constexpr struct rod final : named_unit<"rd", mag<25> * link> {} rod;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Imperial_units#Area
|
||||
inline constexpr struct perch : decltype(square(rod)) {} perch;
|
||||
inline constexpr struct rood : decltype(mag<40> * perch) {} rood;
|
||||
inline constexpr struct acre : decltype(mag<4> * rood) {} acre;
|
||||
inline constexpr struct perch final : named_unit<"perch", square(rod)> {} perch;
|
||||
inline constexpr struct rood final : named_unit<"rood", mag<40> * perch> {} rood;
|
||||
inline constexpr struct acre final : named_unit<"acre", mag<4> * rood> {} acre;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Imperial_units#Volume
|
||||
inline constexpr struct gallon : named_unit<"gal", mag_ratio<454'609, 100'000> * si::litre> {} gallon;
|
||||
inline constexpr struct quart : named_unit<"qt", mag_ratio<1, 4> * gallon> {} quart;
|
||||
inline constexpr struct pint : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint;
|
||||
inline constexpr struct gill : named_unit<"gi", mag_ratio<1, 4> * pint> {} gill;
|
||||
inline constexpr struct fluid_ounce : named_unit<"fl oz", mag_ratio<1, 5> * gill> {} fluid_ounce;
|
||||
inline constexpr struct gallon final : named_unit<"gal", mag_ratio<454'609, 100'000> * si::litre> {} gallon;
|
||||
inline constexpr struct quart final : named_unit<"qt", mag_ratio<1, 4> * gallon> {} quart;
|
||||
inline constexpr struct pint final : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint;
|
||||
inline constexpr struct gill final : named_unit<"gi", mag_ratio<1, 4> * pint> {} gill;
|
||||
inline constexpr struct fluid_ounce final : named_unit<"fl oz", mag_ratio<1, 5> * gill> {} fluid_ounce;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Avoirdupois_system#Post-Elizabethan_units
|
||||
inline constexpr auto drachm = dram;
|
||||
inline constexpr struct stone : named_unit<"st", mag<14> * pound> {} stone;
|
||||
inline constexpr struct quarter : named_unit<"qr", mag<2> * stone> {} quarter;
|
||||
inline constexpr struct long_hundredweight : named_unit<"cwt", mag<8> * stone> {} long_hundredweight;
|
||||
inline constexpr struct ton : named_unit<"t", mag<2'240> * pound> {} ton;
|
||||
inline constexpr struct stone final : named_unit<"st", mag<14> * pound> {} stone;
|
||||
inline constexpr struct quarter final : named_unit<"qr", mag<2> * stone> {} quarter;
|
||||
inline constexpr struct long_hundredweight final : named_unit<"cwt", mag<8> * stone> {} long_hundredweight;
|
||||
inline constexpr struct ton final : named_unit<"t", mag<2'240> * pound> {} ton;
|
||||
inline constexpr auto long_ton = ton;
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -37,48 +37,44 @@ namespace mp_units::international {
|
||||
|
||||
// clang-format off
|
||||
// mass
|
||||
inline constexpr struct pound : named_unit<"lb", mag_ratio<45'359'237, 100'000'000> * si::kilogram> {} pound;
|
||||
inline constexpr struct ounce : named_unit<"oz", mag_ratio<1, 16> * pound> {} ounce;
|
||||
inline constexpr struct dram : named_unit<"dr", mag_ratio<1, 16> * ounce> {} dram;
|
||||
inline constexpr struct grain : named_unit<"gr", mag_ratio<1, 7'000> * pound> {} grain;
|
||||
inline constexpr struct pound final : named_unit<"lb", mag_ratio<45'359'237, 100'000'000> * si::kilogram> {} pound;
|
||||
inline constexpr struct ounce final : named_unit<"oz", mag_ratio<1, 16> * pound> {} ounce;
|
||||
inline constexpr struct dram final : named_unit<"dr", mag_ratio<1, 16> * ounce> {} dram;
|
||||
inline constexpr struct grain final : named_unit<"gr", mag_ratio<1, 7'000> * pound> {} grain;
|
||||
|
||||
// length
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Length
|
||||
inline constexpr struct yard : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard;
|
||||
inline constexpr struct foot : named_unit<"ft", mag_ratio<1, 3> * yard> {} foot;
|
||||
inline constexpr struct inch : named_unit<"in", mag_ratio<1, 12> * foot> {} inch;
|
||||
inline constexpr struct pica : named_unit<"P", mag_ratio<1, 6> * inch> {} pica;
|
||||
inline constexpr struct point : named_unit<"p", mag_ratio<1, 12> * pica> {} point;
|
||||
inline constexpr struct mil : named_unit<"mil", mag_ratio<1, 1'000> * inch> {} mil;
|
||||
inline constexpr struct twip : named_unit<"twip", mag_ratio<1, 20> * point> {} twip;
|
||||
inline constexpr struct mile : named_unit<"mi", mag<1760> * yard> {} mile;
|
||||
inline constexpr struct league : named_unit<"le", mag<3> * mile> {} league;
|
||||
inline constexpr struct yard final : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard;
|
||||
inline constexpr struct foot final : named_unit<"ft", mag_ratio<1, 3> * yard> {} foot;
|
||||
inline constexpr struct inch final : named_unit<"in", mag_ratio<1, 12> * foot> {} inch;
|
||||
inline constexpr struct pica final : named_unit<"P", mag_ratio<1, 6> * inch> {} pica;
|
||||
inline constexpr struct point final : named_unit<"p", mag_ratio<1, 12> * pica> {} point;
|
||||
inline constexpr struct mil final : named_unit<"mil", mag_ratio<1, 1'000> * inch> {} mil;
|
||||
inline constexpr struct twip final : named_unit<"twip", mag_ratio<1, 20> * point> {} twip;
|
||||
inline constexpr struct mile final : named_unit<"mi", mag<1760> * yard> {} mile;
|
||||
inline constexpr struct league final : named_unit<"le", mag<3> * mile> {} league;
|
||||
|
||||
inline constexpr struct nautical_mile : named_unit<"nmi", mag<1852> * si::metre> {} nautical_mile;
|
||||
inline constexpr struct nautical_mile final : named_unit<"nmi", mag<1852> * si::metre> {} nautical_mile;
|
||||
|
||||
// speed
|
||||
inline constexpr struct knot : named_unit<"kn", nautical_mile / si::hour> {} knot;
|
||||
inline constexpr struct knot final : named_unit<"kn", nautical_mile / si::hour> {} knot;
|
||||
|
||||
// force
|
||||
// https://en.wikipedia.org/wiki/Poundal
|
||||
inline constexpr struct poundal : named_unit<"pdl", pound * foot / square(si::second)> {} poundal;
|
||||
inline constexpr struct poundal final : named_unit<"pdl", pound * foot / square(si::second)> {} poundal;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Pound_(force)
|
||||
inline constexpr struct pound_force : named_unit<"lbf", pound * si::standard_gravity> {} pound_force;
|
||||
inline constexpr struct pound_force final : named_unit<"lbf", pound * si::standard_gravity> {} pound_force;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Kip_(unit),
|
||||
#if MP_UNITS_COMP_MSVC
|
||||
inline constexpr struct kip : si::kilo_<pound_force> {} kip;
|
||||
#else
|
||||
inline constexpr struct kip : decltype(si::kilo<pound_force>) {} kip;
|
||||
#endif
|
||||
inline constexpr auto kip = si::kilo<pound_force>;
|
||||
|
||||
// pressure
|
||||
inline constexpr struct psi : named_unit<"psi", pound_force / square(inch)> {} psi;
|
||||
inline constexpr struct psi final : named_unit<"psi", pound_force / square(inch)> {} psi;
|
||||
|
||||
// power
|
||||
// https://en.wikipedia.org/wiki/Horsepower#Definitions
|
||||
inline constexpr struct mechanical_horsepower : named_unit<"hp(I)", mag<33'000> * foot * pound_force / si::minute> {} mechanical_horsepower;
|
||||
inline constexpr struct mechanical_horsepower final : named_unit<"hp(I)", mag<33'000> * foot * pound_force / si::minute> {} mechanical_horsepower;
|
||||
// clang-format on
|
||||
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ namespace mp_units::isq {
|
||||
|
||||
// clang-format off
|
||||
// dimensions of base quantities
|
||||
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
|
||||
inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
|
||||
inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
|
||||
inline constexpr struct dim_electric_current : base_dimension<"I"> {} dim_electric_current;
|
||||
inline constexpr struct dim_thermodynamic_temperature : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
|
||||
inline constexpr struct dim_amount_of_substance : base_dimension<"N"> {} dim_amount_of_substance;
|
||||
inline constexpr struct dim_luminous_intensity : base_dimension<"J"> {} dim_luminous_intensity;
|
||||
inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
|
||||
inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
|
||||
inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
|
||||
inline constexpr struct dim_electric_current final : base_dimension<"I"> {} dim_electric_current;
|
||||
inline constexpr struct dim_thermodynamic_temperature final : base_dimension<symbol_text{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
|
||||
inline constexpr struct dim_amount_of_substance final : base_dimension<"N"> {} dim_amount_of_substance;
|
||||
inline constexpr struct dim_luminous_intensity final : base_dimension<"J"> {} dim_luminous_intensity;
|
||||
// clang-format on
|
||||
|
||||
// base quantities
|
||||
|
||||
@@ -38,12 +38,8 @@ namespace mp_units::natural {
|
||||
|
||||
// clang-format off
|
||||
// units
|
||||
inline constexpr struct electronvolt : named_unit<"eV"> {} electronvolt;
|
||||
#if MP_UNITS_COMP_MSVC
|
||||
inline constexpr struct gigaelectronvolt : si::giga_<electronvolt> {} gigaelectronvolt;
|
||||
#else
|
||||
inline constexpr struct gigaelectronvolt : decltype(si::giga<electronvolt>) {} gigaelectronvolt;
|
||||
#endif
|
||||
inline constexpr struct electronvolt final : named_unit<"eV"> {} electronvolt;
|
||||
inline constexpr auto gigaelectronvolt = si::giga<electronvolt>;
|
||||
|
||||
// system references
|
||||
inline constexpr struct time : system_reference<isq::time, inverse(gigaelectronvolt)> {} time;
|
||||
|
||||
@@ -85,7 +85,7 @@ struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct chrono_point_origin_ : absolute_point_origin<chrono_point_origin_<C>, isq::time> {
|
||||
struct chrono_point_origin_ final : absolute_point_origin<isq::time> {
|
||||
using clock = C;
|
||||
};
|
||||
MP_UNITS_EXPORT template<typename C>
|
||||
@@ -113,12 +113,20 @@ struct quantity_point_like_traits<std::chrono::time_point<C, std::chrono::durati
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
[[nodiscard]] constexpr auto as_ratio(Magnitude auto m)
|
||||
requires(is_rational(m))
|
||||
{
|
||||
return std::ratio<get_value<std::intmax_t>(numerator(m)), get_value<std::intmax_t>(denominator(m))>{};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<QuantityOf<isq::time> Q>
|
||||
[[nodiscard]] constexpr auto to_chrono_duration(const Q& q)
|
||||
{
|
||||
constexpr auto canonical = get_canonical_unit(Q::unit);
|
||||
constexpr detail::ratio r = detail::as_ratio(canonical.mag);
|
||||
return std::chrono::duration<typename Q::rep, std::ratio<r.num, r.den>>{q};
|
||||
return std::chrono::duration<typename Q::rep, decltype(detail::as_ratio(get_canonical_unit(Q::unit).mag))>{q};
|
||||
}
|
||||
|
||||
template<QuantityPointOf<isq::time> QP>
|
||||
@@ -127,9 +135,9 @@ template<QuantityPointOf<isq::time> QP>
|
||||
{
|
||||
using clock = MP_UNITS_TYPENAME decltype(QP::absolute_point_origin)::clock;
|
||||
using rep = MP_UNITS_TYPENAME QP::rep;
|
||||
constexpr auto canonical = get_canonical_unit(QP::unit);
|
||||
constexpr detail::ratio r = detail::as_ratio(canonical.mag);
|
||||
using ret_type = std::chrono::time_point<clock, std::chrono::duration<rep, std::ratio<r.num, r.den>>>;
|
||||
using ret_type =
|
||||
std::chrono::time_point<clock,
|
||||
std::chrono::duration<rep, decltype(detail::as_ratio(get_canonical_unit(QP::unit).mag))>>;
|
||||
return ret_type(to_chrono_duration(qp - qp.absolute_point_origin));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,28 +35,28 @@ namespace mp_units::si {
|
||||
namespace si2019 {
|
||||
|
||||
// clang-format off
|
||||
inline constexpr struct hyperfine_structure_transition_frequency_of_cs :
|
||||
inline constexpr struct hyperfine_structure_transition_frequency_of_cs final :
|
||||
named_unit<symbol_text{u8"Δν_Cs", "dv_Cs"}, mag<9'192'631'770> * hertz> {} hyperfine_structure_transition_frequency_of_cs;
|
||||
inline constexpr struct speed_of_light_in_vacuum :
|
||||
inline constexpr struct speed_of_light_in_vacuum final :
|
||||
named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
|
||||
inline constexpr struct planck_constant :
|
||||
inline constexpr struct planck_constant final :
|
||||
named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant;
|
||||
inline constexpr struct elementary_charge :
|
||||
inline constexpr struct elementary_charge final :
|
||||
named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge;
|
||||
inline constexpr struct boltzmann_constant :
|
||||
inline constexpr struct boltzmann_constant final :
|
||||
named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant;
|
||||
inline constexpr struct avogadro_constant :
|
||||
inline constexpr struct avogadro_constant final :
|
||||
named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant;
|
||||
inline constexpr struct luminous_efficacy :
|
||||
inline constexpr struct luminous_efficacy final :
|
||||
named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy;
|
||||
// clang-format on
|
||||
|
||||
} // namespace si2019
|
||||
|
||||
// clang-format off
|
||||
inline constexpr struct standard_gravity :
|
||||
inline constexpr struct standard_gravity final :
|
||||
named_unit<symbol_text{u8"g₀", "g_0"}, mag_ratio<980'665, 100'000> * metre / square(second)> {} standard_gravity;
|
||||
inline constexpr struct magnetic_constant :
|
||||
inline constexpr struct magnetic_constant final :
|
||||
named_unit<symbol_text{u8"μ₀", "u_0"}, mag<4> * mag_pi * mag_power<10, -7> * henry / metre> {} magnetic_constant;
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -31,30 +31,30 @@
|
||||
namespace mp_units::si {
|
||||
|
||||
// clang-format off
|
||||
template<PrefixableUnit U> struct quecto_ : prefixed_unit<"q", mag_power<10, -30>, U{}> {};
|
||||
template<PrefixableUnit U> struct ronto_ : prefixed_unit<"r", mag_power<10, -27>, U{}> {};
|
||||
template<PrefixableUnit U> struct yocto_ : prefixed_unit<"y", mag_power<10, -24>, U{}> {};
|
||||
template<PrefixableUnit U> struct zepto_ : prefixed_unit<"z", mag_power<10, -21>, U{}> {};
|
||||
template<PrefixableUnit U> struct atto_ : prefixed_unit<"a", mag_power<10, -18>, U{}> {};
|
||||
template<PrefixableUnit U> struct femto_ : prefixed_unit<"f", mag_power<10, -15>, U{}> {};
|
||||
template<PrefixableUnit U> struct pico_ : prefixed_unit<"p", mag_power<10, -12>, U{}> {};
|
||||
template<PrefixableUnit U> struct nano_ : prefixed_unit<"n", mag_power<10, -9>, U{}> {};
|
||||
template<PrefixableUnit U> struct micro_ : prefixed_unit<symbol_text{u8"µ", "u"}, mag_power<10, -6>, U{}> {};
|
||||
template<PrefixableUnit U> struct milli_ : prefixed_unit<"m", mag_power<10, -3>, U{}> {};
|
||||
template<PrefixableUnit U> struct centi_ : prefixed_unit<"c", mag_power<10, -2>, U{}> {};
|
||||
template<PrefixableUnit U> struct deci_ : prefixed_unit<"d", mag_power<10, -1>, U{}> {};
|
||||
template<PrefixableUnit U> struct deca_ : prefixed_unit<"da", mag_power<10, 1>, U{}> {};
|
||||
template<PrefixableUnit U> struct hecto_ : prefixed_unit<"h", mag_power<10, 2>, U{}> {};
|
||||
template<PrefixableUnit U> struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U{}> {};
|
||||
template<PrefixableUnit U> struct mega_ : prefixed_unit<"M", mag_power<10, 6>, U{}> {};
|
||||
template<PrefixableUnit U> struct giga_ : prefixed_unit<"G", mag_power<10, 9>, U{}> {};
|
||||
template<PrefixableUnit U> struct tera_ : prefixed_unit<"T", mag_power<10, 12>, U{}> {};
|
||||
template<PrefixableUnit U> struct peta_ : prefixed_unit<"P", mag_power<10, 15>, U{}> {};
|
||||
template<PrefixableUnit U> struct exa_ : prefixed_unit<"E", mag_power<10, 18>, U{}> {};
|
||||
template<PrefixableUnit U> struct zetta_ : prefixed_unit<"Z", mag_power<10, 21>, U{}> {};
|
||||
template<PrefixableUnit U> struct yotta_ : prefixed_unit<"Y", mag_power<10, 24>, U{}> {};
|
||||
template<PrefixableUnit U> struct ronna_ : prefixed_unit<"R", mag_power<10, 27>, U{}> {};
|
||||
template<PrefixableUnit U> struct quetta_ : prefixed_unit<"Q", mag_power<10, 30>, U{}> {};
|
||||
template<PrefixableUnit U> struct quecto_ final : prefixed_unit<"q", mag_power<10, -30>, U{}> {};
|
||||
template<PrefixableUnit U> struct ronto_ final : prefixed_unit<"r", mag_power<10, -27>, U{}> {};
|
||||
template<PrefixableUnit U> struct yocto_ final : prefixed_unit<"y", mag_power<10, -24>, U{}> {};
|
||||
template<PrefixableUnit U> struct zepto_ final : prefixed_unit<"z", mag_power<10, -21>, U{}> {};
|
||||
template<PrefixableUnit U> struct atto_ final : prefixed_unit<"a", mag_power<10, -18>, U{}> {};
|
||||
template<PrefixableUnit U> struct femto_ final : prefixed_unit<"f", mag_power<10, -15>, U{}> {};
|
||||
template<PrefixableUnit U> struct pico_ final : prefixed_unit<"p", mag_power<10, -12>, U{}> {};
|
||||
template<PrefixableUnit U> struct nano_ final : prefixed_unit<"n", mag_power<10, -9>, U{}> {};
|
||||
template<PrefixableUnit U> struct micro_ final : prefixed_unit<symbol_text{u8"µ", "u"}, mag_power<10, -6>, U{}> {};
|
||||
template<PrefixableUnit U> struct milli_ final : prefixed_unit<"m", mag_power<10, -3>, U{}> {};
|
||||
template<PrefixableUnit U> struct centi_ final : prefixed_unit<"c", mag_power<10, -2>, U{}> {};
|
||||
template<PrefixableUnit U> struct deci_ final : prefixed_unit<"d", mag_power<10, -1>, U{}> {};
|
||||
template<PrefixableUnit U> struct deca_ final : prefixed_unit<"da", mag_power<10, 1>, U{}> {};
|
||||
template<PrefixableUnit U> struct hecto_ final : prefixed_unit<"h", mag_power<10, 2>, U{}> {};
|
||||
template<PrefixableUnit U> struct kilo_ final : prefixed_unit<"k", mag_power<10, 3>, U{}> {};
|
||||
template<PrefixableUnit U> struct mega_ final : prefixed_unit<"M", mag_power<10, 6>, U{}> {};
|
||||
template<PrefixableUnit U> struct giga_ final : prefixed_unit<"G", mag_power<10, 9>, U{}> {};
|
||||
template<PrefixableUnit U> struct tera_ final : prefixed_unit<"T", mag_power<10, 12>, U{}> {};
|
||||
template<PrefixableUnit U> struct peta_ final : prefixed_unit<"P", mag_power<10, 15>, U{}> {};
|
||||
template<PrefixableUnit U> struct exa_ final : prefixed_unit<"E", mag_power<10, 18>, U{}> {};
|
||||
template<PrefixableUnit U> struct zetta_ final : prefixed_unit<"Z", mag_power<10, 21>, U{}> {};
|
||||
template<PrefixableUnit U> struct yotta_ final : prefixed_unit<"Y", mag_power<10, 24>, U{}> {};
|
||||
template<PrefixableUnit U> struct ronna_ final : prefixed_unit<"R", mag_power<10, 27>, U{}> {};
|
||||
template<PrefixableUnit U> struct quetta_ final : prefixed_unit<"Q", mag_power<10, 30>, U{}> {};
|
||||
|
||||
MP_UNITS_EXPORT_BEGIN
|
||||
|
||||
|
||||
@@ -38,59 +38,55 @@ namespace si {
|
||||
|
||||
// clang-format off
|
||||
// base units
|
||||
inline constexpr struct second : named_unit<"s", kind_of<isq::time>> {} second;
|
||||
inline constexpr struct metre : named_unit<"m", kind_of<isq::length>> {} metre;
|
||||
inline constexpr struct gram : named_unit<"g", kind_of<isq::mass>> {} gram;
|
||||
#if MP_UNITS_COMP_MSVC
|
||||
inline constexpr struct kilogram : kilo_<gram> {} kilogram;
|
||||
#else
|
||||
inline constexpr struct kilogram : decltype(kilo<gram>) {} kilogram;
|
||||
#endif
|
||||
inline constexpr struct ampere : named_unit<"A", kind_of<isq::electric_current>> {} ampere;
|
||||
inline constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
|
||||
inline constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
|
||||
inline constexpr struct gram final : named_unit<"g", kind_of<isq::mass>> {} gram;
|
||||
inline constexpr auto kilogram = kilo<gram>;
|
||||
inline constexpr struct ampere final : named_unit<"A", kind_of<isq::electric_current>> {} ampere;
|
||||
|
||||
inline constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
|
||||
inline constexpr struct kelvin : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
|
||||
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline constexpr auto zeroth_kelvin = absolute_zero;
|
||||
inline constexpr struct kelvin final : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
|
||||
|
||||
inline constexpr struct mole : named_unit<"mol", kind_of<isq::amount_of_substance>> {} mole;
|
||||
inline constexpr struct candela : named_unit<"cd", kind_of<isq::luminous_intensity>> {} candela;
|
||||
inline constexpr struct mole final : named_unit<"mol", kind_of<isq::amount_of_substance>> {} mole;
|
||||
inline constexpr struct candela final : named_unit<"cd", kind_of<isq::luminous_intensity>> {} candela;
|
||||
|
||||
// derived named units
|
||||
inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
|
||||
inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
|
||||
inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
|
||||
inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
inline constexpr struct radian final : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
|
||||
inline constexpr struct steradian final : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
|
||||
inline constexpr struct hertz final : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
|
||||
inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
#ifdef pascal
|
||||
#pragma push_macro("pascal")
|
||||
#undef pascal
|
||||
#define MP_UNITS_REDEFINE_PASCAL
|
||||
#endif
|
||||
inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal;
|
||||
inline constexpr struct pascal final : named_unit<"Pa", newton / square(metre)> {} pascal;
|
||||
#ifdef MP_UNITS_REDEFINE_PASCAL
|
||||
#pragma pop_macro("pascal")
|
||||
#undef MP_UNITS_REDEFINE_PASCAL
|
||||
#endif
|
||||
inline constexpr struct joule : named_unit<"J", newton * metre> {} joule;
|
||||
inline constexpr struct watt : named_unit<"W", joule / second> {} watt;
|
||||
inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb;
|
||||
inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt;
|
||||
inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad;
|
||||
inline constexpr struct ohm : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
|
||||
inline constexpr struct siemens : named_unit<"S", one / ohm> {} siemens;
|
||||
inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber;
|
||||
inline constexpr struct tesla : named_unit<"T", weber / square(metre)> {} tesla;
|
||||
inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry;
|
||||
inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
|
||||
inline constexpr struct watt final : named_unit<"W", joule / second> {} watt;
|
||||
inline constexpr struct coulomb final : named_unit<"C", ampere * second> {} coulomb;
|
||||
inline constexpr struct volt final : named_unit<"V", watt / ampere> {} volt;
|
||||
inline constexpr struct farad final : named_unit<"F", coulomb / volt> {} farad;
|
||||
inline constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
|
||||
inline constexpr struct siemens final : named_unit<"S", one / ohm> {} siemens;
|
||||
inline constexpr struct weber final : named_unit<"Wb", volt * second> {} weber;
|
||||
inline constexpr struct tesla final : named_unit<"T", weber / square(metre)> {} tesla;
|
||||
inline constexpr struct henry final : named_unit<"H", weber / ampere> {} henry;
|
||||
|
||||
inline constexpr struct ice_point : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
|
||||
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
|
||||
inline constexpr struct degree_Celsius : named_unit<symbol_text{u8"°C", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
|
||||
inline constexpr struct ice_point final : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
|
||||
inline constexpr auto zeroth_degree_Celsius = ice_point;
|
||||
inline constexpr struct degree_Celsius final : named_unit<symbol_text{u8"°C", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
|
||||
|
||||
inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen;
|
||||
inline constexpr struct lux : named_unit<"lx", lumen / square(metre)> {} lux;
|
||||
inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
|
||||
inline constexpr struct gray : named_unit<"Gy", joule / kilogram, kind_of<isq::absorbed_dose>> {} gray;
|
||||
inline constexpr struct sievert : named_unit<"Sv", joule / kilogram, kind_of<isq::dose_equivalent>> {} sievert;
|
||||
inline constexpr struct katal : named_unit<"kat", mole / second> {} katal;
|
||||
inline constexpr struct lumen final : named_unit<"lm", candela * steradian> {} lumen;
|
||||
inline constexpr struct lux final : named_unit<"lx", lumen / square(metre)> {} lux;
|
||||
inline constexpr struct becquerel final : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
|
||||
inline constexpr struct gray final : named_unit<"Gy", joule / kilogram, kind_of<isq::absorbed_dose>> {} gray;
|
||||
inline constexpr struct sievert final : named_unit<"Sv", joule / kilogram, kind_of<isq::dose_equivalent>> {} sievert;
|
||||
inline constexpr struct katal final : named_unit<"kat", mole / second> {} katal;
|
||||
// clang-format on
|
||||
|
||||
} // namespace si
|
||||
@@ -99,24 +95,20 @@ namespace non_si {
|
||||
|
||||
// clang-format off
|
||||
// non-SI units accepted for use with the SI
|
||||
inline constexpr struct minute : named_unit<"min", mag<60> * si::second> {} minute;
|
||||
inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour;
|
||||
inline constexpr struct day : named_unit<"d", mag<24> * hour> {} day;
|
||||
inline constexpr struct astronomical_unit : named_unit<"au", mag<149'597'870'700> * si::metre> {} astronomical_unit;
|
||||
inline constexpr struct degree : named_unit<symbol_text{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
|
||||
inline constexpr struct arcminute : named_unit<symbol_text{u8"′", "'"}, mag_ratio<1, 60> * degree> {} arcminute;
|
||||
inline constexpr struct arcsecond : named_unit<symbol_text{u8"″", "''"}, mag_ratio<1, 60> * arcminute> {} arcsecond;
|
||||
inline constexpr struct are : named_unit<"a", square(si::deca<si::metre>)> {} are;
|
||||
#if MP_UNITS_COMP_MSVC
|
||||
inline constexpr struct hectare : si::hecto_<are> {} hectare;
|
||||
#else
|
||||
inline constexpr struct hectare : decltype(si::hecto<are>) {} hectare;
|
||||
#endif
|
||||
inline constexpr struct litre : named_unit<"l", cubic(si::deci<si::metre>)> {} litre;
|
||||
inline constexpr struct tonne : named_unit<"t", mag<1000> * si::kilogram> {} tonne;
|
||||
inline constexpr struct dalton : named_unit<"Da", mag_ratio<16'605'390'666'050, 10'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} dalton;
|
||||
inline constexpr struct minute final : named_unit<"min", mag<60> * si::second> {} minute;
|
||||
inline constexpr struct hour final : named_unit<"h", mag<60> * minute> {} hour;
|
||||
inline constexpr struct day final : named_unit<"d", mag<24> * hour> {} day;
|
||||
inline constexpr struct astronomical_unit final : named_unit<"au", mag<149'597'870'700> * si::metre> {} astronomical_unit;
|
||||
inline constexpr struct degree final : named_unit<symbol_text{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
|
||||
inline constexpr struct arcminute final : named_unit<symbol_text{u8"′", "'"}, mag_ratio<1, 60> * degree> {} arcminute;
|
||||
inline constexpr struct arcsecond final : named_unit<symbol_text{u8"″", "''"}, mag_ratio<1, 60> * arcminute> {} arcsecond;
|
||||
inline constexpr struct are final : named_unit<"a", square(si::deca<si::metre>)> {} are;
|
||||
inline constexpr auto hectare = si::hecto<are>;
|
||||
inline constexpr struct litre final : named_unit<"l", cubic(si::deci<si::metre>)> {} litre;
|
||||
inline constexpr struct tonne final : named_unit<"t", mag<1000> * si::kilogram> {} tonne;
|
||||
inline constexpr struct dalton final : named_unit<"Da", mag_ratio<16'605'390'666'050, 10'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} dalton;
|
||||
// TODO A different value is provided in the SI Brochure and different in the ISO 80000
|
||||
inline constexpr struct electronvolt : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt;
|
||||
inline constexpr struct electronvolt final : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt;
|
||||
// TODO the below are logarithmic units - how to support those?
|
||||
// neper
|
||||
// bel
|
||||
|
||||
@@ -36,11 +36,11 @@ namespace mp_units::typographic {
|
||||
|
||||
// clang-format off
|
||||
// https://en.wikipedia.org/wiki/Point_(typography)
|
||||
inline constexpr struct pica_us : named_unit<"pica(us)", mag_ratio<166'044, 1'000'000> * international::inch> {} pica_us;
|
||||
inline constexpr struct point_us : named_unit<"point(us)", mag_ratio<1, 12> * pica_us> {} point_us;
|
||||
inline constexpr struct pica_us final : named_unit<"pica(us)", mag_ratio<166'044, 1'000'000> * international::inch> {} pica_us;
|
||||
inline constexpr struct point_us final : named_unit<"point(us)", mag_ratio<1, 12> * pica_us> {} point_us;
|
||||
|
||||
inline constexpr struct point_dtp : named_unit<"point(dtp)", mag_ratio<1, 72> * international::inch> {} point_dtp;
|
||||
inline constexpr struct pica_dtp : named_unit<"pica(dtp)", mag<12> * point_dtp> {} pica_dtp;
|
||||
inline constexpr struct point_dtp final : named_unit<"point(dtp)", mag_ratio<1, 72> * international::inch> {} point_dtp;
|
||||
inline constexpr struct pica_dtp final : named_unit<"pica(dtp)", mag<12> * point_dtp> {} pica_dtp;
|
||||
// clang-format on
|
||||
|
||||
} // namespace mp_units::typographic
|
||||
@@ -41,12 +41,12 @@ using namespace international;
|
||||
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Length
|
||||
// nautical
|
||||
inline constexpr struct fathom : named_unit<"ftm(us)", mag<2> * yard> {} fathom;
|
||||
inline constexpr struct cable : named_unit<"cb(us)", mag<120> * fathom> {} cable;
|
||||
inline constexpr struct fathom final : named_unit<"ftm(us)", mag<2> * yard> {} fathom;
|
||||
inline constexpr struct cable final : named_unit<"cb(us)", mag<120> * fathom> {} cable;
|
||||
|
||||
// survey
|
||||
struct us_survey_foot : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {};
|
||||
struct us_survey_mile : named_unit<"mi(us)", mag<5280> * us_survey_foot{}> {};
|
||||
struct us_survey_foot final : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {};
|
||||
struct us_survey_mile final : named_unit<"mi(us)", mag<5280> * us_survey_foot{}> {};
|
||||
|
||||
[[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]]
|
||||
inline constexpr us_survey_foot us_survey_foot;
|
||||
@@ -54,72 +54,72 @@ inline constexpr us_survey_foot us_survey_foot;
|
||||
[[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]]
|
||||
inline constexpr us_survey_mile us_survey_mile;
|
||||
|
||||
inline constexpr struct link : named_unit<"li", mag_ratio<33, 50> * foot> {} link;
|
||||
inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod;
|
||||
inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain;
|
||||
inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
inline constexpr struct link final : named_unit<"li", mag_ratio<33, 50> * foot> {} link;
|
||||
inline constexpr struct rod final : named_unit<"rd", mag<25> * link> {} rod;
|
||||
inline constexpr struct chain final : named_unit<"ch", mag<4> * rod> {} chain;
|
||||
inline constexpr struct furlong final : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
// clang-format on
|
||||
|
||||
namespace survey1893 {
|
||||
|
||||
// clang-format off
|
||||
inline constexpr struct us_survey_foot : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {} us_survey_foot;
|
||||
inline constexpr struct link : named_unit<"li", mag_ratio<33, 50> * us_survey_foot> {} link;
|
||||
inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod;
|
||||
inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain;
|
||||
inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
inline constexpr struct us_survey_mile : named_unit<"mi(us)", mag<8> * furlong> {} us_survey_mile;
|
||||
inline constexpr struct league : named_unit<"lea", mag<3> * us_survey_mile> {} league;
|
||||
inline constexpr struct us_survey_foot final : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {} us_survey_foot;
|
||||
inline constexpr struct link final : named_unit<"li", mag_ratio<33, 50> * us_survey_foot> {} link;
|
||||
inline constexpr struct rod final : named_unit<"rd", mag<25> * link> {} rod;
|
||||
inline constexpr struct chain final : named_unit<"ch", mag<4> * rod> {} chain;
|
||||
inline constexpr struct furlong final : named_unit<"fur", mag<10> * chain> {} furlong;
|
||||
inline constexpr struct us_survey_mile final : named_unit<"mi(us)", mag<8> * furlong> {} us_survey_mile;
|
||||
inline constexpr struct league final : named_unit<"lea", mag<3> * us_survey_mile> {} league;
|
||||
// clang-format on
|
||||
|
||||
} // namespace survey1893
|
||||
|
||||
// clang-format off
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Area
|
||||
inline constexpr struct acre : named_unit<"acre", mag<10> * square(survey1893::chain)> {} acre;
|
||||
inline constexpr struct section : named_unit<"section", mag<640> * acre> {} section;
|
||||
inline constexpr struct acre final : named_unit<"acre", mag<10> * square(survey1893::chain)> {} acre;
|
||||
inline constexpr struct section final : named_unit<"section", mag<640> * acre> {} section;
|
||||
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Fluid_volume
|
||||
inline constexpr struct gallon : named_unit<"gal", mag<231> * cubic(inch)> {} gallon;
|
||||
inline constexpr struct pottle : named_unit<"pot", mag_ratio<1, 2> * gallon> {} pottle;
|
||||
inline constexpr struct quart : named_unit<"qt", mag_ratio<1, 2> * pottle> {} quart;
|
||||
inline constexpr struct pint : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint;
|
||||
inline constexpr struct cup : named_unit<"c", mag_ratio<1, 2> * pint> {} cup;
|
||||
inline constexpr struct gill : named_unit<"gi", mag_ratio<1, 2> * cup> {} gill;
|
||||
inline constexpr struct fluid_ounce : named_unit<"fl oz", mag_ratio<1, 4> * gill> {} fluid_ounce;
|
||||
inline constexpr struct tablespoon : named_unit<"tbsp", mag_ratio<1, 2> * fluid_ounce> {} tablespoon;
|
||||
inline constexpr struct shot : named_unit<"jig", mag<3> * tablespoon> {} shot;
|
||||
inline constexpr struct teaspoon : named_unit<"tsp", mag_ratio<1, 3> * tablespoon> {} teaspoon;
|
||||
inline constexpr struct minim : named_unit<"min", mag_ratio<1, 80> * teaspoon> {} minim;
|
||||
inline constexpr struct fluid_dram : named_unit<"fl dr", mag<60> * minim> {} fluid_dram;
|
||||
inline constexpr struct barrel : named_unit<"bbl", mag_ratio<315, 10> * gallon> {} barrel;
|
||||
inline constexpr struct oil_barrel : named_unit<"bbl", mag_ratio<4, 3> * barrel> {} oil_barrel;
|
||||
inline constexpr struct hogshead : decltype(mag<63> * gallon) {} hogshead;
|
||||
inline constexpr struct gallon final : named_unit<"gal", mag<231> * cubic(inch)> {} gallon;
|
||||
inline constexpr struct pottle final : named_unit<"pot", mag_ratio<1, 2> * gallon> {} pottle;
|
||||
inline constexpr struct quart final : named_unit<"qt", mag_ratio<1, 2> * pottle> {} quart;
|
||||
inline constexpr struct pint final : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint;
|
||||
inline constexpr struct cup final : named_unit<"c", mag_ratio<1, 2> * pint> {} cup;
|
||||
inline constexpr struct gill final : named_unit<"gi", mag_ratio<1, 2> * cup> {} gill;
|
||||
inline constexpr struct fluid_ounce final : named_unit<"fl oz", mag_ratio<1, 4> * gill> {} fluid_ounce;
|
||||
inline constexpr struct tablespoon final : named_unit<"tbsp", mag_ratio<1, 2> * fluid_ounce> {} tablespoon;
|
||||
inline constexpr struct shot final : named_unit<"jig", mag<3> * tablespoon> {} shot;
|
||||
inline constexpr struct teaspoon final : named_unit<"tsp", mag_ratio<1, 3> * tablespoon> {} teaspoon;
|
||||
inline constexpr struct minim final : named_unit<"min", mag_ratio<1, 80> * teaspoon> {} minim;
|
||||
inline constexpr struct fluid_dram final : named_unit<"fl dr", mag<60> * minim> {} fluid_dram;
|
||||
inline constexpr struct barrel final : named_unit<"bbl", mag_ratio<315, 10> * gallon> {} barrel;
|
||||
inline constexpr struct oil_barrel final : named_unit<"bbl", mag_ratio<4, 3> * barrel> {} oil_barrel;
|
||||
inline constexpr struct hogshead final : named_unit<"hogshead", mag<63> * gallon> {} hogshead;
|
||||
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Dry_volume
|
||||
inline constexpr struct dry_barrel : named_unit<"bbl", mag<7056> * cubic(inch)> {} dry_barrel;
|
||||
inline constexpr struct bushel : named_unit<"bu", mag_ratio<3'523'907'016'688, 100'000'000'000> * si::litre> {} bushel;
|
||||
inline constexpr struct peck : named_unit<"pk", mag_ratio<1, 4> * bushel> {} peck;
|
||||
inline constexpr struct dry_gallon : named_unit<"gal", mag_ratio<1, 2> * peck> {} dry_gallon;
|
||||
inline constexpr struct dry_quart : named_unit<"qt", mag_ratio<1, 4> * dry_gallon> {} dry_quart;
|
||||
inline constexpr struct dry_pint : named_unit<"pt", mag_ratio<1, 2> * dry_quart> {} dry_pint;
|
||||
inline constexpr struct dry_barrel final : named_unit<"bbl", mag<7056> * cubic(inch)> {} dry_barrel;
|
||||
inline constexpr struct bushel final : named_unit<"bu", mag_ratio<3'523'907'016'688, 100'000'000'000> * si::litre> {} bushel;
|
||||
inline constexpr struct peck final : named_unit<"pk", mag_ratio<1, 4> * bushel> {} peck;
|
||||
inline constexpr struct dry_gallon final : named_unit<"gal", mag_ratio<1, 2> * peck> {} dry_gallon;
|
||||
inline constexpr struct dry_quart final : named_unit<"qt", mag_ratio<1, 4> * dry_gallon> {} dry_quart;
|
||||
inline constexpr struct dry_pint final : named_unit<"pt", mag_ratio<1, 2> * dry_quart> {} dry_pint;
|
||||
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Mass_and_Weight
|
||||
// https://en.wikipedia.org/wiki/Avoirdupois_system#American_customary_system
|
||||
inline constexpr struct quarter : named_unit<"qr", mag<25> * pound> {} quarter;
|
||||
inline constexpr struct short_hundredweight : named_unit<"cwt", mag<100> * pound> {} short_hundredweight;
|
||||
inline constexpr struct ton : named_unit<"t", mag<2'000> * pound> {} ton;
|
||||
inline constexpr struct quarter final : named_unit<"qr", mag<25> * pound> {} quarter;
|
||||
inline constexpr struct short_hundredweight final : named_unit<"cwt", mag<100> * pound> {} short_hundredweight;
|
||||
inline constexpr struct ton final : named_unit<"t", mag<2'000> * pound> {} ton;
|
||||
inline constexpr auto short_ton = ton;
|
||||
inline constexpr struct pennyweight : named_unit<"dwt", mag<24> * grain> {} pennyweight;
|
||||
inline constexpr struct troy_once : named_unit<"oz t", mag<20> * pennyweight> {} troy_once;
|
||||
inline constexpr struct troy_pound : named_unit<"lb t", mag<12> * troy_once> {} troy_pound;
|
||||
inline constexpr struct pennyweight final : named_unit<"dwt", mag<24> * grain> {} pennyweight;
|
||||
inline constexpr struct troy_once final : named_unit<"oz t", mag<20> * pennyweight> {} troy_once;
|
||||
inline constexpr struct troy_pound final : named_unit<"lb t", mag<12> * troy_once> {} troy_pound;
|
||||
|
||||
// https://en.wikipedia.org/wiki/Inch_of_mercury
|
||||
inline constexpr struct inch_of_mercury : named_unit<"inHg", mag_ratio<3'386'389, 1'000> * si::pascal> {} inch_of_mercury;
|
||||
inline constexpr struct inch_of_mercury final : named_unit<"inHg", mag_ratio<3'386'389, 1'000> * si::pascal> {} inch_of_mercury;
|
||||
|
||||
// https://en.wikipedia.org/wiki/United_States_customary_units#Temperature
|
||||
inline constexpr struct zeroth_degree_Fahrenheit : relative_point_origin<quantity_point{-32 * (mag_ratio<5, 9> * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit;
|
||||
inline constexpr struct degree_Fahrenheit : named_unit<symbol_text{u8"°F", "`F"}, mag_ratio<5, 9> * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit;
|
||||
inline constexpr struct zeroth_degree_Fahrenheit final : relative_point_origin<quantity_point{-32 * (mag_ratio<5, 9> * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit;
|
||||
inline constexpr struct degree_Fahrenheit final : named_unit<symbol_text{u8"°F", "`F"}, mag_ratio<5, 9> * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit;
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
// 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.
|
||||
|
||||
module;
|
||||
|
||||
#include <mp-units/bits/core_gmf.h>
|
||||
|
||||
Reference in new issue
Block a user