Lodestar
An integrated real-time control package in C++
TemplateTraits.hpp
1 //
2 // Created by Hamza El-Kebir on 12/22/21.
3 //
4 
5 #ifndef LODESTAR_TEMPLATETRAITS_HPP
6 #define LODESTAR_TEMPLATETRAITS_HPP
7 
8 #include <type_traits>
9 
10 #define RETURNS(...) \
11  noexcept(noexcept(__VA_ARGS__)) \
12  ->decltype(__VA_ARGS__) { \
13  return (__VA_ARGS__); \
14  }
15 
16 namespace ls {
17  namespace aux {
19  public:
20  // See https://stackoverflow.com/a/44013030
21  template<class, template<class...> class>
22  struct isInstance : public ::std::false_type {
23  static const bool value = false;
24  };
25 
26  template<class... T, template<class...> class U>
27  struct isInstance<U<T...>, U> : public ::std::true_type {
28  static const bool value = true;
29  };
30 
31  // https://stackoverflow.com/a/29671981
32  template<bool...>
33  struct bool_pack;
34  template<bool... bs>
35  using allTrue = ::std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
36 
37  template<bool... bs>
38  using allFalse = ::std::is_same<bool_pack<bs..., false>, bool_pack<false, bs...>>;
39 
40  template<class R, class... Ts>
41  using allConvertible = allTrue<::std::is_convertible<Ts, R>::value...>;
42 
43  template<class R, class... Ts>
44  using allSame = allTrue<::std::is_same<Ts, R>::value...>;
45 
46  template<class R, class... Ts>
47  using allBasedOf = allTrue<::std::is_base_of<R, Ts>::value...>;
48 
49  template<bool... bs>
50  using anyTrue = ::std::integral_constant<bool, !allFalse<bs...>::value>;
51 
52  template<class R, class... Ts>
53  using anyConvertible = anyTrue<::std::is_convertible<Ts, R>::value...>;
54 
59  protected:
60  struct addable {
61  template<class T, class U>
62  auto operator()(T t, U u) RETURNS(t + u)
63  };
64 
65  struct subtractable {
66  template<class T, class U>
67  auto operator()(T t, U u) RETURNS(t - u)
68  };
69 
70  struct multiplicable {
71  template<class T, class U>
72  auto operator()(T t, U u) RETURNS(t * u)
73  };
74 
75  struct divisible {
76  template<class T, class U>
77  auto operator()(T t, U u) RETURNS(t / u)
78  };
79 
80  public:
81  // See https://stackoverflow.com/a/29014938
82  template<class...>
83  struct voider {
84  using type = void;
85  };
86  template<class...Ts>
87  using void_t = typename voider<Ts...>::type;
88 
89  template<class T, class U, class BinaryOperation, class Enable = void>
90  struct isBinopableImpl : ::std::false_type {
91  using returnType = void;
92  };
93 
94  template<class T, class U, class BinOp>
95  struct isBinopableImpl<T, U, BinOp, void_t<
96  decltype(::std::declval<BinOp>()(
97  ::std::declval<T>(), ::std::declval<U>()))>> :
98  ::std::true_type {
99  using returnType = typename ::std::decay<decltype(::std::declval<BinOp>()(
100  ::std::declval<T>(), ::std::declval<U>()))>::type;
101  };
102 
113  template<typename T>
114  struct parseMatrixLike : ::std::false_type {
115  using scalar = T;
116 
117  enum {
118  rows = 0,
119  cols = 0
120  };
121  };
122 
132  template<template<typename, int, int, int...> class TWrapper, typename TScalar, int TRows, int TCols, int... TOtherParams>
133  struct parseMatrixLike<TWrapper<TScalar, TRows, TCols, TOtherParams...>>
134  : ::std::true_type {
135  using scalar = TScalar;
136  enum {
137  rows = TRows,
138  cols = TCols
139  };
140 
141  template<typename UScalar, int URows, int UCols, int... UOtherParams>
142  using wrapper = TWrapper<UScalar, URows, UCols, UOtherParams...>;
143  };
144 
151  template<typename T, class BinOp>
152  struct sanitizeTypeBinop : ::std::false_type {
153  using returnType = T;
154  };
155 
187  template<class BinOp,
188  template<typename, typename, int...> class TWrapper,
189  int... TWrapperInts,
190  template<typename, int...> class TWrapperChild1,
191  template<typename, int...> class TWrapperChild2,
192  typename TScalar,
193  typename UScalar,
194  int... TInts,
195  int... UInts>
196  struct sanitizeTypeBinop<TWrapper<
197  TWrapperChild1<TScalar, TInts...>,
198  TWrapperChild2<UScalar, UInts...>,
199  TWrapperInts...>, BinOp>
200  :
201  ::std::true_type {
202  using condition1 = typename ::std::conditional<
204  ::std::true_type,
205  ::std::false_type>::type;
206 
207  using condition2 = typename ::std::conditional<
208  parseMatrixLike<TWrapperChild1<TScalar, TInts...>>::value &&
209  parseMatrixLike<TWrapperChild2<UScalar, UInts...>>::value,
210  ::std::true_type,
211  ::std::false_type
212  >::type;
213 
214  using input = TWrapper<TWrapperChild1<TScalar, TInts...>, TWrapperChild2<UScalar, UInts...>>;
215  // TODO: Investigate if TOtherParams or UOtherParams matter.
216  using sanitized = TWrapperChild1<typename ::std::decay<typename isBinopableImpl<TScalar, UScalar, BinOp>::returnType>::type, parseMatrixLike<TWrapperChild1<TScalar, TInts...>>::rows, parseMatrixLike<TWrapperChild2<UScalar, UInts...>>::cols>;
217 
218  using returnType = typename ::std::conditional<
219  (allSame<::std::true_type, condition1, condition2>::value),
220  sanitized,
221  input
222  >::type;
223  };
224 
225  template<typename T>
227 
228  template<class T, class U, class BinOp>
230 
231  template<class T, class U = T>
233 
234  template<class T, class U = T>
236 
237  template<class T, class U = T>
239 
240  template<class T, class U = T>
242  };
243  };
244  }
245 }
246 
247 #undef RETURNS
248 
249 #endif //LODESTAR_TEMPLATETRAITS_HPP
ls::aux::TemplateTraits::BinaryOperators::sanitizeTypeBinop
Sanitizes a binary operator return type.
Definition: TemplateTraits.hpp:152
ls::aux::TemplateTraits::bool_pack
Definition: TemplateTraits.hpp:33
ls::aux::TemplateTraits::BinaryOperators::divisible
Definition: TemplateTraits.hpp:75
ls::aux::TemplateTraits::BinaryOperators::addable
Definition: TemplateTraits.hpp:60
ls::aux::TemplateTraits::BinaryOperators::isBinopableImpl
Definition: TemplateTraits.hpp:90
ls::aux::TemplateTraits::BinaryOperators::multiplicable
Definition: TemplateTraits.hpp:70
ls::aux::TemplateTraits::BinaryOperators::subtractable
Definition: TemplateTraits.hpp:65
ls::aux::TemplateTraits::BinaryOperators::parseMatrixLike
Extracts data from matrix-like types.
Definition: TemplateTraits.hpp:114
ls
Main Lodestar code.
Definition: BilinearTransformation.hpp:12
ls::aux::TemplateTraits::BinaryOperators
Provides binary operator traits.
Definition: TemplateTraits.hpp:58
ls::aux::TemplateTraits
Definition: TemplateTraits.hpp:18
ls::aux::TemplateTraits::isInstance
Definition: TemplateTraits.hpp:22
ls::aux::TemplateTraits::BinaryOperators::voider
Definition: TemplateTraits.hpp:83