BitStream
meta.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../stream/serialize_traits.h"
4 
5 #include <type_traits>
6 
7 namespace bitstream::utility
8 {
9  // Check if type has a serializable trait
10  template<typename Void, typename T, typename Stream, typename... Args>
11  struct has_serialize : std::false_type {};
12 
13  template<typename T, typename Stream, typename... Args>
14  struct has_serialize<std::void_t<decltype(serialize_traits<T>::serialize(std::declval<Stream&>(), std::declval<Args>()...))>, T, Stream, Args...> : std::true_type {};
15 
16  template<typename T, typename Stream, typename... Args>
17  using has_serialize_t = std::void_t<decltype(serialize_traits<T>::serialize(std::declval<Stream&>(), std::declval<Args>()...))>;
18 
19  template<typename T, typename Stream, typename... Args>
20  constexpr bool has_serialize_v = has_serialize<void, T, Stream, Args...>::value;
21 
22 
23  // Check if stream is writing or reading
24  template<typename T, typename R = bool>
25  using is_writing_t = std::enable_if_t<T::writing, R>;
26 
27  template<typename T, typename R = bool>
28  using is_reading_t = std::enable_if_t<T::reading, R>;
29 
30 
31  // Check if type is noexcept, if it exists
32  template<typename Void, typename T, typename Stream, typename... Args>
33  struct is_serialize_noexcept : std::false_type {};
34 
35  template<typename T, typename Stream, typename... Args>
36  struct is_serialize_noexcept<std::enable_if_t<has_serialize_v<T, Stream, Args...>>, T, Stream, Args...> :
37  std::bool_constant<noexcept(serialize_traits<T>::serialize(std::declval<Stream&>(), std::declval<Args>()...))> {};
38 
39  template<typename T, typename Stream, typename... Args>
40  constexpr bool is_serialize_noexcept_v = is_serialize_noexcept<void, T, Stream, Args...>::value;
41 
42 
43  // Get the underlying type without &, &&, * or const
44  template<typename T>
45  using base_t = typename std::remove_const_t<std::remove_pointer_t<std::decay_t<T>>>;
46 
47 
48  // Meta functions for guessing the trait type from the first argument
49  template<typename Void, typename Trait, typename Stream, typename... Args>
50  struct deduce_trait
51  {
52  using type = Trait;
53  };
54 
55  // Non-const value
56  template<typename Trait, typename Stream, typename... Args>
57  struct deduce_trait<std::enable_if_t<
58  !std::is_pointer_v<std::decay_t<Trait>> &&
59  has_serialize_v<base_t<Trait>, Stream, Trait, Args...>>,
60  Trait, Stream, Args...>
61  {
63  };
64 
65  // Const value
66  template<typename Trait, typename Stream, typename... Args>
67  struct deduce_trait<std::enable_if_t<
68  !std::is_pointer_v<std::decay_t<Trait>> &&
69  has_serialize_v<std::add_const_t<base_t<Trait>>, Stream, Trait, Args...>>,
70  Trait, Stream, Args...>
71  {
72  using type = std::add_const_t<base_t<Trait>>;
73  };
74 
75  // Non-const pointer
76  template<typename Trait, typename Stream, typename... Args>
77  struct deduce_trait<std::enable_if_t<
78  std::is_pointer_v<std::decay_t<Trait>> &&
79  has_serialize_v<std::add_pointer_t<base_t<Trait>>, Stream, Trait, Args...>>,
80  Trait, Stream, Args...>
81  {
82  using type = std::add_pointer_t<base_t<Trait>>;
83  };
84 
85  // Const pointer
86  template<typename Trait, typename Stream, typename... Args>
87  struct deduce_trait<std::enable_if_t<
88  std::is_pointer_v<std::decay_t<Trait>> &&
89  has_serialize_v<std::add_pointer_t<std::add_const_t<base_t<Trait>>>, Stream, Trait, Args...>>,
90  Trait, Stream, Args...>
91  {
92  using type = std::add_pointer_t<std::add_const_t<base_t<Trait>>>;
93  };
94 
95  template<typename Trait, typename Stream, typename... Args>
96  using deduce_trait_t = typename deduce_trait<void, Trait, Stream, Args...>::type;
97 
98 
99  // Shorthands for deduced type_traits
100  template<typename Trait, typename Stream, typename... Args>
101  using has_deduce_serialize_t = has_serialize_t<deduce_trait_t<Trait, Stream, Args...>, Stream, Trait, Args...>;
102 
103  template<typename Trait, typename Stream, typename... Args>
104  constexpr bool is_deduce_serialize_noexcept_v = is_serialize_noexcept_v<deduce_trait_t<Trait, Stream, Args...>, Stream, Trait, Args...>;
105 }
Definition: bits.h:7
std::enable_if_t< T::writing, R > is_writing_t
Definition: meta.h:25
constexpr bool is_deduce_serialize_noexcept_v
Definition: meta.h:104
has_serialize_t< deduce_trait_t< Trait, Stream, Args... >, Stream, Trait, Args... > has_deduce_serialize_t
Definition: meta.h:101
constexpr bool is_serialize_noexcept_v
Definition: meta.h:40
typename std::remove_const_t< std::remove_pointer_t< std::decay_t< T > >> base_t
Definition: meta.h:45
typename deduce_trait< void, Trait, Stream, Args... >::type deduce_trait_t
Definition: meta.h:96
constexpr bool has_serialize_v
Definition: meta.h:20
std::enable_if_t< T::reading, R > is_reading_t
Definition: meta.h:28
std::void_t< decltype(serialize_traits< T >::serialize(std::declval< Stream & >(), std::declval< Args >()...))> has_serialize_t
Definition: meta.h:17
A class for specializing trait serialization functions.
Definition: serialize_traits.h:11
Trait type
Definition: meta.h:52