Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
quantity_origin.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_QUANTITY_ORIGIN_HPP_
5#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_QUANTITY_ORIGIN_HPP_
6
7#include "arene/base/constraints/constraints.hpp"
8#include "arene/base/stdlib_choice/declval.hpp"
9#include "arene/base/stdlib_choice/integral_constant.hpp"
10#include "arene/base/stdlib_choice/is_same.hpp"
11
12namespace arene {
13namespace base {
14
15/// @brief CRTP base class used when defining a new quantity origin, e.g. absolute zero for temperature
16/// @tparam Derived user-defined class publicly inheriting from this one; @c Derived becomes a quantity origin
17template <typename Derived>
18class quantity_origin;
19
20/// @brief CRTP base class used when defining a new relative origin, e.g. zero celsius which is relative to zero Kelvin
21/// @tparam Derived user-defined class publicly inheriting from this one; @c Derived becomes a quantity origin
22/// @tparam BaseOrigin a @c quantity_origin to which this will be defined as being relative
23template <typename Derived, typename BaseOrigin>
24class relative_origin;
25
26namespace quantity_origin_detail {
27
28// parasoft-begin-suppress CERT_C-EXP37-a "False positive: The rule does not mention naming all parameters"
29// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
30
31/// @brief Use overload resolution to check if a type is directly derived from @c quantity_origin or @c relative_origin
32/// @tparam Origin the type being checked; should be explicitly specified to assert that it's the CRTP parameter
33/// @return @c std::true_type so that the selected overload can be examined using @c decltype
34template <typename Origin>
35constexpr auto is_origin_impl(quantity_origin<Origin>*) noexcept -> std::true_type {
36 return {};
37}
38
39/// @brief Use overload resolution to check if a type is directly derived from @c quantity_origin or @c relative_origin
40/// @tparam Origin the type being checked; should be explicitly specified to assert that it's the CRTP parameter
41/// @tparam OtherOrigin any other origin; should be left unspecified and allowed to be deduced
42/// @return @c std::true_type so that the selected overload can be examined using @c decltype
43template <typename Origin, typename OtherOrigin>
44constexpr auto is_origin_impl(relative_origin<Origin, OtherOrigin>*) noexcept -> std::true_type {
45 return {};
46}
47
48/// @brief Use overload resolution to check if a type is directly derived from @c quantity_origin or @c relative_origin
49/// @return @c std::false_type so that the selected overload can be examined using @c decltype
50template <typename>
51constexpr auto is_origin_impl(void*) noexcept -> std::false_type {
52 return {};
53}
54
55// parasoft-end-suppress CERT_C-EXP37-a
56// parasoft-end-suppress AUTOSAR-M3_3_2-a
57
58/// @brief Type trait to check if a quantity kind is itself an origin. The value is @c true if it is, @c false otherwise
59/// @tparam Kind quantity kind to check
60template <typename Origin>
61extern constexpr bool is_origin_v = decltype(is_origin_impl<Origin>(std::declval<Origin*>())){};
62
63/// @brief Type trait to check if a quantity kind has an origin. The value is @c true if it does, @c false otherwise
64/// @tparam Kind quantity kind to check
65template <typename Kind, typename = constraints<>>
66extern constexpr bool has_origin_v = false;
67
68/// @brief Type trait to check if a quantity kind has an origin. The value is @c true if it does, @c false otherwise
69/// @tparam Kind quantity kind to check
70template <typename Kind>
71extern constexpr bool has_origin_v<Kind, constraints<typename Kind::origin>> = is_origin_v<typename Kind::origin>;
72
73/// @brief Type trait to check if the first origin is relative to the second (or they're the same)
74/// @tparam DerivedOrigin the origin of the derived quantity kind
75/// @tparam ParentOrigin the origin of the parent quantity kind
76template <typename DerivedOrigin, typename ParentOrigin, typename = constraints<>>
77extern constexpr bool origin_is_relative_to_v = std::is_same<ParentOrigin, DerivedOrigin>::value;
78
79/// @brief Type trait to check if the first origin is relative to the second (or they're the same)
80/// @tparam DerivedOrigin the origin of the derived quantity kind
81/// @tparam ParentOrigin the origin of the parent quantity kind
82template <typename DerivedOrigin, typename ParentOrigin>
83extern constexpr bool
84 origin_is_relative_to_v<DerivedOrigin, ParentOrigin, constraints<typename DerivedOrigin::base_origin>> =
85 std::is_same<typename DerivedOrigin::base_origin, typename ParentOrigin::origin>::value;
86
87} // namespace quantity_origin_detail
88
89/// @brief CRTP base class used when defining a new quantity origin, e.g. absolute zero for temperature
90/// @tparam Derived user-defined class publicly inheriting from this one; @c Derived becomes a quantity origin
91template <typename Derived>
92class quantity_origin {
93 public:
94 /// @brief Type alias used to identify downstream classes as being anchored to this origin
95 using origin = Derived;
96};
97
98/// @brief CRTP base class used when defining a new relative origin, e.g. zero celsius which is relative to zero Kelvin
99/// @tparam Derived user-defined class publicly inheriting from this one; @c Derived becomes a quantity origin
100/// @tparam BaseOrigin a @c quantity_origin to which this will be defined as being relative
101template <typename Derived, typename BaseOrigin>
102class relative_origin {
103 static_assert(
104 quantity_origin_detail::is_origin_v<BaseOrigin>,
105 "The base origin supplied to relative_origin must actually be a quantity origin"
106 );
107
108 public:
109 /// @brief Type alias for the base origin to allow checking that the two origins are related
110 using base_origin = BaseOrigin;
111 /// @brief Type alias used to identify downstream classes as being anchored to this origin
112 using origin = Derived;
113};
114
115/// @brief Type trait to check if a quantity kind has an origin. The value is @c true if it does, @c false otherwise
116/// @tparam Kind Quantity kind to check
117template <typename Kind>
119
120/// @brief Type trait to check if a quantity kind is itself an origin. The value is @c true if it is, @c false otherwise
121/// @tparam Kind Quantity kind to check
122template <typename Kind>
124
125/// @brief Type trait to get the origin of a quantity; if none exists, then this will cause a compilation error
126/// @tparam Kind Quantity kind to check
127template <typename Kind>
128using quantity_origin_t = typename Kind::origin;
129
130} // namespace base
131} // namespace arene
132
133#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_UNITS_QUANTITY_ORIGIN_HPP_
Definition array_exceptions_disabled.cpp:11
constexpr bool quantity_has_origin_v
Type trait to check if a quantity kind has an origin. The value is true if it does,...
constexpr bool is_quantity_origin_v
Type trait to check if a quantity kind is itself an origin. The value is true if it is,...
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10