Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
kind_with_exponent.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_KIND_WITH_EXPONENT_HPP_
5#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_KIND_WITH_EXPONENT_HPP_
6
7#include "arene/base/constraints/constraints.hpp" // IWYU pragma: keep
8#include "arene/base/stdlib_choice/enable_if.hpp"
9#include "arene/base/stdlib_choice/remove_cv.hpp"
10#include "arene/base/units/has_explicit_units.hpp"
11#include "arene/base/units/has_parent_kind.hpp"
12#include "arene/base/units/is_unit.hpp"
13#include "arene/base/units/kind_with_exponent_fwd.hpp" // IWYU pragma: keep
14#include "arene/base/units/quantity_kind.hpp"
15#include "arene/base/units/quantity_unit.hpp"
16#include "arene/base/units/selected_unit_for.hpp"
17
18namespace arene {
19namespace base {
20
21namespace units_detail {
22
23/// @brief Helper class to determine the result of raising the specified quantity kind to the specified positive and
24/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
25/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
26/// s/s or @c m^2/m^2
27/// @tparam Kind The quantity kind to raise to an exponent
28/// @tparam PositiveExponent The positive exponent to raise it to
29/// @tparam NegativeExponent The negative exponent to raise it to
30template <
31 typename Kind,
32 exponent_t PositiveExponent,
33 exponent_t NegativeExponent,
34 typename /* constraints, defaulted on forward declaration */>
35class kind_with_exponent_helper {
36 static_assert(PositiveExponent >= 0, "The exponents must be non-negative");
37 static_assert(NegativeExponent >= 0, "The exponents must be non-negative");
38
39 public:
40 /// @brief An alias for a quantity kind representing @c Kind raised to the positive and negative exponents
41 using type = quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>;
42};
43
44// parasoft-begin-suppress AUTOSAR-A14_7_2-a "False positive: The primary template is defined in this file"
45/// @brief Helper class to determine the result of raising the specified quantity kind to the specified positive and
46/// negative exponents. This specialization is for when the positive exponent is 1 and the negative exponent is zero
47/// @tparam Kind The quantity kind to raise to an exponent of 1
48template <typename Kind>
49class kind_with_exponent_helper<Kind, 1, 0> {
50 public:
51 /// @brief An alias for @c Kind
52 using type = Kind;
53};
54// parasoft-end-suppress AUTOSAR-A14_7_2-a
55
56// parasoft-begin-suppress AUTOSAR-A14_7_2-a "The primary template is forward declared to avoid circular dependencies"
57/// @brief Implementation class for a quantity kind raised to the specified positive and
58/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
59/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
60/// s/s or @c m^2/m^2
61/// @tparam Kind The quantity kind to raise to an exponent
62/// @tparam PositiveExponent The positive exponent to raise it to
63/// @tparam NegativeExponent The negative exponent to raise it to
64template <typename Kind, exponent_t PositiveExponent, exponent_t NegativeExponent>
65class quantity_kind_with_exponent<
66 Kind,
67 PositiveExponent,
68 NegativeExponent,
69 constraints<std::enable_if_t<!has_parent_kind_v<Kind>>, std::enable_if_t<!has_explicit_units_v<Kind>>>>
70 : public quantity_kind<quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>> {
71 public:
72 /// @brief Denotes that quantity kind is implicit and does not mark a
73 /// boundary when aggregating and simplifying quantity kind types.
74 using is_implicit = void;
75};
76// parasoft-end-suppress AUTOSAR-A14_7_2-a
77
78// parasoft-begin-suppress AUTOSAR-A14_7_2-a "The primary template is forward declared to avoid circular dependencies"
79/// @brief Implementation class for a quantity kind raised to the specified positive and
80/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
81/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
82/// s/s or @c m^2/m^2
83/// @tparam Kind The quantity kind to raise to an exponent
84/// @tparam PositiveExponent The positive exponent to raise it to
85/// @tparam NegativeExponent The negative exponent to raise it to
86template <typename Kind, exponent_t PositiveExponent, exponent_t NegativeExponent>
87class quantity_kind_with_exponent<
88 Kind,
89 PositiveExponent,
90 NegativeExponent,
91 constraints<std::enable_if_t<is_unit_v<Kind>>>>
92 : public quantity_unit<
93 quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>,
94 typename kind_with_exponent_helper<
95 typename Kind::parent_quantity_kind_type,
96 PositiveExponent,
97 NegativeExponent>::type> {
98 public:
99 /// @brief Denotes that quantity kind is implicit and does not mark a
100 /// boundary when aggregating and simplifying quantity kind types.
101 using is_implicit = void;
102};
103// parasoft-end-suppress AUTOSAR-A14_7_2-a
104
105// parasoft-begin-suppress AUTOSAR-A14_7_2-a "The primary template is forward declared to avoid circular dependencies"
106/// @brief Implementation class for a quantity kind raised to the specified positive and
107/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
108/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
109/// s/s or @c m^2/m^2
110/// @tparam Kind The quantity kind to raise to an exponent
111/// @tparam PositiveExponent The positive exponent to raise it to
112/// @tparam NegativeExponent The negative exponent to raise it to
113template <typename Kind, exponent_t PositiveExponent, exponent_t NegativeExponent>
114class quantity_kind_with_exponent<
115 Kind,
116 PositiveExponent,
117 NegativeExponent,
118 constraints<
119 std::enable_if_t<!is_unit_v<Kind>>,
120 std::enable_if_t<has_parent_kind_v<Kind>>,
121 std::enable_if_t<!has_explicit_units_v<Kind>>>>
122 : public quantity_kind<
123 quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>,
124 typename kind_with_exponent_helper<
125 typename Kind::parent_quantity_kind_type,
126 PositiveExponent,
127 NegativeExponent>::type> {
128 public:
129 /// @brief Denotes that quantity kind is implicit and does not mark a
130 /// boundary when aggregating and simplifying quantity kind types.
131 using is_implicit = void;
132};
133// parasoft-end-suppress AUTOSAR-A14_7_2-a
134
135// parasoft-begin-suppress AUTOSAR-A14_7_2-a "The primary template is forward declared to avoid circular dependencies"
136/// @brief Implementation class for a quantity kind raised to the specified positive and
137/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
138/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
139/// s/s or @c m^2/m^2
140/// @tparam Kind The quantity kind to raise to an exponent
141/// @tparam PositiveExponent The positive exponent to raise it to
142/// @tparam NegativeExponent The negative exponent to raise it to
143template <typename Kind, exponent_t PositiveExponent, exponent_t NegativeExponent>
144class quantity_kind_with_exponent<
145 Kind,
146 PositiveExponent,
147 NegativeExponent,
148 constraints<std::enable_if_t<!has_parent_kind_v<Kind>>, std::enable_if_t<has_explicit_units_v<Kind>>>>
149 : public quantity_kind<
150 quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>,
151 typename kind_with_exponent_helper<selected_unit_for_t<Kind>, PositiveExponent, NegativeExponent>::type> {
152 public:
153 /// @brief Denotes that quantity kind is implicit and does not mark a
154 /// boundary when aggregating and simplifying quantity kind types.
155 using is_implicit = void;
156};
157// parasoft-end-suppress AUTOSAR-A14_7_2-a
158
159// parasoft-begin-suppress AUTOSAR-A14_7_2-a "False positive: The primary template is defined in this file"
160/// @brief Implementation class for a quantity kind raised to the specified positive and
161/// negative exponents. Both @c PositiveExponent and @c NegativeExponent must be non-negative. The effective exponent is
162/// @c PositiveExponent - @c NegativeExponent however they are stored separately to allow distinguishing @c m/m from @c
163/// s/s or @c m^2/m^2
164/// @tparam Kind The quantity kind to raise to an exponent
165/// @tparam PositiveExponent The positive exponent to raise it to
166/// @tparam NegativeExponent The negative exponent to raise it to
167template <typename Kind, exponent_t PositiveExponent, exponent_t NegativeExponent>
168class quantity_kind_with_exponent<
169 Kind,
170 PositiveExponent,
171 NegativeExponent,
172 constraints<std::enable_if_t<has_parent_kind_v<Kind>>, std::enable_if_t<has_explicit_units_v<Kind>>>>
173 : public quantity_kind<
174 quantity_kind_with_exponent<Kind, PositiveExponent, NegativeExponent>,
175 typename kind_with_exponent_helper<
176 typename Kind::parent_quantity_kind_type,
177 PositiveExponent,
178 NegativeExponent>::type,
179 typename kind_with_exponent_helper<selected_unit_for_t<Kind>, PositiveExponent, NegativeExponent>::type> {
180 public:
181 /// @brief Denotes that quantity kind is implicit and does not mark a
182 /// boundary when aggregating and simplifying quantity kind types.
183 using is_implicit = void;
184};
185// parasoft-end-suppress AUTOSAR-A14_7_2-a
186
187// parasoft-begin-suppress AUTOSAR-A14_7_2-a "The template is forward declared to avoid circular dependencies"
188/// @brief Helper class to determine the result of raising the specified quantity kind to the specified exponent
189/// @tparam BaseKind The quantity kind to raise to an exponent
190/// @tparam BasePositiveExponent The positive exponent to it is already raised to
191/// @tparam BaseNegativeExponent The negative exponent to it is already raised to
192/// @tparam PositiveExponent The positive exponent to raise it to
193/// @tparam NegativeExponent The negative exponent to raise it to
194template <
195 typename BaseKind,
196 exponent_t BasePositiveExponent,
197 exponent_t BaseNegativeExponent,
198 exponent_t PositiveExponent,
199 exponent_t NegativeExponent>
200class kind_with_exponent_helper<
201 quantity_kind_with_exponent<BaseKind, BasePositiveExponent, BaseNegativeExponent>,
202 PositiveExponent,
203 NegativeExponent,
204 constraints<
205 // negated expr matches constraint for other specialization
206 // NOLINTNEXTLINE(readability-simplify-boolean-expr)
207 std::enable_if_t<!(PositiveExponent == 1 && NegativeExponent == 0)>>> {
208 public:
209 /// @brief An alias for a quantity kind representing the result of raising the specified quantity kind to the
210 /// specified exponent
211 using type = typename kind_with_exponent_helper<
212 BaseKind,
213 BasePositiveExponent * PositiveExponent + BaseNegativeExponent * NegativeExponent,
214 BasePositiveExponent * NegativeExponent + BaseNegativeExponent * PositiveExponent>::type;
215};
216// parasoft-end-suppress AUTOSAR-A14_7_2-a
217
218} // namespace units_detail
219
220} // namespace base
221} // namespace arene
222
223#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_KIND_WITH_EXPONENT_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10