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