ATLAS Offline Software
Loading...
Searching...
No Matches
StackElement.icc
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5*/
6
7// $Id$
8#ifndef EXPRESSIONEVALUATION_STACKELEMENT_ICC
9#define EXPRESSIONEVALUATION_STACKELEMENT_ICC
10
11// System include(s):
12#include <cmath>
13#include <stdexcept>
14
15namespace ExpressionParsing {
16 inline StackElement::StackElement(const StackElement &a)
17 : m_type(a.m_type),
18 m_intVal(a.m_intVal),
19 m_doubleVal(a.m_doubleVal),
20 m_vecIntVal(a.m_vecIntVal),
21 m_vecDoubleVal(a.m_vecDoubleVal),
22 m_varName(a.m_varName),
23 m_proxyLoader(a.m_proxyLoader),
24 m_variableType(static_cast<IProxyLoader::VariableType>(a.m_variableType)),
25 m_determinedVariableType(a.m_determinedVariableType ? true : false)
26 {
27 if (a.m_moved) throw std::logic_error("Content already moved"); \
28 }
29 inline StackElement::StackElement(StackElement &&a)
30 : m_type(a.m_type),
31 m_intVal(a.m_intVal),
32 m_doubleVal(a.m_doubleVal),
33 m_vecIntVal(std::move(a.m_vecIntVal)),
34 m_vecDoubleVal(std::move(a.m_vecDoubleVal)),
35 m_varName(std::move(a.m_varName)),
36 m_proxyLoader(a.m_proxyLoader),
37 m_variableType(static_cast<IProxyLoader::VariableType>(a.m_variableType)),
38 m_determinedVariableType(a.m_determinedVariableType ? true : false)
39 {
40 if (a.m_moved) throw std::logic_error("Content already moved");
41 }
42
43 inline StackElement &StackElement::operator=(StackElement &&a) {
44 if (&a != this) {
45 if (a.m_moved) throw std::logic_error("Content already moved");
46 m_type = a.m_type;
47 m_intVal = a.m_intVal;
48 m_doubleVal = a.m_doubleVal;
49 m_vecIntVal = std::move(a.m_vecIntVal);
50 m_vecDoubleVal = std::move(a.m_vecDoubleVal);
51 m_varName = std::move(a.m_varName);
52 m_proxyLoader = a.m_proxyLoader;
53 m_variableType = static_cast<IProxyLoader::VariableType>(a.m_variableType);
54 m_determinedVariableType = a.m_determinedVariableType ? true : false;
55 m_moved = false;
56 }
57 return *this;
58 }
59
60 inline size_t StackElement::size() const {
61 switch( m_type ) {
62
63 case SE_VECINT:
64 return m_vecIntVal.size();
65 break;
66
67 case SE_VECDOUBLE:
68 return m_vecDoubleVal.size();
69 break;
70
71 case SE_INT: [[fallthrough]] ;
72 case SE_DOUBLE:
73 return 1; // @TOOD 0?
74 break;
75
76 default:
77 throw std::runtime_error( "size(): Unsupported StackElement" );
78 break;
79 }
80 }
81
82 /// Declare specialisations required in subsequent code
83 template<>
84 std::vector< int >
85 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
86 template<>
87 std::vector< double >
88 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
89
90
91
92#define ASSIGN_OP( OP ) \
93 template< typename T > \
94 StackElement& StackElement::operator OP( const T& rhs ) { \
95 makeDoubleIfNecessary( rhs ); \
96 switch( m_type ) { \
97 case SE_INT: \
98 m_intVal OP rhs; \
99 break; \
100 case SE_DOUBLE: \
101 m_doubleVal OP rhs; \
102 break; \
103 case SE_VECINT: \
104 for( int& value : m_vecIntVal ) { \
105 value OP rhs; \
106 } \
107 break; \
108 case SE_VECDOUBLE: \
109 for( double& value : m_vecDoubleVal ) { \
110 value OP rhs; \
111 } \
112 break; \
113 default: \
114 throw std::runtime_error( "StackElement ill-defined in " \
115 "scalar " #OP ); \
116 break; \
117 } \
118 return *this; \
119 } \
120 template< typename T > \
121 StackElement& \
122 StackElement::operator OP( const std::vector< T >& rhs ) { \
123 makeVectorIfNecessary( rhs ); \
124 makeDoubleIfNecessary( rhs ); \
125 ensureCompatibleVectors( rhs ); \
126 switch( m_type ) { \
127 case SE_VECINT: \
128 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
129 m_vecIntVal[ i ] OP rhs[ i ]; \
130 } \
131 break; \
132 case SE_VECDOUBLE: \
133 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
134 m_vecDoubleVal[i] OP rhs[ i ]; \
135 } \
136 break; \
137 default: \
138 throw std::runtime_error( "StackElement ill-defined in " \
139 "vector " #OP ); \
140 break; \
141 } \
142 return *this; \
143 } \
144
145 ASSIGN_OP( -= )
146 ASSIGN_OP( += )
147 ASSIGN_OP( *= )
148 ASSIGN_OP( /= )
149
150#undef ASSIGN_OP
151
152#define BINARY_MUTING_OP( OP ) \
153 template< typename T > \
154 StackElement StackElement::operator OP( const T& rhs ) { \
155 if (this->m_moved) throw std::logic_error("Content already moved");\
156 StackElement temp( std::move(*this) ); \
157 this->m_moved=true; \
158 temp OP ## = rhs; \
159 return temp; \
160 }
161
162 BINARY_MUTING_OP( - )
163 BINARY_MUTING_OP( + )
164 BINARY_MUTING_OP( * )
165 BINARY_MUTING_OP( / )
166
167#undef BINARY_MUTING_OP
168
169 template< typename T >
170 std::vector< T > StackElement::vectorValue( std::size_t ) {
171
172 throw std::runtime_error( "Unsupported vector type requested" );
173 }
174
175 template< typename T >
176 StackElement StackElement::_pow( const T& n ) {
177
178 if (this->m_moved) throw std::logic_error("Content already moved");
179 StackElement temp( std::move(*this) );
180 this->m_moved=true;
181 temp.makeDouble();
182
183 switch( temp.m_type ) {
184
185 case SE_DOUBLE:
186 temp.m_doubleVal = std::pow( temp.m_doubleVal, n );
187 return temp;
188 break;
189
190 case SE_VECDOUBLE:
191 for( std::size_t i = 0; i < temp.m_vecDoubleVal.size(); ++i ) {
192 temp.m_vecDoubleVal[ i ] = std::pow( temp.m_vecDoubleVal[ i ], n );
193 }
194 return temp;
195 break;
196
197 default:
198 return 0;
199 break;
200 }
201 }
202
203 template<>
204 StackElement StackElement::_pow( const StackElement& n );
205
206 template< typename T >
207 T StackElement::scalarValue() const {
208
209 switch( m_type ) {
210
211 case SE_INT:
212 return m_intVal;
213 break;
214
215 case SE_DOUBLE:
216 return m_doubleVal;
217 break;
218
219 case SE_VECINT:
220 case SE_VECDOUBLE:
221 case SE_UNK:
222 default:
223 throw std::runtime_error( "Trying to cast vector to scalar!" );
224 break;
225 }
226 }
227
228 template< typename T >
229 void StackElement::ensureCompatibleVectors( const T& ) const {
230
231 throw std::runtime_error( "Can't compare vector to arbitrary type!" );
232 }
233
234 template< typename T >
235 void StackElement::
236 ensureCompatibleVectors( const std::vector< T >& other ) const {
237
238 if( isScalar() ) {
239 return;
240 }
241
242 const std::size_t ourlen = this->size();
243 if( ourlen != other.size() ) {
244 throw std::runtime_error( "Incompatible vectors - different length" );
245 }
246 }
247
248} // namespace ExpressionParsing
249
250#endif // EXPRESSIONEVALUATION_STACKELEMENT_ICC