15 #ifndef BELUGA_PRIMITIVES_HPP
16 #define BELUGA_PRIMITIVES_HPP
19 #include <type_traits>
55 using Weight = Numeric<double, struct WeightTag>;
61 namespace state_detail {
65 template <
class T,
class =
void>
66 struct has_member_variable_state : std::false_type {};
69 struct has_member_variable_state<T,
std::void_t<decltype(std::declval<T>().state)>> : std::true_type {};
72 inline constexpr
bool has_member_variable_state_v = has_member_variable_state<T>::value;
74 template <
class T,
class =
void>
75 struct has_member_state : std::false_type {};
78 struct has_member_state<T,
std::void_t<decltype(std::declval<T>().state())>> : std::true_type {};
81 inline constexpr
bool has_member_state_v = has_member_state<T>::value;
83 template <
class T,
class =
void>
84 struct has_non_member_state : std::false_type {};
87 struct has_non_member_state<T,
std::void_t<decltype(state(std::declval<T>()))>> : std::true_type {};
90 inline constexpr
bool has_non_member_state_v = has_non_member_state<T>::value;
104 has_member_variable_state<T>,
105 std::negation<has_member_state<T>>,
106 std::negation<has_non_member_state<T>>>,
108 constexpr decltype(
auto) operator()(T&& t) const noexcept {
109 return beluga::forward_like<T>(t.state);
117 std::negation<has_member_variable_state<T>>,
119 std::negation<has_non_member_state<T>>>,
121 constexpr decltype(
auto) operator()(T&& t) const noexcept(noexcept(
std::forward<T>(t).
state())) {
122 return std::forward<T>(t).state();
133 std::negation<has_member_variable_state<T>>,
134 std::negation<has_member_state<T>>,
135 has_non_member_state<T>>,
137 constexpr decltype(
auto) operator()(T&& t) const noexcept(noexcept(
state(
std::forward<T>(t)))) {
138 return state(std::forward<T>(t));
149 std::negation<has_member_variable_state<T>>,
150 std::negation<has_member_state<T>>,
151 std::negation<has_non_member_state<T>>,
154 std::enable_if_t<(std::tuple_size_v<std::decay_t<T>> > 1),
int> = 0>
155 constexpr decltype(
auto)
operator()(T&& t)
const noexcept(noexcept(std::get<0>(std::forward<T>(t)))) {
156 return std::get<0>(std::forward<T>(t));
165 namespace weight_detail {
169 template <
class T,
class =
void>
170 struct has_member_variable_weight : std::false_type {};
173 struct has_member_variable_weight<T,
std::void_t<decltype(std::declval<T>().weight)>> : std::true_type {};
176 inline constexpr
bool has_member_variable_weight_v = has_member_variable_weight<T>::value;
178 template <
class T,
class =
void>
179 struct has_member_weight : std::false_type {};
182 struct has_member_weight<T,
std::void_t<decltype(std::declval<T>().weight())>> : std::true_type {};
185 inline constexpr
bool has_member_weight_v = has_member_weight<T>::value;
187 template <
class T,
class =
void>
188 struct has_non_member_weight : std::false_type {};
191 struct has_non_member_weight<T,
std::void_t<decltype(weight(std::declval<T>()))>> : std::true_type {};
194 inline constexpr
bool has_non_member_weight_v = has_non_member_weight<T>::value;
208 has_member_variable_weight<T>,
209 std::negation<has_member_weight<T>>,
210 std::negation<has_non_member_weight<T>>>,
212 constexpr decltype(
auto) operator()(T&& t) const noexcept {
213 return beluga::forward_like<T>(t.weight);
221 std::negation<has_member_variable_weight<T>>,
222 has_member_weight<T>,
223 std::negation<has_non_member_weight<T>>>,
225 constexpr decltype(
auto) operator()(T&& t) const noexcept(noexcept(
std::forward<T>(t).
weight())) {
226 return std::forward<T>(t).weight();
237 std::negation<has_member_variable_weight<T>>,
238 std::negation<has_member_weight<T>>,
239 has_non_member_weight<T>>,
241 constexpr decltype(
auto) operator()(T&& t) const noexcept(noexcept(
weight(
std::forward<T>(t)))) {
242 return weight(std::forward<T>(t));
250 std::negation<has_member_variable_weight<T>>,
251 std::negation<has_member_weight<T>>,
252 std::negation<has_non_member_weight<T>>,
257 return element<beluga::Weight>(std::forward<T>(t));