ATLAS Offline Software
Loading...
Searching...
No Matches
StackElement.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id$
6
7// System include(s):
8#include <cmath>
9#include <iostream>
10#include <stdexcept>
11#include <algorithm>
12#include <cassert>
13
14// Local include(s):
16
17namespace {
18
19 template< typename T >
20 std::ostream& operator <<( std::ostream& os, const std::vector< T >& vec ) {
21
22 os << '[';
23 for( std::size_t i = 0; i < vec.size(); ++i ) {
24 os << vec[ i ];
25 if( ( i + 1 ) < vec.size() ) {
26 os << ", ";
27 }
28 }
29 os << ']';
30
31 return os;
32 }
33
34} // private namespace
35
36namespace ExpressionParsing {
37
38
40
41 m_type = SE_INT;
42 m_intVal = rhs;
43 m_doubleVal = 0;
44 m_vecIntVal.clear();
45 m_vecDoubleVal.clear();
46 m_moved = false;
47
48 return *this;
49 }
50
52
54 m_intVal = 0;
55 m_doubleVal = rhs;
56 m_vecIntVal.clear();
57 m_vecDoubleVal.clear();
58 m_moved = false;
59
60 return *this;
61 }
62
63
64 StackElement& StackElement::operator=( const std::vector< int >& rhs ) {
65
67 m_intVal = 0;
68 m_doubleVal = 0;
69 m_vecIntVal = rhs;
70 m_vecDoubleVal.clear();
71 m_moved = false;
72
73 return *this;
74 }
75 StackElement& StackElement::operator=( std::vector< int >&& rhs ) {
76
78 m_intVal = 0;
79 m_doubleVal = 0;
80 m_vecIntVal = std::move(rhs);
81 m_vecDoubleVal.clear();
82 m_moved = false;
83
84 return *this;
85 }
86 StackElement& StackElement::operator=( const std::vector< double >& rhs ) {
87
89 m_intVal = 0;
90 m_doubleVal = 0;
91 m_vecIntVal.clear();
92 m_vecDoubleVal = rhs;
93 m_moved = false;
94
95 return *this;
96 }
97
98 StackElement& StackElement::operator=( std::vector< double >&& rhs ) {
99
101 m_intVal = 0;
102 m_doubleVal = 0;
103 m_vecIntVal.clear();
104 m_vecDoubleVal = std::move(rhs);
105 m_moved = false;
106
107 return *this;
108 }
109
111
112 // Create a copy of the object:
113 if (this->m_moved) throw std::logic_error("Content already moved");
114 StackElement temp( std::move(*this) );
115 this->m_moved=true;
116 // ...and modify its payload appropriately:
117 switch( m_type ) {
118
119 case SE_INT:
120 temp.m_intVal = !( temp.m_intVal );
121 break;
122
123 case SE_DOUBLE:
124 // temp.makeInt();
125 temp.m_intVal = !( temp.m_doubleVal );
126 break;
127
128 case SE_VECINT:
129 for( std::size_t i = 0; i < temp.m_vecIntVal.size(); ++i ) {
130 temp.m_vecIntVal[ i ] = !( temp.m_vecIntVal[ i ] );
131 }
132 break;
133
134 case SE_VECDOUBLE:
135 // temp.makeInt();
136 temp.m_vecIntVal.resize(temp.m_vecDoubleVal.size());
137 for( std::size_t i = 0; i < temp.m_vecDoubleVal.size(); ++i ) {
138 temp.m_vecIntVal[ i ] = !( temp.m_vecDoubleVal[ i ] ); // @TODO use >0. ?
139 }
140 break;
141
142 default:
143 throw std::runtime_error( "! operator called on unknown "
144 "variable type" );
145 break;
146 }
147
148 // Return the negated object:
149 return temp;
150 }
151
153
154 // Create a copy of the object:
155 if (this->m_moved) throw std::logic_error("Content already moved");
156 StackElement temp( std::move(*this) );
157 this->m_moved=true;
158
159 // ...and modify its payload appropriately:
160 switch( m_type ) {
161
162 case SE_INT:
163 temp.m_intVal = -( this->m_intVal );
164 break;
165
166 case SE_DOUBLE:
167 temp.m_doubleVal = -( this->m_doubleVal );
168 break;
169
170 case SE_VECINT:
171 for( std::size_t i = 0; i < temp.m_vecIntVal.size(); ++i ) {
172 temp.m_vecIntVal[ i ] = -( temp.m_vecIntVal[ i ] );
173 }
174 break;
175
176 case SE_VECDOUBLE:
177 for( std::size_t i = 0; i < temp.m_vecDoubleVal.size(); ++i ) {
178 temp.m_vecDoubleVal[ i ] = -( temp.m_vecDoubleVal[ i ] );
179 }
180 break;
181
182 default:
183 throw std::runtime_error( "- operator called on unknown "
184 "variable type" );
185 break;
186 }
187
188 // Return the inverted object:
189 return temp;
190 }
191
193#define IMPL_ASSIGN_OP( OP ) \
194 StackElement& StackElement::operator OP( StackElement& rhs ) { \
195 makeVectorIfNecessary( rhs ); \
196 makeDoubleIfNecessary( rhs ); \
197 switch( m_type ) { \
198 case SE_INT: \
199 m_intVal OP rhs.scalarValue< int >(); \
200 break; \
201 case SE_DOUBLE: \
202 m_doubleVal OP rhs.scalarValue< double >(); \
203 break; \
204 case SE_VECINT: \
205 *this OP rhs.vectorValue< int >( m_vecIntVal.size() ); \
206 break; \
207 case SE_VECDOUBLE: \
208 *this OP rhs.vectorValue< double >( m_vecDoubleVal.size() ); \
209 break; \
210 default: \
211 throw std::runtime_error( "StackElement ill-defined in " \
212 #OP ); \
213 break; \
214 } \
215 return *this; \
216 }
217
218 IMPL_ASSIGN_OP( -= )
219 IMPL_ASSIGN_OP( += )
220 IMPL_ASSIGN_OP( *= )
221 IMPL_ASSIGN_OP( /= )
222
224#undef IMPL_ASSIGN_OP
225
230
232
233 return ( ( m_type == SE_INT ) || ( m_type == SE_DOUBLE ) );
234 }
235
237
238 return ( ( m_type == SE_VECINT ) || ( m_type == SE_VECDOUBLE ) );
239 }
240
242
243 return ( m_varName.length() > 0 );
244 }
245
247
248 if( m_type != SE_INT ) {
249 throw std::runtime_error( "asInt() only valid for SE_INT" );
250 }
251
252 return scalarValue< int >();
253 }
254
255 bool StackElement::asBool() const {
256
257 if( ! ( ( m_type == SE_INT ) || ( m_type == SE_DOUBLE ) ) ) {
258 throw std::runtime_error( "asBool() only valid for non-vector types" );
259 }
260
261 return scalarValue< bool >();
262 }
263
264 template<>
265 std::vector< int >
266 StackElement::vectorValue( std::size_t sizeIfScalar ) {
267
268 if (this->m_moved) throw std::logic_error("Content already moved");
269 switch( m_type ) {
270
271 case SE_VECINT:
272 this->m_moved=true;
273 return std::move(m_vecIntVal);
274 break;
275
276 case SE_VECDOUBLE: {
277 std::vector<int> ret(m_vecDoubleVal.size());
278 std::transform (m_vecDoubleVal.begin(), m_vecDoubleVal.end(), ret.begin(), [](const double &a) -> int { return static_cast<int>(a);});
279 break;
280 }
281 case SE_INT: {
282 return std::vector<int>( sizeIfScalar, m_intVal );
283 break;
284 }
285 case SE_DOUBLE:{
286 return std::vector<int>( sizeIfScalar,static_cast< int >( m_doubleVal ) );
287 break;
288 }
289 default:
290 throw std::runtime_error( "(int) vectorValue(): Unsupported "
291 "StackElement" );
292 break;
293 }
294 return std::vector<int>();
295 }
296
297 template<>
298 std::vector< double >
299 StackElement::vectorValue( size_t sizeIfScalar ) {
300
301 if (this->m_moved) throw std::logic_error("Content already moved");
302 switch( m_type ) {
303
304 case SE_VECINT: {
305 std::vector<double> ret(m_vecIntVal.size());
306 std::transform (m_vecIntVal.begin(), m_vecIntVal.end(), ret.begin(), [](int a) -> double { return a;});
307 return ret;
308 break;
309 }
310 case SE_VECDOUBLE:
311 m_moved=true;
312 return std::move(m_vecDoubleVal);
313 break;
314
315 case SE_INT: {
316 return std::vector<double>(sizeIfScalar,static_cast< double >( m_intVal ) );
317 break;
318 }
319 case SE_DOUBLE: {
320 return std::vector<double>(sizeIfScalar, m_doubleVal );
321 break;
322 }
323 default:
324 throw std::runtime_error( "(dbl) vectorValue(): Unsupported "
325 "StackElement" );
326 break;
327 }
328 return std::vector<double>();
329 }
330
332
333 if( m_type == SE_DOUBLE ) {
334 m_type = SE_INT;
336 } else if( m_type == SE_VECDOUBLE ) {
338 m_vecIntVal.clear();
339 for( auto& value : m_vecDoubleVal ) {
340 m_vecIntVal.push_back( static_cast< int >( value ) );
341 }
342 }
343
344 return;
345 }
346
348
349 if( m_type == SE_INT ) {
352 } else if( m_type == SE_VECINT ) {
354 m_vecDoubleVal.clear();
355 for( auto& value : m_vecIntVal ) {
356 m_vecDoubleVal.push_back( static_cast< double >( value ) );
357 }
358 }
359
360 return;
361 }
362
363 void StackElement::makeVector( std::size_t n ) {
364
365 if( isVector() ) {
366 return;
367 }
368
369 if( m_type == SE_INT ) {
371 m_vecIntVal.clear();
372 m_vecIntVal.resize( n, m_intVal );
373 } else if( m_type == SE_DOUBLE ) {
375 m_vecDoubleVal.clear();
376 m_vecDoubleVal.resize( n, m_doubleVal );
377 }
378
379 return;
380 }
381
382 StackElement StackElement::valueFromProxy([[maybe_unused]] const EventContext& ctx) const {
383
384 StackElement tmp;
385 if( ! isProxy() ) {
386 return tmp;
387 }
388
389 IAccessor::VariableType the_variable_type=m_variableType.load(std::memory_order_seq_cst);
390 if( the_variable_type==IProxyLoader::VT_UNK) {
391 auto [variable_type, accessor] = m_proxyLoader->getAccessorFromString(ctx, m_varName);
392 // if ( m_variableType != IProxyLoader::VT_UNK) {
393 if (variable_type != IProxyLoader::VT_VECEMPTY) {
394 // do not cache the accessor and variable type if it was an empty vector because
395 // in such cases there is not enough information to decide the variable type.
396 // otherwise set the accessor if still unset and set the variable type.
397 // Other threads would come to the same conclusion in case the vector is not empty
398 // (or empty), so which thread sets the variable type and/or accessor does not matter.
399 m_accessor.setIfUnset(accessor);
400 m_variableType.store(variable_type, std::memory_order_seq_cst);
401 }
402 // for the current event what ever getAccessorFromString returned is a good choice
403 // independent of other threads which might have had more information for a final
404 // decision. So, for this evaluation what ever getAccessorFromString returned will
405 // be used.
406 the_variable_type = variable_type;
407 }
408 assert((the_variable_type == IProxyLoader::VT_UNK || the_variable_type == IProxyLoader::VT_VECEMPTY || m_accessor == true) );
409
410 switch( the_variable_type ) {
412 tmp = m_accessor->loadInt(ctx, m_varName );
413 break;
414
416 tmp = m_accessor->loadDouble(ctx, m_varName );
417 break;
418
420 tmp = m_accessor->loadVecInt(ctx, m_varName );
421 break;
422
424 tmp = m_accessor->loadVec(ctx, m_varName );
425 break;
426 }
428 tmp=std::vector<double>();
429 break;
431 default:
432 throw std::runtime_error( "Got VT_UNK - unknown identifier: " +
433 m_varName );
434 break;
435 }
436
437 return tmp;
438 }
439
440
441 template <class T_CompHelper, class T>
442 std::vector<int> compareVector(std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
443 {
444 std::vector<int> ret;
445 ret.resize(a.size());
446 assert( a.size() == b.size() );
447 for (std::size_t idx=0; idx < a.size(); ++idx) {
448 ret[idx] = helper.compare(a[idx],b[idx]);
449 }
450 return ret;
451 }
452 template <class T_CompHelper, class T>
453 std::vector<int> compareVectorAlt(const std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
454 {
455 return compareVectorAlt(a,b,helper);
456 }
457
458 template <class T_CompHelper>
459 std::vector<int> compareVector(std::vector<int> &&a, const std::vector<int> &&b,T_CompHelper helper)
460 {
461 assert( a.size() == b.size() );
462 for (std::size_t idx=0; idx < a.size(); ++idx) {
463 a[idx] = helper.compare(a[idx],b[idx]);
464 }
465 return std::vector<int>(std::move(a));
466 }
467
468 template <class T_CompHelper>
469 std::vector<int> compareVectorAlt(const std::vector<int> &&a, std::vector<int> &&b,T_CompHelper helper)
470 {
471 assert( a.size() == b.size() );
472 for (std::size_t idx=0; idx < a.size(); ++idx) {
473 b[idx] = helper.compare(a[idx],b[idx]);
474 }
475 return std::vector<int>(std::move(b));
476 }
477
478 template <class T_CompHelper>
479 StackElement StackElement::_comparisonOp(StackElement &other, T_CompHelper comp_helper)
480 {
481 if (m_type ==SE_UNK || other.m_type==SE_UNK) {
482 throw std::runtime_error( "ERROR: Can't operate on SE_UNK "
483 "StackElements");
484 }
485 if( isScalar() && other.isScalar() ) {
486 if( m_type == SE_INT && other.m_type == SE_INT ) {
487 return comp_helper.compare(scalarValue< int >(),other.scalarValue< int >() );
488 } else {
489 return comp_helper.compare(scalarValue< double >(),other.scalarValue< double >() );
490 }
491 } else {
492 if (isVector() && other.isVector() && this->size() != other.size()) {
493 throw std::runtime_error( "Incompatible vectors - different length" );
494 }
495 std::size_t the_size = ( m_type == SE_VECINT || m_type==SE_VECDOUBLE) ? this->size() : other.size();
496 if( ( m_type == SE_VECINT)
497 && ( other.m_type == SE_VECINT || other.m_type == SE_INT )) {
498 return compareVector( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
499 }
500 else if( m_type == SE_INT && other.m_type == SE_VECINT) {
501 return compareVectorAlt( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
502 }
503 else {
504 return compareVector( this->vectorValue<double>(the_size) , other.vectorValue< double >(the_size), comp_helper );
505 }
506 }
507 }
508
509 class Helper_eq { public: template <class T> int compare(const T &a, const T &b) { return a == b; } };
510 class Helper_neq { public: template <class T> int compare(const T &a, const T &b) { return a != b; } };
511 class Helper_and { public: template <class T> int compare(const T &a, const T &b) { return a && b; } };
512 class Helper_or { public: template <class T> int compare(const T &a, const T &b) { return a || b; } };
513 class Helper_gt { public: template <class T> int compare(const T &a, const T &b) { return a > b; } };
514 class Helper_gte { public: template <class T> int compare(const T &a, const T &b) { return a >= b; } };
515 class Helper_lt { public: template <class T> int compare(const T &a, const T &b) { return a < b; } };
516 class Helper_lte { public: template <class T> int compare(const T &a, const T &b) { return a <= b; } };
517
526
527
528 template <>
530
531 if( n.isVector() ) {
532 throw std::runtime_error( "Can't use vector as exponent" );
533 } else {
534 return _pow( n.scalarValue< double >() );
535 }
536 }
537
539
540 switch( m_type ) {
541
542 case SE_INT:
543 return m_intVal;
544 break;
545
546 case SE_DOUBLE:
547 return m_doubleVal;
548 break;
549
550 case SE_VECINT:
551 {
552 int total = 0;
553 for( int value : m_vecIntVal ) {
554 total += value;
555 }
556 return total;
557 }
558 break;
559
560 case SE_VECDOUBLE:
561 {
562 double total = 0.0;
563 for( double value : m_vecDoubleVal ) {
564 total += value;
565 }
566 return total;
567 }
568 break;
569
570 default:
571 return 0;
572 break;
573 }
574 }
575
577
578 switch( m_type ) {
579
580 case SE_INT:
581 return !!( m_intVal );
582 break;
583
584 case SE_DOUBLE:
585 return !!( m_doubleVal );
586 break;
587
588 case SE_VECINT:
589 {
590 int total = 0;
591 for( int value : m_vecIntVal ) {
592 total += !!value;
593 }
594 return total;
595 }
596 break;
597
598 case SE_VECDOUBLE:
599 {
600 int total = 0;
601 for( double value : m_vecDoubleVal ) {
602 total += !!value;
603 }
604 return total;
605 }
606 break;
607
608 default:
609 return 0;
610 break;
611 }
612 }
613
615 if (this->m_moved) throw std::logic_error("Content already moved");
616
617 StackElement temp(std::move(*this));
618 this->m_moved=true;
619 switch( m_type ) {
620
621 case SE_INT:
622 m_intVal = std::abs( temp.m_intVal );
623 break;
624
625 case SE_DOUBLE:
626 m_doubleVal = std::abs( temp.m_doubleVal );
627 break;
628
629 case SE_VECINT:
630 {
631 for( int &value : temp.m_vecIntVal ) {
632 value = std::abs( value );
633 }
634 }
635 break;
636
637 case SE_VECDOUBLE:
638 {
639 for( double &value : temp.m_vecDoubleVal ) {
640 value = std::abs( value );
641 }
642 }
643 break;
644
645 default:
646 // @throw exception ?
647 break;
648 }
649 return temp;
650 }
651
653#define UNARY_MATH_FUNCTION( FUNC, BASEFUNC ) \
654 StackElement StackElement::FUNC() { \
655 if (this->m_moved) throw std::logic_error("Content already moved");\
656 StackElement temp( std::move(*this) ); \
657 this->m_moved=true; \
658 temp.makeDouble(); \
659 if( temp.m_type == SE_DOUBLE ) { \
660 temp.m_doubleVal = BASEFUNC( temp.m_doubleVal ); \
661 return temp; \
662 } else if( temp.m_type == SE_VECDOUBLE ) { \
663 for( double& value : temp.m_vecDoubleVal ) { \
664 value = BASEFUNC( value ); \
665 } \
666 return temp; \
667 } else { \
668 /* @TODO throw exception */ \
669 return temp; \
670 } \
671 }
672
673 UNARY_MATH_FUNCTION( _sqrt, sqrt )
674 UNARY_MATH_FUNCTION( _cbrt, cbrt )
675 UNARY_MATH_FUNCTION( _sin, sin )
676 UNARY_MATH_FUNCTION( _cos, cos )
677 UNARY_MATH_FUNCTION( _tan, tan )
678 UNARY_MATH_FUNCTION( _asin, asin )
679 UNARY_MATH_FUNCTION( _acos, acos )
680 UNARY_MATH_FUNCTION( _atan, atan )
681 UNARY_MATH_FUNCTION( _sinh, sinh )
682 UNARY_MATH_FUNCTION( _cosh, cosh )
683 UNARY_MATH_FUNCTION( _tanh, tanh )
684 UNARY_MATH_FUNCTION( _asinh, asinh )
685 UNARY_MATH_FUNCTION( _acosh, acosh )
686 UNARY_MATH_FUNCTION( _atanh, atanh )
687 UNARY_MATH_FUNCTION( _log, log )
688 UNARY_MATH_FUNCTION( _exp, exp )
689
690
691#undef UNARY_MATH_FUNCTION
692
694
695 if( isVector() ) {
696 return;
697 }
698 if( other.isVector() ) {
699 makeVector( other.size() );
700 }
701
702 return;
703 }
704
705 void StackElement::makeVectorIfNecessary(const std::vector< int >& other ) {
706
707 if( isVector() ) {
708 return;
709 }
710 makeVector( other.size() );
711
712 return;
713 }
714
715 void
716 StackElement::makeVectorIfNecessary( const std::vector< double >& other ) {
717
718 if( isVector() ) {
719 return;
720 }
721 makeVector( other.size() );
722
723 return;
724 }
725
727
728 if( ( m_type == SE_INT ) && ( other.m_type == SE_DOUBLE ) ) {
729 makeDouble();
730 } else if( ( m_type == SE_VECINT ) && ( other.m_type == SE_VECDOUBLE ) ) {
731 makeDouble();
732 }
733
734 return;
735 }
736
738
739 return;
740 }
741
743
744 if( m_type == SE_INT ) {
745 makeDouble();
746 }
747
748 return;
749 }
750
751 void StackElement::makeDoubleIfNecessary( const std::vector< int >& ) {
752
753 return;
754 }
755
756 void StackElement::makeDoubleIfNecessary( const std::vector< double >& ) {
757
758 if( m_type == SE_VECINT ) {
759 makeDouble();
760 }
761
762 return;
763 }
764
765 void StackElement::ensureCompatible( const StackElement& other ) const {
766
767 if( this->m_type != other.m_type ) {
768 throw std::runtime_error( "Incompatible stack elements" );
769 }
770
771 return;
772 }
773
774 template<>
775 void
777
778 if( isScalar() ) {
779 return;
780 }
781
782 const std::size_t ourlen = size();
783 if( ourlen != other.size() ) {
784 throw std::runtime_error( "Incompatible vectors - different length" );
785 }
786 }
787
788 std::ostream &operator<<( std::ostream& os,
789 const StackElement& el ) {
790
791 switch( el.m_type ) {
792
794 os << "(int)" << el.m_intVal;
795 break;
796
798 os << "(double)" << el.m_doubleVal;
799 break;
800
802 os << "(vec<int>)" << el.m_vecIntVal;
803 break;
804
806 os << "(vec<double>)" << el.m_vecDoubleVal;
807 break;
808
810 os << "SE_UNK";
811 break;
812
813 default:
814 break;
815 }
816
817 return os;
818 }
819
820} // namespace ExpressionParsing
std::vector< size_t > vec
static Double_t a
#define IMPL_ASSIGN_OP(OP)
Helper macro implementing the assignment operator specialisations.
#define UNARY_MATH_FUNCTION(FUNC, BASEFUNC)
Helper macro for implementing many of the mathematical functions.
std::ostream & operator<<(std::ostream &lhs, const TestGaudiProperty &rhs)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
int compare(const T &a, const T &b)
std::string m_varName
The name/definition of the variable.
int asInt() const
Get the internal value of the object as an integer.
bool isVector() const
Check if the object describes a vector value.
IProxyLoader * m_proxyLoader
Loader for the described variable.
std::vector< double > m_vecDoubleVal
The value of the object represented as a vector of doubles.
std::vector< T > vectorValue(std::size_t sizeIfScalar=0)
Evaluate the value of the object into the requested vector type.
StackElement _gt(StackElement &other)
void makeDouble()
Function constructing internal double values in case integer values were given to the object initiall...
StackElement _comparisonOp(StackElement &other, T_CompHelper comp_helper)
StackElement operator!()
NOT operator.
bool isProxy() const
Check if the object takes its value from a StoreGate object.
StackElement _lt(StackElement &other)
std::atomic< bool > m_moved
Internal flag showing whether the type of the variable was already determined.
StackElement & operator=(int rhs)
Operator assigning an integer value to the object.
StackElement _pow(const T &n)
Function raising the object's value to the n'th power.
bool asBool() const
Get the internal value of the object as a boolean.
T scalarValue() const
Evaluate the value of the object into the requested scalar type.
StackElement _eq(StackElement &other)
bool isScalar() const
Check if the object describes a scalar value.
ElementType
Type of the data held by this object.
@ SE_UNK
The type is not known, or not applicable.
@ SE_INT
The type is an integer.
@ SE_DOUBLE
The type is a double.
@ SE_VECINT
The type is a vector of integers.
@ SE_VECDOUBLE
The type is a vector of doubles.
void makeVectorIfNecessary(const StackElement &other)
The macro is not needed anymore:
StackElement _neq(StackElement &other)
StackElement _abs()
Function taking the absolute value of the object.
StackElement valueFromProxy(const EventContext &ctx) const
Set the internal variables of the object based on the objects in SG.
StackElement _or(StackElement &other)
StackElement _and(StackElement &other)
StackElement _sum()
Function calculating a sum value.
void ensureCompatibleVectors(const T &other) const
ElementType m_type
The type of the variable held by the object.
int m_intVal
The value of the object represented as an integer.
StackElement operator-()
Inverse operator.
void makeVector(std::size_t n)
Function converting a possibly scalar value into a vector.
StackElement _count()
Function counting elements.
ElementType getType() const
Get the variable type of the object.
StackElement()
Default constructor.
void ensureCompatible(const StackElement &other) const
std::vector< int > m_vecIntVal
The value of the object represented as a vector of integers.
StackElement _gte(StackElement &other)
std::atomic< IAccessor::VariableType > m_variableType
Type of the variable provided by the proxy loader.
void makeInt()
Function constructing internal integer values in case double values were given to the object initiall...
double m_doubleVal
The value of the object represented as a double.
void makeDoubleIfNecessary(const StackElement &other)
StackElement _lte(StackElement &other)
Namespace holding all the expression evaluation code.
std::ostream & operator<<(std::ostream &os, const StackElement &el)
Declare an output operator for StackElement objects.
std::vector< int > compareVectorAlt(const std::vector< T > &&a, std::vector< T > &&b, T_CompHelper helper)
std::vector< int > compareVector(std::vector< T > &&a, std::vector< T > &&b, T_CompHelper helper)