1// Dear emacs, this is -*- c++ -*-
4 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
8#ifndef EXPRESSIONEVALUATION_STACKELEMENT_ICC
9#define EXPRESSIONEVALUATION_STACKELEMENT_ICC
15namespace 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(IAccessor::VT_UNK) // cannot copy the accessor cache, so have to recet variable type
26 if (a.m_moved) throw std::logic_error("Content already moved"); \
28 inline StackElement::StackElement(StackElement &&a)
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
38 if (a.m_moved) throw std::logic_error("Content already moved");
41 inline StackElement &StackElement::operator=(StackElement &&a) {
43 if (a.m_moved) throw std::logic_error("Content already moved");
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;
57 inline size_t StackElement::size() const {
61 return m_vecIntVal.size();
65 return m_vecDoubleVal.size();
68 case SE_INT: [[fallthrough]] ;
74 throw std::runtime_error( "size(): Unsupported StackElement" );
79 /// Declare specialisations required in subsequent code
82 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
85 StackElement::vectorValue( std::size_t sizeIfScalar ) ;
89#define ASSIGN_OP( OP ) \
90 template< typename T > \
91 StackElement& StackElement::operator OP( const T& rhs ) { \
92 makeDoubleIfNecessary( rhs ); \
101 for( int& value : m_vecIntVal ) { \
106 for( double& value : m_vecDoubleVal ) { \
111 throw std::runtime_error( "StackElement ill-defined in " \
117 template< typename T > \
119 StackElement::operator OP( const std::vector< T >& rhs ) { \
120 makeVectorIfNecessary( rhs ); \
121 makeDoubleIfNecessary( rhs ); \
122 ensureCompatibleVectors( rhs ); \
125 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
126 m_vecIntVal[ i ] OP rhs[ i ]; \
130 for( std::size_t i = 0; i < rhs.size(); ++i ) { \
131 m_vecDoubleVal[i] OP rhs[ i ]; \
135 throw std::runtime_error( "StackElement ill-defined in " \
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; \
159 BINARY_MUTING_OP( - )
160 BINARY_MUTING_OP( + )
161 BINARY_MUTING_OP( * )
162 BINARY_MUTING_OP( / )
164#undef BINARY_MUTING_OP
166 template< typename T >
167 std::vector< T > StackElement::vectorValue( std::size_t ) {
169 throw std::runtime_error( "Unsupported vector type requested" );
172 template< typename T >
173 StackElement StackElement::_pow( const T& n ) {
175 if (this->m_moved) throw std::logic_error("Content already moved");
176 StackElement temp( std::move(*this) );
180 switch( temp.m_type ) {
183 temp.m_doubleVal = std::pow( temp.m_doubleVal, n );
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 );
201 StackElement StackElement::_pow( const StackElement& n );
203 template< typename T >
204 T StackElement::scalarValue() const {
220 throw std::runtime_error( "Trying to cast vector to scalar!" );
225 template< typename T >
226 void StackElement::ensureCompatibleVectors( const T& ) const {
228 throw std::runtime_error( "Can't compare vector to arbitrary type!" );
231 template< typename T >
233 ensureCompatibleVectors( const std::vector< T >& other ) const {
239 const std::size_t ourlen = this->size();
240 if( ourlen != other.size() ) {
241 throw std::runtime_error( "Incompatible vectors - different length" );
245} // namespace ExpressionParsing
247#endif // EXPRESSIONEVALUATION_STACKELEMENT_ICC