4#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_QUANTITY_KIND_HPP_
5#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_QUANTITY_KIND_HPP_
7#include "arene/base/constraints/constraints.hpp"
8#include "arene/base/stdlib_choice/declval.hpp"
9#include "arene/base/stdlib_choice/enable_if.hpp"
10#include "arene/base/stdlib_choice/is_class.hpp"
11#include "arene/base/stdlib_choice/is_same.hpp"
12#include "arene/base/stdlib_choice/remove_cv.hpp"
13#include "arene/base/type_traits/conditional.hpp"
14#include "arene/base/units/detail/missing.hpp"
15#include "arene/base/units/is_possible_unit_for.hpp"
16#include "arene/base/units/is_quantity_kind.hpp"
17#include "arene/base/units/is_unit.hpp"
18#include "arene/base/units/kind_with_exponent_fwd.hpp"
19#include "arene/base/units/quantity_origin.hpp"
24namespace quantity_kind_detail {
27template <
typename Type>
28extern constexpr bool is_missing_v = std::is_same<Type, units_detail::missing>::value;
32auto rebind_quantity_kind_unit_type() ->
void =
delete;
36template <
typename Unit>
37class quantity_kind_unit_mixin {
40 using unit_type = Unit;
45class quantity_kind_unit_mixin<units_detail::missing> {};
49template <
typename Origin>
50class quantity_kind_origin_mixin {
53 using origin = Origin;
58class quantity_kind_origin_mixin<units_detail::missing> {};
62template <
typename ParentKind>
63class quantity_kind_parent_mixin {
66 using parent_quantity_kind_type = ParentKind;
72class quantity_kind_parent_mixin<units_detail::missing> {};
79template <
typename Derived,
typename OptionalParentKind,
typename OptionalOrigin,
typename OptionalUnit>
80class quantity_kind_base
81 :
public quantity_kind_parent_mixin<OptionalParentKind>
82 ,
public quantity_kind_origin_mixin<OptionalOrigin>
83 ,
public quantity_kind_unit_mixin<OptionalUnit> {
86 using quantity_kind_type = Derived;
90 template <units_detail::exponent_t Exponent>
91 using with_exponent = kind_with_exponent_t<Derived, Exponent>;
95 template <
typename OtherUnit>
96 using in = std::enable_if_t<
97 std::is_class<OtherUnit>::value,
98 decltype(rebind_quantity_kind_unit_type(std::declval<quantity_kind_base>(), std::declval<OtherUnit>()))>;
106template <
typename Derived,
typename OptionalParentKind,
typename OptionalOrigin,
typename OptionalUnit>
107class choose_quantity_kind_sanity_check {
109 is_missing_v<OptionalParentKind> || is_quantity_kind_v<OptionalParentKind>,
110 "The specified parent kind must be a quantity kind"
113 is_missing_v<OptionalParentKind> || !is_unit_v<OptionalParentKind>,
114 "The specified parent kind must not be a unit"
118 is_missing_v<OptionalOrigin> || is_quantity_origin_v<OptionalOrigin>,
119 "The specified origin must be a quantity origin"
122 static_assert(is_missing_v<OptionalUnit> || is_unit_v<OptionalUnit>,
"The specified unit must be a quantity unit");
124 is_missing_v<OptionalUnit> || units_detail::is_declared_possible_unit_for_v<OptionalUnit, Derived> ||
125 is_possible_unit_for_v<OptionalUnit, OptionalParentKind>,
126 "The specified unit must be a possible unit for the specified kind or for its parent kind"
133template <
typename MaybeParentKind,
typename MaybeDerivedOrigin,
typename = constraints<>>
134class derived_origin_impl {
137 using type = units_detail::missing;
143template <
typename MaybeParentKind>
144class derived_origin_impl<
146 units_detail::missing,
147 constraints<std::enable_if_t<quantity_has_origin_v<MaybeParentKind>>>> {
150 using type =
typename MaybeParentKind::origin;
156template <
typename MaybeParentKind,
typename MaybeDerivedOrigin>
157class derived_origin_impl<
160 constraints<std::enable_if_t<!quantity_has_origin_v<MaybeParentKind>>>> {
163 using type = MaybeDerivedOrigin;
169template <
typename MaybeParentKind,
typename MaybeDerivedOrigin>
170class derived_origin_impl<
173 constraints<std::enable_if_t<quantity_has_origin_v<MaybeParentKind>>>> {
175 quantity_origin_detail::origin_is_relative_to_v<MaybeDerivedOrigin,
typename MaybeParentKind::origin>,
176 "If the parent of a derived quantity kind has an origin, the derived kind's origin must be relative to it"
181 using type = MaybeDerivedOrigin;
187template <
typename MaybeParentKind,
typename MaybeDerivedOrigin>
188using derived_origin_t =
typename derived_origin_impl<MaybeParentKind, MaybeDerivedOrigin>::type;
197template <
typename Derived,
typename ParentKindOrOriginOrUnit,
typename OriginOrUnit,
typename Unit>
198class choose_quantity_kind_base {
200 using actual_parent = ParentKindOrOriginOrUnit;
203 using actual_origin = OriginOrUnit;
206 using actual_unit = Unit;
210 static constexpr choose_quantity_kind_sanity_check<Derived, actual_parent, actual_origin, actual_unit> check{};
215 using type = quantity_kind_base<Derived, actual_parent, derived_origin_t<actual_parent, actual_origin>, actual_unit>;
225template <
typename Derived,
typename ParentKindOrOrigin,
typename OriginOrUnit>
226class choose_quantity_kind_base<Derived, ParentKindOrOrigin, OriginOrUnit, units_detail::missing> {
229 using missing = units_detail::missing;
233 using actual_parent = conditional_t<!is_quantity_origin_v<ParentKindOrOrigin>, ParentKindOrOrigin, missing>;
236 using actual_origin = conditional_t<
237 !is_quantity_kind_v<ParentKindOrOrigin>,
239 conditional_t<!is_unit_v<OriginOrUnit>, OriginOrUnit, missing>>;
242 using actual_unit = conditional_t<!is_quantity_origin_v<OriginOrUnit>, OriginOrUnit, missing>;
246 static constexpr choose_quantity_kind_sanity_check<Derived, actual_parent, actual_origin, actual_unit> check{};
251 using type = quantity_kind_base<Derived, actual_parent, derived_origin_t<actual_parent, actual_origin>, actual_unit>;
261template <
typename Derived,
typename ParentKindOrOriginOrUnit>
262class choose_quantity_kind_base<Derived, ParentKindOrOriginOrUnit, units_detail::missing, units_detail::missing> {
265 using missing = units_detail::missing;
269 using actual_parent = conditional_t<
270 !is_quantity_origin_v<ParentKindOrOriginOrUnit> && !is_unit_v<ParentKindOrOriginOrUnit>,
271 ParentKindOrOriginOrUnit,
275 using actual_origin =
276 conditional_t<is_quantity_origin_v<ParentKindOrOriginOrUnit>, ParentKindOrOriginOrUnit, missing>;
279 using actual_unit = conditional_t<is_unit_v<ParentKindOrOriginOrUnit>, ParentKindOrOriginOrUnit, missing>;
283 static constexpr choose_quantity_kind_sanity_check<Derived, actual_parent, actual_origin, actual_unit> check{};
288 using type = quantity_kind_base<Derived, actual_parent, derived_origin_t<actual_parent, actual_origin>, actual_unit>;
298template <
typename Derived>
299class choose_quantity_kind_base<Derived, units_detail::missing, units_detail::missing, units_detail::missing> {
302 using missing = units_detail::missing;
307 using type = quantity_kind_base<Derived, missing, missing, missing>;
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10