1 // Dear emacs, this is -*- c++ -*-
4 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
8 #ifndef EXPRESSIONEVALUATION_STACKELEMENT_ICC
9 #define EXPRESSIONEVALUATION_STACKELEMENT_ICC
15 namespace ExpressionParsing {
16 inline StackElement::StackElement(const StackElement &a)
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)
27 if (a.m_moved) throw std::logic_error("Content already moved"); \
29 inline StackElement::StackElement(StackElement &&a)
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)
40 if (a.m_moved) throw std::logic_error("Content already moved");
43 inline StackElement &StackElement::operator=(StackElement &&a) {
45 if (a.m_moved) throw std::logic_error("Content already moved");
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;
60 inline size_t StackElement::size() const {
64 return m_vecIntVal.size();
68 return m_vecDoubleVal.size();
71 case SE_INT: [[fallthrough]] ;
77 throw std::runtime_error( "size(): Unsupported StackElement" );
82 /// Declare specialisations required in subsequent code
85 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
88 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
92 #define ASSIGN_OP( OP ) \
93 template< typename T > \
94 StackElement& StackElement::operator OP( const T& rhs ) { \
95 makeDoubleIfNecessary( rhs ); \
101 m_doubleVal OP rhs; \
104 for( int& value : m_vecIntVal ) { \
109 for( double& value : m_vecDoubleVal ) { \
114 throw std::runtime_error( "StackElement ill-defined in " \
120 template< typename T > \
122 StackElement::operator OP( const std::vector< T >& rhs ) { \
123 makeVectorIfNecessary( rhs ); \
124 makeDoubleIfNecessary( rhs ); \
125 ensureCompatibleVectors( rhs ); \
128 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
129 m_vecIntVal[ i ] OP rhs[ i ]; \
133 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
134 m_vecDoubleVal[i] OP rhs[ i ]; \
138 throw std::runtime_error( "StackElement ill-defined in " \
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; \
162 BINARY_MUTING_OP( - )
163 BINARY_MUTING_OP( + )
164 BINARY_MUTING_OP( * )
165 BINARY_MUTING_OP( / )
167 #undef BINARY_MUTING_OP
169 template< typename T >
170 std::vector< T > StackElement::vectorValue( std::size_t ) {
172 throw std::runtime_error( "Unsupported vector type requested" );
175 template< typename T >
176 StackElement StackElement::_pow( const T& n ) {
178 if (this->m_moved) throw std::logic_error("Content already moved");
179 StackElement temp( std::move(*this) );
183 switch( temp.m_type ) {
186 temp.m_doubleVal = std::pow( temp.m_doubleVal, n );
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 );
204 StackElement StackElement::_pow( const StackElement& n );
206 template< typename T >
207 T StackElement::scalarValue() const {
223 throw std::runtime_error( "Trying to cast vector to scalar!" );
228 template< typename T >
229 void StackElement::ensureCompatibleVectors( const T& ) const {
231 throw std::runtime_error( "Can't compare vector to arbitrary type!" );
234 template< typename T >
236 ensureCompatibleVectors( const std::vector< T >& other ) const {
242 const std::size_t ourlen = this->size();
243 if( ourlen != other.size() ) {
244 throw std::runtime_error( "Incompatible vectors - different length" );
248 } // namespace ExpressionParsing
250 #endif // EXPRESSIONEVALUATION_STACKELEMENT_ICC