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 return std::vector<double>(m_vecIntVal.begin(), m_vecIntVal.end());
306 break;
307 }
308 case SE_VECDOUBLE:
309 m_moved=true;
310 return std::move(m_vecDoubleVal);
311 break;
312
313 case SE_INT: {
314 return std::vector<double>(sizeIfScalar,static_cast< double >( m_intVal ) );
315 break;
316 }
317 case SE_DOUBLE: {
318 return std::vector<double>(sizeIfScalar, m_doubleVal );
319 break;
320 }
321 default:
322 throw std::runtime_error( "(dbl) vectorValue(): Unsupported "
323 "StackElement" );
324 break;
325 }
326 }
327
329
330 if( m_type == SE_DOUBLE ) {
331 m_type = SE_INT;
333 } else if( m_type == SE_VECDOUBLE ) {
335 m_vecIntVal.clear();
336 for( auto& value : m_vecDoubleVal ) {
337 m_vecIntVal.push_back( static_cast< int >( value ) );
338 }
339 }
340
341 return;
342 }
343
345
346 if( m_type == SE_INT ) {
349 } else if( m_type == SE_VECINT ) {
351 m_vecDoubleVal.clear();
352 for( auto& value : m_vecIntVal ) {
353 m_vecDoubleVal.push_back( static_cast< double >( value ) );
354 }
355 }
356
357 return;
358 }
359
360 void StackElement::makeVector( std::size_t n ) {
361
362 if( isVector() ) {
363 return;
364 }
365
366 if( m_type == SE_INT ) {
368 m_vecIntVal.clear();
369 m_vecIntVal.resize( n, m_intVal );
370 } else if( m_type == SE_DOUBLE ) {
372 m_vecDoubleVal.clear();
373 m_vecDoubleVal.resize( n, m_doubleVal );
374 }
375
376 return;
377 }
378
379 StackElement StackElement::valueFromProxy([[maybe_unused]] const EventContext& ctx) const {
380
381 StackElement tmp;
382 if( ! isProxy() ) {
383 return tmp;
384 }
385
386 IAccessor::VariableType the_variable_type=m_variableType.load(std::memory_order_seq_cst);
387 if( the_variable_type==IProxyLoader::VT_UNK) {
388 auto [variable_type, accessor] = m_proxyLoader->getAccessorFromString(ctx, m_varName);
389 // if ( m_variableType != IProxyLoader::VT_UNK) {
390 if (variable_type != IProxyLoader::VT_VECEMPTY) {
391 // do not cache the accessor and variable type if it was an empty vector because
392 // in such cases there is not enough information to decide the variable type.
393 // otherwise set the accessor if still unset and set the variable type.
394 // Other threads would come to the same conclusion in case the vector is not empty
395 // (or empty), so which thread sets the variable type and/or accessor does not matter.
396 m_accessor.setIfUnset(accessor);
397 m_variableType.store(variable_type, std::memory_order_seq_cst);
398 }
399 // for the current event what ever getAccessorFromString returned is a good choice
400 // independent of other threads which might have had more information for a final
401 // decision. So, for this evaluation what ever getAccessorFromString returned will
402 // be used.
403 the_variable_type = variable_type;
404 }
405 assert((the_variable_type == IProxyLoader::VT_UNK || the_variable_type == IProxyLoader::VT_VECEMPTY || m_accessor == true) );
406
407 switch( the_variable_type ) {
409 tmp = m_accessor->loadInt(ctx, m_varName );
410 break;
411
413 tmp = m_accessor->loadDouble(ctx, m_varName );
414 break;
415
417 tmp = m_accessor->loadVecInt(ctx, m_varName );
418 break;
419
421 tmp = m_accessor->loadVec(ctx, m_varName );
422 break;
423 }
425 tmp=std::vector<double>();
426 break;
428 default:
429 throw std::runtime_error( "Got VT_UNK - unknown identifier: " +
430 m_varName );
431 break;
432 }
433
434 return tmp;
435 }
436
437
438 template <class T_CompHelper, class T>
439 std::vector<int> compareVector(std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
440 {
441 std::vector<int> ret;
442 ret.resize(a.size());
443 assert( a.size() == b.size() );
444 for (std::size_t idx=0; idx < a.size(); ++idx) {
445 ret[idx] = helper.compare(a[idx],b[idx]);
446 }
447 return ret;
448 }
449 template <class T_CompHelper, class T>
450 std::vector<int> compareVectorAlt(const std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
451 {
452 return compareVectorAlt(a,b,helper);
453 }
454
455 template <class T_CompHelper>
456 std::vector<int> compareVector(std::vector<int> &&a, const std::vector<int> &&b,T_CompHelper helper)
457 {
458 assert( a.size() == b.size() );
459 for (std::size_t idx=0; idx < a.size(); ++idx) {
460 a[idx] = helper.compare(a[idx],b[idx]);
461 }
462 return std::vector<int>(std::move(a));
463 }
464
465 template <class T_CompHelper>
466 std::vector<int> compareVectorAlt(const std::vector<int> &&a, std::vector<int> &&b,T_CompHelper helper)
467 {
468 assert( a.size() == b.size() );
469 for (std::size_t idx=0; idx < a.size(); ++idx) {
470 b[idx] = helper.compare(a[idx],b[idx]);
471 }
472 return std::vector<int>(std::move(b));
473 }
474
475 template <class T_CompHelper>
476 StackElement StackElement::_comparisonOp(StackElement &other, T_CompHelper comp_helper)
477 {
478 if (m_type ==SE_UNK || other.m_type==SE_UNK) {
479 throw std::runtime_error( "ERROR: Can't operate on SE_UNK "
480 "StackElements");
481 }
482 if( isScalar() && other.isScalar() ) {
483 if( m_type == SE_INT && other.m_type == SE_INT ) {
484 return comp_helper.compare(scalarValue< int >(),other.scalarValue< int >() );
485 } else {
486 return comp_helper.compare(scalarValue< double >(),other.scalarValue< double >() );
487 }
488 } else {
489 if (isVector() && other.isVector() && this->size() != other.size()) {
490 throw std::runtime_error( "Incompatible vectors - different length" );
491 }
492 std::size_t the_size = ( m_type == SE_VECINT || m_type==SE_VECDOUBLE) ? this->size() : other.size();
493 if( ( m_type == SE_VECINT)
494 && ( other.m_type == SE_VECINT || other.m_type == SE_INT )) {
495 return compareVector( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
496 }
497 else if( m_type == SE_INT && other.m_type == SE_VECINT) {
498 return compareVectorAlt( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
499 }
500 else {
501 return compareVector( this->vectorValue<double>(the_size) , other.vectorValue< double >(the_size), comp_helper );
502 }
503 }
504 }
505
506 class Helper_eq { public: template <class T> int compare(const T &a, const T &b) { return a == b; } };
507 class Helper_neq { public: template <class T> int compare(const T &a, const T &b) { return a != b; } };
508 class Helper_and { public: template <class T> int compare(const T &a, const T &b) { return a && b; } };
509 class Helper_or { public: template <class T> int compare(const T &a, const T &b) { return a || b; } };
510 class Helper_gt { public: template <class T> int compare(const T &a, const T &b) { return a > b; } };
511 class Helper_gte { public: template <class T> int compare(const T &a, const T &b) { return a >= b; } };
512 class Helper_lt { public: template <class T> int compare(const T &a, const T &b) { return a < b; } };
513 class Helper_lte { public: template <class T> int compare(const T &a, const T &b) { return a <= b; } };
514
523
524
525 template <>
527
528 if( n.isVector() ) {
529 throw std::runtime_error( "Can't use vector as exponent" );
530 } else {
531 return _pow( n.scalarValue< double >() );
532 }
533 }
534
536
537 switch( m_type ) {
538
539 case SE_INT:
540 return m_intVal;
541 break;
542
543 case SE_DOUBLE:
544 return m_doubleVal;
545 break;
546
547 case SE_VECINT:
548 {
549 int total = 0;
550 for( int value : m_vecIntVal ) {
551 total += value;
552 }
553 return total;
554 }
555 break;
556
557 case SE_VECDOUBLE:
558 {
559 double total = 0.0;
560 for( double value : m_vecDoubleVal ) {
561 total += value;
562 }
563 return total;
564 }
565 break;
566
567 default:
568 return 0;
569 break;
570 }
571 }
572
574
575 switch( m_type ) {
576
577 case SE_INT:
578 return !!( m_intVal );
579 break;
580
581 case SE_DOUBLE:
582 return !!( m_doubleVal );
583 break;
584
585 case SE_VECINT:
586 {
587 int total = 0;
588 for( int value : m_vecIntVal ) {
589 total += !!value;
590 }
591 return total;
592 }
593 break;
594
595 case SE_VECDOUBLE:
596 {
597 int total = 0;
598 for( double value : m_vecDoubleVal ) {
599 total += !!value;
600 }
601 return total;
602 }
603 break;
604
605 default:
606 return 0;
607 break;
608 }
609 }
610
612 if (this->m_moved) throw std::logic_error("Content already moved");
613
614 StackElement temp(std::move(*this));
615 this->m_moved=true;
616 switch( m_type ) {
617
618 case SE_INT:
619 m_intVal = std::abs( temp.m_intVal );
620 break;
621
622 case SE_DOUBLE:
623 m_doubleVal = std::abs( temp.m_doubleVal );
624 break;
625
626 case SE_VECINT:
627 {
628 for( int &value : temp.m_vecIntVal ) {
629 value = std::abs( value );
630 }
631 }
632 break;
633
634 case SE_VECDOUBLE:
635 {
636 for( double &value : temp.m_vecDoubleVal ) {
637 value = std::abs( value );
638 }
639 }
640 break;
641
642 default:
643 // @throw exception ?
644 break;
645 }
646 return temp;
647 }
648
650#define UNARY_MATH_FUNCTION( FUNC, BASEFUNC ) \
651 StackElement StackElement::FUNC() { \
652 if (this->m_moved) throw std::logic_error("Content already moved");\
653 StackElement temp( std::move(*this) ); \
654 this->m_moved=true; \
655 temp.makeDouble(); \
656 if( temp.m_type == SE_DOUBLE ) { \
657 temp.m_doubleVal = BASEFUNC( temp.m_doubleVal ); \
658 return temp; \
659 } else if( temp.m_type == SE_VECDOUBLE ) { \
660 for( double& value : temp.m_vecDoubleVal ) { \
661 value = BASEFUNC( value ); \
662 } \
663 return temp; \
664 } else { \
665 /* @TODO throw exception */ \
666 return temp; \
667 } \
668 }
669
670 UNARY_MATH_FUNCTION( _sqrt, sqrt )
671 UNARY_MATH_FUNCTION( _cbrt, cbrt )
672 UNARY_MATH_FUNCTION( _sin, sin )
673 UNARY_MATH_FUNCTION( _cos, cos )
674 UNARY_MATH_FUNCTION( _tan, tan )
675 UNARY_MATH_FUNCTION( _asin, asin )
676 UNARY_MATH_FUNCTION( _acos, acos )
677 UNARY_MATH_FUNCTION( _atan, atan )
678 UNARY_MATH_FUNCTION( _sinh, sinh )
679 UNARY_MATH_FUNCTION( _cosh, cosh )
680 UNARY_MATH_FUNCTION( _tanh, tanh )
681 UNARY_MATH_FUNCTION( _asinh, asinh )
682 UNARY_MATH_FUNCTION( _acosh, acosh )
683 UNARY_MATH_FUNCTION( _atanh, atanh )
684 UNARY_MATH_FUNCTION( _log, log )
685 UNARY_MATH_FUNCTION( _exp, exp )
686
687
688#undef UNARY_MATH_FUNCTION
689
691
692 if( isVector() ) {
693 return;
694 }
695 if( other.isVector() ) {
696 makeVector( other.size() );
697 }
698
699 return;
700 }
701
702 void StackElement::makeVectorIfNecessary(const std::vector< int >& other ) {
703
704 if( isVector() ) {
705 return;
706 }
707 makeVector( other.size() );
708
709 return;
710 }
711
712 void
713 StackElement::makeVectorIfNecessary( const std::vector< double >& other ) {
714
715 if( isVector() ) {
716 return;
717 }
718 makeVector( other.size() );
719
720 return;
721 }
722
724
725 if( ( m_type == SE_INT ) && ( other.m_type == SE_DOUBLE ) ) {
726 makeDouble();
727 } else if( ( m_type == SE_VECINT ) && ( other.m_type == SE_VECDOUBLE ) ) {
728 makeDouble();
729 }
730
731 return;
732 }
733
735
736 return;
737 }
738
740
741 if( m_type == SE_INT ) {
742 makeDouble();
743 }
744
745 return;
746 }
747
748 void StackElement::makeDoubleIfNecessary( const std::vector< int >& ) {
749
750 return;
751 }
752
753 void StackElement::makeDoubleIfNecessary( const std::vector< double >& ) {
754
755 if( m_type == SE_VECINT ) {
756 makeDouble();
757 }
758
759 return;
760 }
761
762 void StackElement::ensureCompatible( const StackElement& other ) const {
763
764 if( this->m_type != other.m_type ) {
765 throw std::runtime_error( "Incompatible stack elements" );
766 }
767
768 return;
769 }
770
771 template<>
772 void
774
775 if( isScalar() ) {
776 return;
777 }
778
779 const std::size_t ourlen = size();
780 if( ourlen != other.size() ) {
781 throw std::runtime_error( "Incompatible vectors - different length" );
782 }
783 }
784
785 std::ostream &operator<<( std::ostream& os,
786 const StackElement& el ) {
787
788 switch( el.m_type ) {
789
791 os << "(int)" << el.m_intVal;
792 break;
793
795 os << "(double)" << el.m_doubleVal;
796 break;
797
799 os << "(vec<int>)" << el.m_vecIntVal;
800 break;
801
803 os << "(vec<double>)" << el.m_vecDoubleVal;
804 break;
805
807 os << "SE_UNK";
808 break;
809
810 default:
811 break;
812 }
813
814 return os;
815 }
816
817} // 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)