hash/include/nil/crypto3/detail/type_traits.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_TYPE_TRAITS_HPP
27 #define CRYPTO3_TYPE_TRAITS_HPP
28 
29 #include <complex>
30 #include <type_traits>
31 
32 #define GENERATE_HAS_MEMBER_TYPE(Type) \
33  \
34  template<class T> \
35  class HasMemberType_##Type { \
36  private: \
37  using Yes = char[2]; \
38  using No = char[1]; \
39  \
40  struct Fallback { \
41  struct Type { }; \
42  }; \
43  struct Derived : T, Fallback { }; \
44  \
45  template<class U> \
46  static No &test(typename U::Type *); \
47  template<typename U> \
48  static Yes &test(U *); \
49  \
50  public: \
51  static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
52  }; \
53  \
54  template<class T> \
55  struct has_##Type : public std::integral_constant<bool, HasMemberType_##Type<T>::RESULT> { };
56 
57 #define GENERATE_HAS_MEMBER(member) \
58  \
59  template<class T> \
60  class HasMember_##member { \
61  private: \
62  using Yes = char[2]; \
63  using No = char[1]; \
64  \
65  struct Fallback { \
66  int member; \
67  }; \
68  struct Derived : T, Fallback { }; \
69  \
70  template<class U> \
71  static No &test(decltype(U::member) *); \
72  template<typename U> \
73  static Yes &test(U *); \
74  \
75  public: \
76  static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
77  }; \
78  \
79  template<class T> \
80  struct has_##member : public std::integral_constant<bool, HasMember_##member<T>::RESULT> { };
81 
82 #define GENERATE_HAS_MEMBER_FUNCTION(Function, ...) \
83  \
84  template<typename T> \
85  struct has_##Function { \
86  struct Fallback { \
87  void Function(##__VA_ARGS__); \
88  }; \
89  \
90  struct Derived : Fallback { }; \
91  \
92  template<typename C, C> \
93  struct ChT; \
94  \
95  template<typename C> \
96  static char (&f(ChT<void (Fallback::*)(##__VA_ARGS__), &C::Function> *))[1]; \
97  \
98  template<typename C> \
99  static char (&f(...))[2]; \
100  \
101  static bool const value = sizeof(f<Derived>(0)) == 2; \
102  };
103 
104 #define GENERATE_HAS_MEMBER_CONST_FUNCTION(Function, ...) \
105  \
106  template<typename T> \
107  struct has_##Function { \
108  struct Fallback { \
109  void Function(##__VA_ARGS__) const; \
110  }; \
111  \
112  struct Derived : Fallback { }; \
113  \
114  template<typename C, C> \
115  struct ChT; \
116  \
117  template<typename C> \
118  static char (&f(ChT<void (Fallback::*)(##__VA_ARGS__) const, &C::Function> *))[1]; \
119  \
120  template<typename C> \
121  static char (&f(...))[2]; \
122  \
123  static bool const value = sizeof(f<Derived>(0)) == 2; \
124  };
125 
126 #define GENERATE_HAS_MEMBER_RETURN_FUNCTION(Function, ReturnType, ...) \
127  \
128  template<typename T> \
129  struct has_##Function { \
130  struct Dummy { \
131  typedef void ReturnType; \
132  }; \
133  typedef typename std::conditional<has_##ReturnType<T>::value, T, Dummy>::type TType; \
134  typedef typename TType::ReturnType type; \
135  \
136  struct Fallback { \
137  type Function(##__VA_ARGS__); \
138  }; \
139  \
140  struct Derived : TType, Fallback { }; \
141  \
142  template<typename C, C> \
143  struct ChT; \
144  \
145  template<typename C> \
146  static char (&f(ChT<type (Fallback::*)(##__VA_ARGS__), &C::Function> *))[1]; \
147  \
148  template<typename C> \
149  static char (&f(...))[2]; \
150  \
151  static bool const value = sizeof(f<Derived>(0)) == 2; \
152  };
153 
154 #define GENERATE_HAS_MEMBER_CONST_RETURN_FUNCTION(Function, ReturnType, ...) \
155  \
156  template<typename T> \
157  struct has_##Function { \
158  struct Dummy { \
159  typedef void ReturnType; \
160  }; \
161  typedef typename std::conditional<has_##ReturnType<T>::value, T, Dummy>::type TType; \
162  typedef typename TType::ReturnType type; \
163  \
164  struct Fallback { \
165  type Function(##__VA_ARGS__) const; \
166  }; \
167  \
168  struct Derived : TType, Fallback { }; \
169  \
170  template<typename C, C> \
171  struct ChT; \
172  \
173  template<typename C> \
174  static char (&f(ChT<type (Fallback::*)(##__VA_ARGS__) const, &C::Function> *))[1]; \
175  \
176  template<typename C> \
177  static char (&f(...))[2]; \
178  \
179  static bool const value = sizeof(f<Derived>(0)) == 2; \
180  };
181 
182 namespace nil {
183  namespace crypto3 {
184  namespace detail {
185  //
186  // as C++20 is not used
187  //
188  template <class T>
189  struct unwrap_reference { using type = T; };
190  template <class U>
191  struct unwrap_reference<std::reference_wrapper<U>> { using type = U&; };
192 
193  GENERATE_HAS_MEMBER_TYPE(iterator)
194  GENERATE_HAS_MEMBER_TYPE(const_iterator)
195 
196  GENERATE_HAS_MEMBER_TYPE(encoded_value_type)
197  GENERATE_HAS_MEMBER_TYPE(encoded_block_type)
198  GENERATE_HAS_MEMBER_TYPE(decoded_value_type)
199  GENERATE_HAS_MEMBER_TYPE(decoded_block_type)
200 
201  GENERATE_HAS_MEMBER_TYPE(block_type)
202  GENERATE_HAS_MEMBER_TYPE(digest_type)
203  GENERATE_HAS_MEMBER_TYPE(key_type)
204  GENERATE_HAS_MEMBER_TYPE(key_schedule_type)
205  GENERATE_HAS_MEMBER_TYPE(word_type)
206 
207  GENERATE_HAS_MEMBER(encoded_value_bits)
208  GENERATE_HAS_MEMBER(encoded_block_bits)
209  GENERATE_HAS_MEMBER(decoded_value_bits)
210  GENERATE_HAS_MEMBER(decoded_block_bits)
211 
212  GENERATE_HAS_MEMBER(block_bits)
213  GENERATE_HAS_MEMBER(digest_bits)
214  GENERATE_HAS_MEMBER(key_bits)
215  GENERATE_HAS_MEMBER(min_key_bits)
216  GENERATE_HAS_MEMBER(max_key_bits)
217  GENERATE_HAS_MEMBER(key_schedule_bits)
218  GENERATE_HAS_MEMBER(word_bits)
219 
220  GENERATE_HAS_MEMBER(rounds)
221 
222  GENERATE_HAS_MEMBER_CONST_RETURN_FUNCTION(begin, const_iterator)
223  GENERATE_HAS_MEMBER_CONST_RETURN_FUNCTION(end, const_iterator)
224 
227 
230 
233 
234  GENERATE_HAS_MEMBER_TYPE(extension_policy)
235  GENERATE_HAS_MEMBER_TYPE(curve_type)
236  GENERATE_HAS_MEMBER_TYPE(underlying_field_type)
237  GENERATE_HAS_MEMBER_TYPE(value_type)
238  GENERATE_HAS_MEMBER_TYPE(integral_type)
239  GENERATE_HAS_MEMBER_TYPE(base_field_type)
240  GENERATE_HAS_MEMBER_TYPE(number_type)
241  GENERATE_HAS_MEMBER_TYPE(scalar_field_type)
242  GENERATE_HAS_MEMBER_TYPE(g1_type)
243  GENERATE_HAS_MEMBER_TYPE(g2_type)
244  GENERATE_HAS_MEMBER_TYPE(gt_type)
245 
246  GENERATE_HAS_MEMBER(value_bits)
247  GENERATE_HAS_MEMBER(modulus_bits)
248  GENERATE_HAS_MEMBER(base_field_bits)
249  GENERATE_HAS_MEMBER(base_field_modulus)
250  GENERATE_HAS_MEMBER(scalar_field_bits)
251  GENERATE_HAS_MEMBER(scalar_field_modulus)
252  GENERATE_HAS_MEMBER(arity)
255 
256  GENERATE_HAS_MEMBER_FUNCTION(to_affine_coordinates)
257  GENERATE_HAS_MEMBER_FUNCTION(to_special)
258  GENERATE_HAS_MEMBER_FUNCTION(is_special)
259 
260  template<typename T>
261  struct is_iterator {
262  static char test(...);
263 
264  template<typename U, typename = typename std::iterator_traits<U>::difference_type,
265  typename = typename std::iterator_traits<U>::pointer,
266  typename = typename std::iterator_traits<U>::reference,
267  typename = typename std::iterator_traits<U>::value_type,
268  typename = typename std::iterator_traits<U>::iterator_category>
269  static long test(U &&);
270 
271  constexpr static bool value = std::is_same<decltype(test(std::declval<T>())), long>::value;
272  };
273 
274  template<typename Range>
275  struct is_range {
276  static const bool value = has_begin<Range>::value && has_end<Range>::value;
277  };
278 
279  template<typename Container>
280  struct is_container {
281  static const bool value =
282  has_const_iterator<Container>::value && has_begin<Container>::value && has_end<Container>::value;
283  };
284 
285  template<typename T>
286  struct is_codec {
287  static const bool value = has_encoded_value_type<T>::value && has_encoded_value_bits<T>::value &&
288  has_decoded_value_type<T>::value && has_decoded_value_bits<T>::value &&
289  has_encoded_block_type<T>::value && has_encoded_block_bits<T>::value &&
290  has_decoded_block_type<T>::value && has_decoded_block_bits<T>::value &&
291  has_encode<T>::value && has_decode<T>::value;
292  typedef T type;
293  };
294 
295  template<typename T>
296  struct is_block_cipher {
297  static const bool value = has_word_type<T>::value && has_word_bits<T>::value &&
298  has_block_type<T>::value && has_block_bits<T>::value &&
299  has_key_type<T>::value && has_key_bits<T>::value && has_rounds<T>::value &&
300  has_encrypt<T>::value && has_decrypt<T>::value;
301  typedef T type;
302  };
303 
304  template<typename T>
305  struct is_hash {
306  private:
307  typedef char one;
308  typedef struct {
309  char array[2];
310  } two;
311 
312  template<typename C>
313  static one test_construction_type(typename C::construction::type *);
314 
315  template<typename C>
316  static two test_construction_type(...);
317 
318  template<typename C>
319  static one test_construction_params(typename C::construction::params_type *);
320 
321  template<typename C>
322  static two test_construction_params(...);
323 
324  public:
325  static const bool value = has_digest_type<T>::value && has_digest_bits<T>::value &&
326  sizeof(test_construction_type<T>(0)) == sizeof(one) &&
327  sizeof(test_construction_params<T>(0)) == sizeof(one);
328  typedef T type;
329  };
330 
331  template<typename T>
332  struct is_mac {
333  static const bool value = has_digest_type<T>::value && has_digest_bits<T>::value &&
334  has_block_type<T>::value && has_block_bits<T>::value &&
335  has_key_type<T>::value && has_key_bits<T>::value;
336  typedef T type;
337  };
338 
339  template<typename T>
340  struct is_kdf {
341  static const bool value = has_digest_type<T>::value && has_digest_bits<T>::value &&
342  has_key_type<T>::value && has_max_key_bits<T>::value &&
343  has_min_key_bits<T>::value;
344  typedef T type;
345  };
346 
347  template<typename T>
348  struct is_passhash {
349  static const bool value = has_generate<T>::value && has_check<T>::value;
350  typedef T type;
351  };
352 
353  template<typename T>
354  struct is_curve {
355  static const bool value = has_base_field_bits<T>::value && has_base_field_type<T>::value &&
356  has_number_type<T>::value && has_base_field_modulus<T>::value &&
357  has_scalar_field_bits<T>::value && has_scalar_field_type<T>::value &&
358  has_scalar_field_modulus<T>::value && has_g1_type<T>::value &&
359  has_g2_type<T>::value && has_gt_type<T>::value && has_p<T>::value &&
360  has_q<T>::value;
361  typedef T type;
362  };
363 
364  template<typename T> //TODO: we should add some other params to curve group policy to identify it more clearly
365  struct is_curve_group {
366  static const bool value = has_value_type<T>::value && has_underlying_field_type<T>::value &&
367  has_value_bits<T>::value && has_curve_type<T>::value;
368  typedef T type;
369  };
370 
371  template<typename T>
372  struct is_field {
373  static const bool value = has_value_type<T>::value && has_value_bits<T>::value &&
374  has_integral_type<T>::value && has_modulus_bits<T>::value &&
375  has_number_type<T>::value && has_arity<T>::value;
376  typedef T type;
377  };
378 
379  template<typename T>
381  static const bool value = has_value_type<T>::value && has_value_bits<T>::value &&
382  has_integral_type<T>::value && has_modulus_bits<T>::value &&
383  has_number_type<T>::value && has_arity<T>::value &&
384  has_extension_policy<T>::value;
385  typedef T type;
386  };
387 
388  template<typename T>
389  struct is_complex : std::false_type { };
390  template<typename T>
391  struct is_complex<std::complex<T>> : std::true_type { };
392  template<typename T>
394 
395  template<typename T>
396  struct remove_complex {
397  using type = T;
398  };
399  template<typename T>
400  struct remove_complex<std::complex<T>> {
401  using type = T;
402  };
403  template<typename T>
405  } // namespace detail
406  } // namespace crypto3
407 } // namespace nil
408 
409 #endif // CRYPTO3_TYPE_TRAITS_HPP
OutputIterator encrypt(InputIterator first, InputIterator last, KeyInputIterator key_first, KeyInputIterator key_last, OutputIterator out)
Definition: block/include/nil/crypto3/block/algorithm/encrypt.hpp:66
OutputIterator decrypt(InputIterator first, InputIterator last, KeyInputIterator key_first, KeyInputIterator key_last, OutputIterator out)
Definition: block/include/nil/crypto3/block/algorithm/decrypt.hpp:66
std::enable_if< detail::is_iterator< OutputIterator >::value, OutputIterator >::type encode(InputIterator first, InputIterator last, OutputIterator out)
Encodes the elements with particular codec defined with Encoder in the range, defined by [first,...
Definition: codec/include/nil/crypto3/codec/algorithm/encode.hpp:57
std::enable_if< detail::is_iterator< OutputIterator >::value, OutputIterator >::type decode(InputIterator first, InputIterator last, OutputIterator out)
Decodes the elements with particular codec defined with Decoder in the range, defined by [first,...
Definition: decode.hpp:57
constexpr decltype(auto) generate(F &&f)
generates a matrix as a function of its indices
Definition: matrix/utility.hpp:84
OutputIterator check(InputIterator first, InputIterator last, OutputIterator out)
Definition: check.hpp:52
#define GENERATE_HAS_MEMBER_CONST_RETURN_FUNCTION(Function, ReturnType,...)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:154
#define GENERATE_HAS_MEMBER_RETURN_FUNCTION(Function, ReturnType,...)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:126
#define GENERATE_HAS_MEMBER_CONST_FUNCTION(Function,...)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:104
#define GENERATE_HAS_MEMBER_TYPE(Type)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:32
#define GENERATE_HAS_MEMBER(member)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:57
#define GENERATE_HAS_MEMBER_FUNCTION(Function,...)
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:82
constexpr bool is_complex_v
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:393
typename remove_complex< T >::type remove_complex_t
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:404
Definition: pair.hpp:31
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:125
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:301
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:126
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:111
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:292
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:389
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:100
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:365
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:368
static const bool value
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:366
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:354
static const bool value
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:355
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:361
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:380
static const bool value
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:381
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:385
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:372
static const bool value
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:373
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:376
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:137
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:328
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:157
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:78
constexpr static bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:88
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:174
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:175
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:344
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:165
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:336
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:166
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:184
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:185
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:350
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:92
static const bool value
Definition: algebra/include/nil/crypto3/detail/type_traits.hpp:93
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:401
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:396
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:397
U & type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:191
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:189
T type
Definition: hash/include/nil/crypto3/detail/type_traits.hpp:189