Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
units_conversion_traits.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_UNITS_CONVERSION_TRAITS_HPP_
5#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_UNITS_CONVERSION_TRAITS_HPP_
6
7#include "arene/base/constraints/constraints.hpp"
8#include "arene/base/stdlib_choice/enable_if.hpp"
9#include "arene/base/stdlib_choice/is_same.hpp"
10#include "arene/base/stdlib_choice/ratio.hpp"
11#include "arene/base/type_list/apply_all.hpp"
12#include "arene/base/units/base_kind_set.hpp"
13#include "arene/base/units/combine_kinds.hpp"
14#include "arene/base/units/explicit_base_set.hpp"
15#include "arene/base/units/is_base_quantity_kind.hpp"
16#include "arene/base/units/is_explicit.hpp"
17#include "arene/base/units/is_implicit.hpp"
18#include "arene/base/units/is_quantity_kind.hpp"
19
20namespace arene {
21namespace base {
22namespace units_conversion_traits_detail {
23
24/// @brief determine if a quantity kind type is explicit and has an implicit parent
25/// @tparam Kind quantity kind type
26template <typename Kind, typename = constraints<>>
27extern constexpr bool is_explicit_with_implicit_parent_v = false;
28
29/// @brief determine if a quantity kind type is explicit and has an implicit parent
30/// @tparam Kind quantity kind type
31template <typename Kind>
32extern constexpr bool is_explicit_with_implicit_parent_v<
33 Kind,
34 constraints<
35 std::enable_if_t<units_detail::is_explicit_v<Kind>>,
36 std::enable_if_t<units_detail::is_implicit_v<typename Kind::parent_quantity_kind_type>>>> = true;
37
38/// @brief determine if a type provides a @c scale_factor typedef
39/// @tparam Type type
40template <typename Type, typename = constraints<>>
41extern constexpr bool has_scale_factor_v = false;
42
43/// @brief determine if a type provides a @c scale_factor typedef
44/// @tparam Type type
45template <typename Type>
46extern constexpr bool has_scale_factor_v<Type, constraints<typename Type::scale_factor>> = true;
47
48/// @brief Determine if the quantity type can be implicitly converted
49/// @tparam From the source type of the unit being impliclty converted
50/// @tparam To the destination type of the unit being implicitly converted
51///
52/// This primary template defines @c From to *not* be implicitly convertible to @c To
53template <typename From, typename To, typename = constraints<>>
54class units_conversion_traits_impl {
55 public:
56 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
57 // exposed as part of the API"
58 /// @brief Boolean value that is @c true if these types "compatible" such that quantities with type @c From can be
59 /// implicitly converted to quantities of type @c To, @c false otherwise.
60 static constexpr bool compatible{false};
61 // parasoft-end-suppress AUTOSAR-M11_0_1-a
62};
63
64/// @brief Determine if the quantity type can be implicitly converted
65/// @tparam From the source and destination type of the unit being impliclty converted
66///
67/// This specialization allows a type to always be compatible with the same type.
68template <typename From>
69class units_conversion_traits_impl<From, From, constraints<std::enable_if_t<!is_quantity_kind_v<From>>>> {
70 public:
71 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
72 // exposed as part of the API"
73 /// @brief Boolean value that is @c true to indicate that a type can be "converted" to itself
74 static constexpr bool compatible{true};
75 // parasoft-end-suppress AUTOSAR-M11_0_1-a
76
77 /// @brief The scale factor to use when converting a type to itself: no scaling
78 using scale_factor = std::ratio<1, 1>;
79};
80
81/// @brief obtain the destination base set
82/// @tparam Kind quantity kind type
83template <typename Kind, typename = constraints<>>
84struct destination_base_set {
85 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
86 // exposed as part of the API"
87 // parasoft-begin-suppress AUTOSAR-A3_3_2-a "False positive: variable 'value' is initialized"
88 // parasoft-begin-suppress CERT_CPP-DCL56-a "False positive: variable 'value' is initialized"
89 /// @brief destination explicit base set
90 static constexpr auto value = units_detail::explicit_base_set<Kind>;
91 // parasoft-end-suppress AUTOSAR-A3_3_2-a
92 // parasoft-end-suppress CERT_CPP-DCL56-a
93 // parasoft-end-suppress AUTOSAR-M11_0_1-a
94};
95
96/// @brief obtain the destination base set
97/// @tparam Kind quantity kind type
98template <typename Kind>
99struct destination_base_set<Kind, constraints<std::enable_if_t<is_explicit_with_implicit_parent_v<Kind>>>> {
100 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
101 // exposed as part of the API"
102 // parasoft-begin-suppress AUTOSAR-A3_3_2-a "False positive: variable 'value' is initialized"
103 // parasoft-begin-suppress CERT_CPP-DCL56-a "False positive: variable 'value' is initialized"
104 /// @brief destination explicit base set
105 static constexpr auto value = units_detail::explicit_base_set<typename Kind::parent_quantity_kind_type>;
106 // parasoft-end-suppress AUTOSAR-A3_3_2-a
107 // parasoft-end-suppress CERT_CPP-DCL56-a
108 // parasoft-end-suppress AUTOSAR-M11_0_1-a
109};
110
111/// @brief Determine if the quantity type can be implicitly converted
112/// @tparam From the source type of the unit being impliclty converted
113/// @tparam To the destination type of the unit being implicitly converted
114///
115/// This specialization allows a quantity to be compatible with another quantity
116/// if the quantity kind base sets of @c From and @c To are compatible.
117///
118/// @note This specialization only applies if both quantity kind types do *not*
119/// explicitly specify a @c scale_factor typedef.
120template <typename From, typename To>
121class units_conversion_traits_impl<
122 From,
123 To,
124 constraints<
125 std::enable_if_t<is_quantity_kind_v<From>>,
126 std::enable_if_t<is_quantity_kind_v<To>>,
127 std::enable_if_t<!has_scale_factor_v<From>>,
128 std::enable_if_t<!has_scale_factor_v<To>>>> {
129 /// @brief defines the source explicit base set
130 struct source_set {
131 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
132 // exposed as part of the API"
133 // parasoft-begin-suppress AUTOSAR-A3_3_2-a "False positive: variable 'value' is initialized"
134 // parasoft-begin-suppress CERT_CPP-DCL56-a "False positive: variable 'value' is initialized"
135 /// @brief source explicit base set
136 static constexpr auto value = units_detail::explicit_base_set<From>;
137 // parasoft-end-suppress AUTOSAR-A3_3_2-a
138 // parasoft-end-suppress CERT_CPP-DCL56-a
139 // parasoft-end-suppress AUTOSAR-M11_0_1-a
140 };
141
142 /// @brief source explicit base set converted to an implicit combined quantity kind
143 using lifted_source_set =
144 type_lists::apply_all_t<units_detail::as_list_of_kinds_with_exponents_t<source_set>, combine_kinds_t>;
145 /// @brief dest explicit base set converted to an implicit combined quantity kind
146 using lifted_dest_set = type_lists::
147 apply_all_t<units_detail::as_list_of_kinds_with_exponents_t<destination_base_set<To>>, combine_kinds_t>;
148
149 public:
150 /// @brief indicates if @c From and @c To are compatible quantity kind types
151 ///
152 /// Boolean value that is @c true to indicate that the explicit bases
153 /// of @c From is a relaxation of the @c Ed, where :
154 /// * if @c To is an explicit quantity kind and
155 /// @c To::parent_quantity_kind_type is an implicit quantity kind,
156 /// @c Ed is the explicit base set of @c To::parent_quantity_kind_type
157 /// * otherwise, @c Ed is the explicit base set of @c To.
158 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "False positive: this is not 'member data', it is a public property,
159 // exposed as part of the API"
160 // parasoft-begin-suppress CERT_CPP-DCL56-a "False positive: variable 'compatible' is initialized"
161 static constexpr bool
162 compatible{std::is_same<lifted_source_set, lifted_dest_set>::value || is_base_quantity_kind_of_v<lifted_dest_set, lifted_source_set>};
163 // parasoft-end-suppress CERT_CPP-DCL56-a
164 // parasoft-end-suppress AUTOSAR-M11_0_1-a
165
166 /// @brief The scale factor to use when converting quantity kind types without explicit scaling factors
167 using scale_factor = std::ratio<1, 1>;
168};
169
170} // namespace units_conversion_traits_detail
171
172/// @brief Traits class with information about if and how a physical unit of type @c From can be converted to a physical
173/// unit of type @c To.
174///
175/// The physical unit types themselves are just tags used for the @c quantity class template rather than holding any
176/// values directly.
177///
178/// @tparam From the tag type of the unit being converted from
179/// @tparam To the tag type of the unit being converted to
180template <typename From, typename To>
182
183} // namespace base
184} // namespace arene
185
186#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_UNITS_CONVERSION_TRAITS_HPP_
Traits class with information about if and how a physical unit of type From can be converted to a phy...
Definition units_conversion_traits.hpp:181
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10