RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
at.hh
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_UTIL_AT_HH
22 #define RFFGEN_UTIL_AT_HH
23 
24 #include <type_traits>
25 #include <utility>
26 #include "staticChecks.hh"
27 
28 namespace RFFGen
29 {
33  namespace AtDetail
34  {
35 
36 
37  template <class Matrix, bool accessViaSquareBrackets, bool accessViaRoundBrackets, bool isMatrix>
38  struct ValueTypeImpl;
39 
40  template <class Matrix, bool accessViaRoundBrackets>
41  struct ValueTypeImpl<Matrix,true,accessViaRoundBrackets,true>
42  {
43  using type = decltype(std::declval<Matrix>()[0][0]);
44  };
45 
46  template <class Matrix>
47  struct ValueTypeImpl<Matrix,false,true,true>
48  {
49  using type = decltype(std::declval<Matrix>()(0,0));
50  };
51 
52  template <class Vector, bool accessViaRoundBrackets>
53  struct ValueTypeImpl<Vector,true,accessViaRoundBrackets,false>
54  {
55  using type = decltype(std::declval<Vector>()[0]);
56  };
57 
58  template <class Vector>
59  struct ValueTypeImpl<Vector,false,true,false>
60  {
61  using type = decltype(std::declval<Vector>()(0));
62  };
63 
64  template <class Matrix>
65  using ValueType = ValueTypeImpl<Matrix,Checks::accessViaSquareBrackets<Matrix>(),Checks::accessViaRoundBrackets<Matrix>(),Checks::isConstantSizeMatrix<Matrix>()>;
66 
67 
68  template <class Matrix, class = void>
69  struct At
70  {
71  static auto& apply(Matrix& A, int i, int j)
72  {
73  return A(i,j);
74  }
75  };
76 
77  template <class Matrix>
78  struct At< Matrix , void_t< Checks::TryAccessViaSquareBracketsForMatrix<Matrix> > >
79  {
80  static auto& apply(Matrix& A, int i, int j)
81  {
82  return A[i][j];
83  }
84  };
85 
86  template <class Vector, class = void>
87  struct At_v
88  {
89  static auto& apply(Vector& v, int i)
90  {
91  return v(i);
92  }
93  };
94 
95  template <class Vector>
96  struct At_v< Vector , void_t< Checks::AccessViaSquareBracketsForVector<Vector> > >
97  {
98  static auto& apply(Vector& v, int i)
99  {
100  return v[i];
101  }
102  };
103  }
104 
106  template <class Arg>
107  using at_t = typename AtDetail::ValueType<Arg>::type;
108 
109 
110  template <class Matrix>
111  __attribute__((always_inline)) auto& at(Matrix& A, int i, int j)
112  {
113  return AtDetail::At<Matrix>::apply(A,i,j);
114  }
115 
116  template <class Vector>
117  __attribute__((always_inline)) auto& at(Vector& v, int i)
118  {
119  return AtDetail::At_v<Vector>::apply(v,i);
120  }
124 }
125 
126 #endif // RFFGEN_UTIL_AT_HH
typename Detail::voider< Types...>::type void_t
Most fascinating type ever. Is always void.
Definition: voider.hh:40
Static checks for detection of presence of different operators and functions.