9 #ifndef EAGINE_UNITS_CUSTOM_UNIT_HPP
10 #define EAGINE_UNITS_CUSTOM_UNIT_HPP
18 namespace eagine::units {
20 template <
typename Dims,
typename Conv,
typename System>
21 struct custom_dim_unit {
22 using dimension = Dims;
23 using conversion = Conv;
24 using system = System;
25 using type = custom_dim_unit;
29 template <
typename Conv,
typename Unit>
30 struct make_custom_unit;
32 template <
typename Conv,
typename Unit>
33 using make_custom_unit_t =
typename make_custom_unit<Conv, Unit>::type;
35 template <
typename Conv,
typename Dimension,
typename System>
36 struct make_custom_unit<Conv, unit<Dimension, System>>
37 : custom_dim_unit<Dimension, Conv, System> {};
40 template <
typename D,
typename C,
typename S>
41 struct is_convertible<custom_dim_unit<D, C, S>, unit<D, S>> : std::true_type {};
43 template <
typename D,
typename C,
typename S>
44 struct is_convertible<unit<D, S>, custom_dim_unit<D, C, S>> : std::true_type {};
46 template <
typename D,
typename C,
typename S>
47 struct is_convertible<custom_dim_unit<D, C, S>, custom_dim_unit<D, C, S>>
50 template <
typename D,
typename C1,
typename C2,
typename S>
51 struct is_convertible<custom_dim_unit<D, C1, S>, custom_dim_unit<D, C2, S>>
55 template <
typename D,
typename C,
typename S>
56 struct value_conv<custom_dim_unit<D, C, S>, unit<D, S>> {
58 constexpr
auto operator()(T v)
const {
59 return custom_dim_unit<D, C, S>::conversion::to_base(v);
63 template <
typename D,
typename C,
typename S>
64 struct value_conv<unit<D, S>, custom_dim_unit<D, C, S>> {
66 constexpr
auto operator()(T v)
const {
67 return custom_dim_unit<D, C, S>::conversion::from_base(v);
71 template <
typename D,
typename C,
typename S>
72 struct value_conv<custom_dim_unit<D, C, S>, custom_dim_unit<D, C, S>>
73 : trivial_value_conv {};
75 template <
typename D,
typename C1,
typename C2,
typename S>
76 struct value_conv<custom_dim_unit<D, C1, S>, custom_dim_unit<D, C2, S>> {
78 constexpr
auto operator()(T v)
const {
79 return custom_dim_unit<D, C2, S>::conversion::from_base(
80 custom_dim_unit<D, C1, S>::conversion::to_base(v));
85 template <
typename D,
typename C,
typename S>
86 struct lit_result<custom_dim_unit<D, C, S>> : custom_dim_unit<D, C, S> {};
89 template <
typename D,
typename C,
typename S>
90 struct add_result<custom_dim_unit<D, C, S>, unit<D, S>> : unit<D, S> {};
92 template <
typename D,
typename C,
typename S>
93 struct add_result<unit<D, S>, custom_dim_unit<D, C, S>> : unit<D, S> {};
95 template <
typename D,
typename C,
typename S>
96 struct add_result<custom_dim_unit<D, C, S>, custom_dim_unit<D, C, S>>
97 : custom_dim_unit<D, C, S> {};
99 template <
typename D,
typename C1,
typename C2,
typename S>
100 struct add_result<custom_dim_unit<D, C1, S>, custom_dim_unit<D, C2, S>>
101 : custom_dim_unit<D, C1, S> {};
104 template <
typename D,
typename C,
typename S>
105 struct sub_result<custom_dim_unit<D, C, S>, unit<D, S>> : unit<D, S> {};
107 template <
typename D,
typename C,
typename S>
108 struct sub_result<unit<D, S>, custom_dim_unit<D, C, S>> : unit<D, S> {};
110 template <
typename D,
typename C,
typename S>
111 struct sub_result<custom_dim_unit<D, C, S>, custom_dim_unit<D, C, S>>
112 : custom_dim_unit<D, C, S> {};
114 template <
typename D,
typename C1,
typename C2,
typename S>
115 struct sub_result<custom_dim_unit<D, C1, S>, custom_dim_unit<D, C2, S>>
116 : custom_dim_unit<D, C1, S> {};
119 template <
typename D1,
typename D2,
typename C,
typename S>
120 struct mul_l_operand<custom_dim_unit<D1, C, S>, unit<D2, S>> : unit<D1, S> {};
122 template <
typename D1,
typename D2,
typename C,
typename S>
123 struct mul_l_operand<unit<D1, S>, custom_dim_unit<D2, C, S>> : unit<D1, S> {};
125 template <
typename D1,
typename D2,
typename C1,
typename C2,
typename S>
126 struct mul_l_operand<custom_dim_unit<D1, C1, S>, custom_dim_unit<D2, C2, S>>
130 template <
typename D1,
typename D2,
typename C,
typename S>
131 struct mul_r_operand<custom_dim_unit<D1, C, S>, unit<D2, S>> : unit<D2, S> {};
133 template <
typename D1,
typename D2,
typename C,
typename S>
134 struct mul_r_operand<unit<D1, S>, custom_dim_unit<D2, C, S>> : unit<D2, S> {};
136 template <
typename D1,
typename D2,
typename C1,
typename C2,
typename S>
137 struct mul_r_operand<custom_dim_unit<D1, C1, S>, custom_dim_unit<D2, C2, S>>
141 template <
typename D1,
typename D2,
typename C,
typename S>
142 struct mul_result<custom_dim_unit<D1, C, S>, unit<D2, S>>
143 : unit<bits::dim_add_t<D1, D2>, S> {};
145 template <
typename D1,
typename D2,
typename C,
typename S>
146 struct mul_result<unit<D1, S>, custom_dim_unit<D2, C, S>>
147 : unit<bits::dim_add_t<D1, D2>, S> {};
149 template <
typename D1,
typename D2,
typename C1,
typename C2,
typename S>
150 struct mul_result<custom_dim_unit<D1, C1, S>, custom_dim_unit<D2, C2, S>>
151 : unit<bits::dim_add_t<D1, D2>, S> {};
154 template <
typename D1,
typename D2,
typename C,
typename S>
155 struct div_result<custom_dim_unit<D1, C, S>, unit<D2, S>>
156 : unit<bits::dim_sub_t<D1, D2>, S> {};
158 template <
typename D1,
typename D2,
typename C,
typename S>
159 struct div_result<unit<D1, S>, custom_dim_unit<D2, C, S>>
160 : unit<bits::dim_sub_t<D1, D2>, S> {};
162 template <
typename D1,
typename D2,
typename C1,
typename C2,
typename S>
163 struct div_result<custom_dim_unit<D1, C1, S>, custom_dim_unit<D2, C2, S>>
164 : unit<bits::dim_sub_t<D1, D2>, S> {};
168 #endif // EAGINE_UNITS_CUSTOM_UNIT_HPP