RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
staticChecks.hh
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the C++-library RFFGen. */
4 /* Copyright 2015 Lars Lubkoll */
5 /* */
6 /* RFFGen is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* RFFGen is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with RFFGen. If not, see <http://www.gnu.org/licenses/>. */
18 /* */
19 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20 
21 #ifndef RFFGEN_STATIC_CHECKS_HH
22 #define RFFGEN_STATIC_CHECKS_HH
23 
24 #include <type_traits>
25 #include <utility>
26 
27 #include "../LinearAlgebra/extractRowsAndCols.hh"
28 #include "base.hh"
29 #include "voider.hh"
30 
36 namespace RFFGen
37 {
38  namespace Checks
39  {
43  // Multiplication with doubles
44  template < class Arg , class ScalarArg > using TryMultiplicationWithArithmeticFromLeft = decltype( std::declval<ScalarArg>() * std::declval<Arg>() );
45  template < class Arg , class ScalarArg > using TryMultiplicationWithArithmeticFromRight = decltype( std::declval<Arg>() * std::declval<ScalarArg>() );
46  template < class Arg , class ScalarArg > using TryInPlaceMultiplicationWithArithmetic = decltype( std::declval<Arg>() *= std::declval<ScalarArg>() );
47 
48  template < class Arg , class ScalarArg , bool , class = void > struct MultiplicationWithArithmeticFromLeft : std::false_type {};
49  template < class Arg , class ScalarArg , bool , class = void > struct MultiplicationWithArithmeticFromRight : std::false_type {};
50  template < class Arg , class ScalarArg , bool , class = void > struct InPlaceMultiplicationWithArithmetic : std::false_type {};
51 
52  template < class Arg , class ScalarArg >
53  struct MultiplicationWithArithmeticFromLeft< Arg , ScalarArg , true , void_t< TryMultiplicationWithArithmeticFromLeft<Arg,ScalarArg> > >
54  : std::true_type
55  {};
56 
57  template < class Arg , class ScalarArg >
58  struct MultiplicationWithArithmeticFromRight< Arg , ScalarArg , true , void_t< TryMultiplicationWithArithmeticFromRight<Arg,ScalarArg> > >
59  : std::true_type
60  {};
61 
62  template < class Arg , class ScalarArg >
63  struct InPlaceMultiplicationWithArithmetic< Arg , ScalarArg , true , void_t< TryInPlaceMultiplicationWithArithmetic<Arg,ScalarArg> > >
64  : std::true_type
65  {};
66 
67 
68  // Multiplication
69  template < class Arg1 , class Arg2 > using TryMultiplication = decltype( std::declval<Arg1>() * std::declval<Arg2>() );
70  template < class Arg1 , class Arg2 > using TryInPlaceMultiplication = decltype( std::declval<Arg1>() *= std::declval<Arg2>() );
71  template < class Arg1 , class Arg2 > using TryCallToRightMultiply = decltype( std::declval<Arg1>().rightmultiplyany(std::declval<Arg2>()) );
72 
73  template < class Arg1 , class Arg2 , bool , class = void > struct Multiplication : std::false_type {};
74  template < class Arg1 , class Arg2 , bool , class = void > struct InPlaceMultiplication : std::false_type {};
75  template < class Arg1 , class Arg2 , bool , class = void > struct CallToRightMultiply : std::false_type {};
76 
77  template < class Arg1 , class Arg2 >
78  struct Multiplication< Arg1 , Arg2 , true , void_t< TryMultiplication<Arg1,Arg2> > > : std::true_type {};
79 
80  template < class Arg1 , class Arg2 >
81  struct InPlaceMultiplication< Arg1 , Arg2 , true , void_t< TryInPlaceMultiplication<Arg1,Arg2> > > : std::true_type {};
82 
83  template < class Arg1 , class Arg2 >
84  struct CallToRightMultiply< Arg1 , Arg2 , true , void_t< TryCallToRightMultiply<Arg1,Arg2> > > : std::true_type {};
85 
86 
87  // Summation
88  template < class Arg > using TrySummation = decltype( std::declval<Arg>() + std::declval<Arg>() );
89  template < class Arg > using TryInPlaceSummation = decltype( std::declval<Arg>() += std::declval<Arg>() );
90 
91  template < class Arg , bool , class = void > struct Summation : std::false_type {};
92  template < class Arg , bool , class = void > struct InPlaceSummation : std::false_type {};
93 
94  template < class Arg > struct Summation< Arg , true , void_t< TrySummation<Arg> > > : std::true_type {};
95  template < class Arg > struct InPlaceSummation< Arg , true , void_t< TryInPlaceSummation<Arg> > > : std::true_type {};
96 
97 
98  // Access to vector or matrix entries
99  template <class Matrix>
100  using TryAccessViaSquareBracketsForMatrix = decltype(std::declval<Matrix>()[0][0]);
101 
102  template <class Vector>
103  using TryAccessViaSquareBracketsForVector = decltype(std::declval<Vector>()[0]);
104 
105  template <class Matrix>
106  using TryAccessViaRoundBracketsForMatrix = decltype(std::declval<Matrix>()(0,0));
107 
108  template <class Vector>
109  using TryAccessViaRoundBracketsForVector = decltype(std::declval<Vector>()(0));
110 
111  template < class Matrix, class = void > struct AccessViaSquareBracketsForMatrix : std::false_type {};
112  template <class Matrix> struct AccessViaSquareBracketsForMatrix< Matrix , void_t<TryAccessViaSquareBracketsForMatrix<Matrix> > > : std::true_type {};
113 
114  template < class Matrix, class = void > struct AccessViaRoundBracketsForMatrix : std::false_type {};
115  template <class Matrix> struct AccessViaRoundBracketsForMatrix< Matrix , void_t<TryAccessViaRoundBracketsForMatrix<Matrix> > > : std::true_type {};
116 
117  template < class Vector, class = void > struct AccessViaSquareBracketsForVector : std::false_type {};
118  template <class Vector> struct AccessViaSquareBracketsForVector< Vector , void_t<TryAccessViaSquareBracketsForVector<Vector> > > : std::true_type {};
119 
120  template < class Vector, class = void > struct AccessViaRoundBracketsForVector : std::false_type {};
121  template <class Vector> struct AccessViaRoundBracketsForVector< Vector , void_t<TryAccessViaRoundBracketsForVector<Vector> > > : std::true_type {};
122 
123 
124  // Update and updateVariable functions.
125  template < class F >
126  using TryCallOfUpdate = decltype(std::declval<F>().update(std::declval<int>()));
127 
128  template < class F >
129  using TryCallOfUpdateVariable = decltype(std::declval<F>().template updateVariable<0>(std::declval<int>()));
130 
131  template < class F , class = void > struct CallOfUpdate : std::false_type {};
132  template < class F , class = void > struct CallOfUpdateVariable : std::false_type {};
133 
134  template < class F > struct CallOfUpdate< F , void_t< TryCallOfUpdate<F> > > : std::true_type {};
135  template < class F > struct CallOfUpdateVariable< F , void_t< TryCallOfUpdateVariable<F> > > : std::true_type {};
145  template < class Arg , class ScalarArg >
146  constexpr bool multiplicationWithArithmeticFromLeft()
147  {
148  return MultiplicationWithArithmeticFromLeft<Arg,ScalarArg,!std::is_base_of<Base,Arg>() && !std::is_arithmetic<Arg>()>::value;
149  }
150 
155  template < class Arg , class ScalarArg >
156  constexpr bool multiplicationWithArithmeticFromRight()
157  {
158  return MultiplicationWithArithmeticFromRight<Arg,ScalarArg,!std::is_base_of<Base,Arg>() && !std::is_arithmetic<Arg>()>::value;
159  }
160 
165  template < class Arg , class ScalarArg >
166  constexpr bool inPlaceMultiplicationWithArithmetic()
167  {
168  return InPlaceMultiplicationWithArithmetic<Arg,ScalarArg,!std::is_base_of<Base,Arg>() && !std::is_arithmetic<Arg>()>::value;
169  }
170 
175  template < class Arg1 , class Arg2 >
176  constexpr bool multiplication()
177  {
178  return Multiplication<Arg1,Arg2,!std::is_base_of<Base,Arg1>() && !std::is_base_of<Base,Arg2>() && !std::is_arithmetic<Arg1>() && !std::is_arithmetic<Arg2>()>::value;
179  }
180 
185  template < class Arg1 , class Arg2 >
186  constexpr bool inPlaceMultiplication()
187  {
188  return InPlaceMultiplication<Arg1,Arg2,!std::is_base_of<Base,Arg1>() && !std::is_base_of<Base,Arg2>() && !std::is_arithmetic<Arg1>() && !std::is_arithmetic<Arg2>()>::value;
189  }
190 
195  template < class Arg1 , class Arg2 >
196  constexpr bool callToRightMultiply()
197  {
198  return CallToRightMultiply<Arg1,Arg2,!std::is_base_of<Base,Arg1>() && !std::is_base_of<Base,Arg2>() && !std::is_arithmetic<Arg1>() && !std::is_arithmetic<Arg2>()>::value;
199  }
200 
205  template < class Arg >
206  constexpr bool summation()
207  {
208  return Summation<Arg,!std::is_base_of<Base,Arg>() && !std::is_arithmetic<Arg>()>::value;
209  }
210 
215  template < class Arg >
216  constexpr bool inPlaceSummation()
217  {
218  return InPlaceSummation<Arg,!std::is_base_of<Base,Arg>() && !std::is_arithmetic<Arg>()>::value;
219  }
220 
227  template < class Arg >
228  constexpr bool isConstantSizeMatrix()
229  {
230  return ( LinearAlgebra::numberOfRows<Arg>() > 0 ) && ( LinearAlgebra::numberOfColumns<Arg>() > 0 );
231  }
232 
239  template < class Arg >
240  constexpr bool isStaticVector()
241  {
242  return ( LinearAlgebra::numberOfRows<Arg>() > 0 ) && ( LinearAlgebra::numberOfColumns<Arg>() == -1 );
243  }
244 
249  template < class Arg >
250  constexpr bool accessViaSquareBrackets()
251  {
252  return std::conditional_t< !isConstantSizeMatrix<Arg>() && isStaticVector<Arg>() ,
253  AccessViaSquareBracketsForVector<Arg> ,
254  AccessViaSquareBracketsForMatrix<Arg> >::value;
255  }
256 
261  template < class Arg >
262  constexpr bool accessViaRoundBrackets()
263  {
264  return std::conditional_t< !isConstantSizeMatrix<Arg>() && isStaticVector<Arg>() ,
265  AccessViaRoundBracketsForVector<Arg> ,
266  AccessViaRoundBracketsForMatrix<Arg> >::value;
267  }
268 
273  template < class F >
274  constexpr bool hasUpdateFunction()
275  {
276  return CallOfUpdate<F>::value;
277  }
278 
283  template < class F >
284  constexpr bool hasUpdateVariableFunction()
285  {
286  return CallOfUpdateVariable<F>::value;
287  }
288  }
289 }
290 
291 #endif // RFFGEN_STATIC_CHECKS_HH
typename Detail::voider< Types...>::type void_t
Most fascinating type ever. Is always void.
Definition: voider.hh:40