10 #ifndef SRC_INCLUDE_SMASH_TRAITS_H_
11 #define SRC_INCLUDE_SMASH_TRAITS_H_
17 #include <type_traits>
56 template <
typename... Args>
64 template <
typename... Args>
72 template <
typename... Args>
87 : std::bool_constant<detail::is_stl_container<std::decay_t<T>>::value> {};
103 template <
typename T,
typename Enable =
void>
113 template <
typename T>
120 template <
typename T>
131 template <
typename T>
141 template <
typename K,
typename V,
typename... Args>
147 template <
typename T>
159 template <
typename S,
typename T,
typename Enable =
void>
168 template <
typename S,
typename T>
170 S, T, std::void_t<decltype(std::declval<S&>() << std::declval<T>())>>
176 template <typename S, typename T>
177 inline constexpr bool is_streamable_v = is_streamable<S, T>::value;
190 template <typename S, typename T, typename Enable = void>
191 struct is_writable_to_stream : std::false_type {};
206 template <typename S, typename T>
207 struct is_writable_to_stream<
208 S, T, std::enable_if_t<!is_stl_container_v<T> && !is_tuple_like_v<T>>>
209 : std::bool_constant<is_streamable_v<S, T>> {};
225 template <typename S, typename T>
226 struct is_writable_to_stream<
227 S, T, std::enable_if_t<is_stl_container_v<T> && !is_map_like_v<T>>>
228 : std::bool_constant<
229 is_streamable_v<S, T> &&
230 is_writable_to_stream<S, typename T::value_type>::value> {};
244 template <typename S, typename T>
245 struct is_writable_to_stream<S, T, std::enable_if_t<is_map_like_v<T>>> {
248 using key_type = typename T::key_type;
250 using mapped_type = typename T::mapped_type;
254 static constexpr bool value = is_streamable_v<S, T> &&
255 is_writable_to_stream<S, key_type>::value &&
256 is_writable_to_stream<S, mapped_type>::value;
271 template <typename S, typename T>
272 struct is_writable_to_stream<S, T, std::enable_if_t<is_tuple_like_v<T>>> {
283 template <std::size_t... I>
284 static constexpr bool check(std::index_sequence<I...>) {
285 return (is_writable_to_stream<S, std::tuple_element_t<I, T>>::value && ...);
290 static constexpr bool value =
291 is_streamable_v<S, T> &&
292 check(std::make_index_sequence<std::tuple_size_v<T>>{});
298 template <typename S, typename T>
299 inline constexpr bool is_writable_to_stream_v =
300 is_writable_to_stream<S, T>::value;
310 template <typename T, typename Enable = void>
311 struct has_to_string : std::false_type {};
329 template <typename T>
330 struct has_to_string<T,
331 std::void_t<decltype(smash::to_string(std::declval<T>()))>>
332 : std::is_same<decltype(smash::to_string(std::declval<T>())), std::string> {
344 template <std::size_t N>
345 struct has_to_string<std::bitset<N>, std::void_t<decltype(smash::to_string(
346 std::declval<std::bitset<N>>()))>>
347 : std::is_same<decltype(smash::to_string(std::declval<std::bitset<N>>())),
348 std::vector<std::string>> {};
353 template <typename T>
354 inline constexpr bool has_to_string_v = has_to_string<T>::value;
constexpr bool is_tuple_like_v
Helper alias which is common to be defined next to a type trait.
constexpr bool is_map_like_v
Helper alias which is common to be defined next to a type trait.
constexpr bool is_stl_container_v
Helper alias which is common to be defined next to a type trait.
static const uint32_t K[64]
The K array.
Implementation of the type trait to infer if a type is an STL container.
Type trait to infer if a type is map-like (for the moment only std::map is considered).
Type trait to infer if a type is an STL container.
Type trait to infer if a type can be streamed via the << operator.
Type trait to infer if a type is tuple-like (std::pair or std::tuple or std::array or few others).