Version: SMASH-3.3
traits.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2024-2025
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_SMASH_TRAITS_H_
11 #define SRC_INCLUDE_SMASH_TRAITS_H_
12 
13 #include <map>
14 #include <set>
15 #include <sstream>
16 #include <string>
17 #include <type_traits>
18 #include <vector>
19 
20 #include "stringify.h"
21 
22 namespace smash {
23 
25 namespace detail {
26 
48 template <typename T>
49 struct is_stl_container : std::false_type {};
50 
56 template <typename... Args>
57 struct is_stl_container<std::vector<Args...>> : std::true_type {};
58 
64 template <typename... Args>
65 struct is_stl_container<std::set<Args...>> : std::true_type {};
66 
72 template <typename... Args>
73 struct is_stl_container<std::map<Args...>> : std::true_type {};
74 
75 } // namespace detail
76 
77 //============================================================================//
85 template <typename T>
87  : std::bool_constant<detail::is_stl_container<std::decay_t<T>>::value> {};
88 
92 template <typename T>
94 
95 //============================================================================//
103 template <typename T, typename Enable = void>
104 struct is_tuple_like : std::false_type {};
105 
113 template <typename T>
114 struct is_tuple_like<T, std::void_t<decltype(std::tuple_size<T>::value)>>
115  : std::true_type {};
116 
120 template <typename T>
121 inline constexpr bool is_tuple_like_v = is_tuple_like<T>::value;
122 
123 //============================================================================//
131 template <typename T>
132 struct is_map_like : std::false_type {};
133 
141 template <typename K, typename V, typename... Args>
142 struct is_map_like<std::map<K, V, Args...>> : std::true_type {};
143 
147 template <typename T>
148 inline constexpr bool is_map_like_v = is_map_like<std::decay_t<T>>::value;
149 
150 //============================================================================//
159 template <typename S, typename T, typename Enable = void>
160 struct is_streamable : std::false_type {};
161 
168 template <typename S, typename T>
170  S, T, std::void_t<decltype(std::declval<S&>() << std::declval<T>())>>
171  : std::true_type {};
172 
176 template <typename S, typename T>
177 inline constexpr bool is_streamable_v = is_streamable<S, T>::value;
178 
179 //============================================================================//
190 template <typename S, typename T, typename Enable = void>
191 struct is_writable_to_stream : std::false_type {};
192 
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>> {};
210 
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> {};
231 
244 template <typename S, typename T>
245 struct is_writable_to_stream<S, T, std::enable_if_t<is_map_like_v<T>>> {
246  private:
248  using key_type = typename T::key_type;
250  using mapped_type = typename T::mapped_type;
251 
252  public:
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;
257 };
258 
271 template <typename S, typename T>
272 struct is_writable_to_stream<S, T, std::enable_if_t<is_tuple_like_v<T>>> {
273  private:
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 && ...);
286  }
287 
288  public:
290  static constexpr bool value =
291  is_streamable_v<S, T> &&
292  check(std::make_index_sequence<std::tuple_size_v<T>>{});
293 };
294 
298 template <typename S, typename T>
299 inline constexpr bool is_writable_to_stream_v =
300  is_writable_to_stream<S, T>::value;
301 
310 template <typename T, typename Enable = void>
311 struct has_to_string : std::false_type {};
312 
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> {
333 };
334 
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>> {};
349 
353 template <typename T>
354 inline constexpr bool has_to_string_v = has_to_string<T>::value;
355 
356 } // namespace smash
357 
358 #endif // SRC_INCLUDE_SMASH_TRAITS_H_
Definition: action.h:24
constexpr bool is_tuple_like_v
Helper alias which is common to be defined next to a type trait.
Definition: traits.h:121
constexpr bool is_map_like_v
Helper alias which is common to be defined next to a type trait.
Definition: traits.h:148
constexpr bool is_stl_container_v
Helper alias which is common to be defined next to a type trait.
Definition: traits.h:93
static const uint32_t K[64]
The K array.
Definition: sha256.cc:70
#define S(x, n)
Definition: sha256.cc:54
Implementation of the type trait to infer if a type is an STL container.
Definition: traits.h:49
Type trait to infer if a type is map-like (for the moment only std::map is considered).
Definition: traits.h:132
Type trait to infer if a type is an STL container.
Definition: traits.h:87
Type trait to infer if a type can be streamed via the << operator.
Definition: traits.h:160
Type trait to infer if a type is tuple-like (std::pair or std::tuple or std::array or few others).
Definition: traits.h:104