ATLAS Offline Software
Loading...
Searching...
No Matches
StackElement.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 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
39 StackElement& StackElement::operator=( int rhs ) {
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
51 StackElement& StackElement::operator=( double rhs ) {
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
110 StackElement StackElement::operator!() {
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
152 StackElement StackElement::operator-() {
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
226 StackElement::ElementType StackElement::getType() const {
227
228 return m_type;
229 }
230
231 bool StackElement::isScalar() const {
232
233 return ( ( m_type == SE_INT ) || ( m_type == SE_DOUBLE ) );
234 }
235
236 bool StackElement::isVector() const {
237
238 return ( ( m_type == SE_VECINT ) || ( m_type == SE_VECDOUBLE ) );
239 }
240
241 bool StackElement::isProxy() const {
242
243 return ( m_varName.length() > 0 );
244 }
245
246 int StackElement::asInt() const {
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
331 void StackElement::makeInt() {
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
347 void StackElement::makeDouble() {
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() const {
383
384 StackElement tmp;
385 if( ! isProxy() ) {
386 return tmp;
387 }
388
390 m_variableType = m_proxyLoader->variableTypeFromString( m_varName );
393 }
394 }
395
396 switch( m_variableType ) {
397
399 tmp = m_proxyLoader->loadIntVariableFromString( m_varName );
400 break;
401
403 tmp = m_proxyLoader->loadDoubleVariableFromString( m_varName );
404 break;
405
407 tmp = m_proxyLoader->loadVecIntVariableFromString( m_varName );
408 break;
409
411 tmp = m_proxyLoader->loadVecDoubleVariableFromString( m_varName );
412 break;
413
415 tmp=std::vector<double>();
416 break;
418 default:
419 throw std::runtime_error( "Got VT_UNK - unknown identifier: " +
420 m_varName );
421 break;
422 }
423
424 return tmp;
425 }
426
427
428 template <class T_CompHelper, class T>
429 std::vector<int> compareVector(std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
430 {
431 std::vector<int> ret;
432 ret.resize(a.size());
433 assert( a.size() == b.size() );
434 for (std::size_t idx=0; idx < a.size(); ++idx) {
435 ret[idx] = helper.compare(a[idx],b[idx]);
436 }
437 return ret;
438 }
439 template <class T_CompHelper, class T>
440 std::vector<int> compareVectorAlt(const std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
441 {
442 return compareVectorAlt(a,b,helper);
443 }
444
445 template <class T_CompHelper>
446 std::vector<int> compareVector(std::vector<int> &&a, const std::vector<int> &&b,T_CompHelper helper)
447 {
448 assert( a.size() == b.size() );
449 for (std::size_t idx=0; idx < a.size(); ++idx) {
450 a[idx] = helper.compare(a[idx],b[idx]);
451 }
452 return std::vector<int>(std::move(a));
453 }
454
455 template <class T_CompHelper>
456 std::vector<int> compareVectorAlt(const std::vector<int> &&a, 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 b[idx] = helper.compare(a[idx],b[idx]);
461 }
462 return std::vector<int>(std::move(b));
463 }
464
465 template <class T_CompHelper>
466 StackElement StackElement::_comparisonOp(StackElement &other, T_CompHelper comp_helper)
467 {
468 if (m_type ==SE_UNK || other.m_type==SE_UNK) {
469 throw std::runtime_error( "ERROR: Can't operate on SE_UNK "
470 "StackElements");
471 }
472 if( isScalar() && other.isScalar() ) {
473 if( m_type == SE_INT && other.m_type == SE_INT ) {
474 return comp_helper.compare(scalarValue< int >(),other.scalarValue< int >() );
475 } else {
476 return comp_helper.compare(scalarValue< double >(),other.scalarValue< double >() );
477 }
478 } else {
479 if (isVector() && other.isVector() && this->size() != other.size()) {
480 throw std::runtime_error( "Incompatible vectors - different length" );
481 }
482 std::size_t the_size = ( m_type == SE_VECINT || m_type==SE_VECDOUBLE) ? this->size() : other.size();
483 if( ( m_type == SE_VECINT)
484 && ( other.m_type == SE_VECINT || other.m_type == SE_INT )) {
485 return compareVector( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
486 }
487 else if( m_type == SE_INT && other.m_type == SE_VECINT) {
488 return compareVectorAlt( this->vectorValue<int>(the_size) , other.vectorValue< int >(the_size), comp_helper );
489 }
490 else {
491 return compareVector( this->vectorValue<double>(the_size) , other.vectorValue< double >(the_size), comp_helper );
492 }
493 }
494 }
495
496 class Helper_eq { public: template <class T> int compare(const T &a, const T &b) { return a == b; } };
497 class Helper_neq { public: template <class T> int compare(const T &a, const T &b) { return a != b; } };
498 class Helper_and { public: template <class T> int compare(const T &a, const T &b) { return a && b; } };
499 class Helper_or { public: template <class T> int compare(const T &a, const T &b) { return a || b; } };
500 class Helper_gt { public: template <class T> int compare(const T &a, const T &b) { return a > b; } };
501 class Helper_gte { public: template <class T> int compare(const T &a, const T &b) { return a >= b; } };
502 class Helper_lt { public: template <class T> int compare(const T &a, const T &b) { return a < b; } };
503 class Helper_lte { public: template <class T> int compare(const T &a, const T &b) { return a <= b; } };
504
505 StackElement StackElement::_eq(StackElement &b) { return _comparisonOp(b, Helper_eq()); }
506 StackElement StackElement::_neq(StackElement &b) { return _comparisonOp(b, Helper_neq()); }
507 StackElement StackElement::_and(StackElement &b) { return _comparisonOp(b, Helper_and()); }
508 StackElement StackElement::_or(StackElement &b) { return _comparisonOp(b, Helper_or()); }
509 StackElement StackElement::_gt(StackElement &b) { return _comparisonOp(b, Helper_gt()); }
510 StackElement StackElement::_gte(StackElement &b) { return _comparisonOp(b, Helper_gte()); }
511 StackElement StackElement::_lt(StackElement &b) { return _comparisonOp(b, Helper_lt()); }
512 StackElement StackElement::_lte(StackElement &b) { return _comparisonOp(b, Helper_lte()); }
513
514
515 template <>
516 StackElement StackElement::_pow( const StackElement& n ) {
517
518 if( n.isVector() ) {
519 throw std::runtime_error( "Can't use vector as exponent" );
520 } else {
521 return _pow( n.scalarValue< double >() );
522 }
523 }
524
525 StackElement StackElement::_sum() {
526
527 switch( m_type ) {
528
529 case SE_INT:
530 return m_intVal;
531 break;
532
533 case SE_DOUBLE:
534 return m_doubleVal;
535 break;
536
537 case SE_VECINT:
538 {
539 int total = 0;
540 for( int value : m_vecIntVal ) {
541 total += value;
542 }
543 return total;
544 }
545 break;
546
547 case SE_VECDOUBLE:
548 {
549 double total = 0.0;
550 for( double value : m_vecDoubleVal ) {
551 total += value;
552 }
553 return total;
554 }
555 break;
556
557 default:
558 return 0;
559 break;
560 }
561 }
562
563 StackElement StackElement::_count() {
564
565 switch( m_type ) {
566
567 case SE_INT:
568 return !!( m_intVal );
569 break;
570
571 case SE_DOUBLE:
572 return !!( m_doubleVal );
573 break;
574
575 case SE_VECINT:
576 {
577 int total = 0;
578 for( int value : m_vecIntVal ) {
579 total += !!value;
580 }
581 return total;
582 }
583 break;
584
585 case SE_VECDOUBLE:
586 {
587 int total = 0;
588 for( double value : m_vecDoubleVal ) {
589 total += !!value;
590 }
591 return total;
592 }
593 break;
594
595 default:
596 return 0;
597 break;
598 }
599 }
600
601 StackElement StackElement::_abs() {
602 if (this->m_moved) throw std::logic_error("Content already moved");
603
604 StackElement temp(std::move(*this));
605 this->m_moved=true;
606 switch( m_type ) {
607
608 case SE_INT:
609 m_intVal = std::abs( temp.m_intVal );
610 break;
611
612 case SE_DOUBLE:
613 m_doubleVal = std::abs( temp.m_doubleVal );
614 break;
615
616 case SE_VECINT:
617 {
618 for( int &value : temp.m_vecIntVal ) {
619 value = std::abs( value );
620 }
621 }
622 break;
623
624 case SE_VECDOUBLE:
625 {
626 for( double &value : temp.m_vecDoubleVal ) {
627 value = std::abs( value );
628 }
629 }
630 break;
631
632 default:
633 // @throw exception ?
634 break;
635 }
636 return temp;
637 }
638
640#define UNARY_MATH_FUNCTION( FUNC, BASEFUNC ) \
641 StackElement StackElement::FUNC() { \
642 if (this->m_moved) throw std::logic_error("Content already moved");\
643 StackElement temp( std::move(*this) ); \
644 this->m_moved=true; \
645 temp.makeDouble(); \
646 if( temp.m_type == SE_DOUBLE ) { \
647 temp.m_doubleVal = BASEFUNC( temp.m_doubleVal ); \
648 return temp; \
649 } else if( temp.m_type == SE_VECDOUBLE ) { \
650 for( double& value : temp.m_vecDoubleVal ) { \
651 value = BASEFUNC( value ); \
652 } \
653 return temp; \
654 } else { \
655 /* @TODO throw exception */ \
656 return temp; \
657 } \
658 }
659
660 UNARY_MATH_FUNCTION( _sqrt, sqrt )
661 UNARY_MATH_FUNCTION( _cbrt, cbrt )
662 UNARY_MATH_FUNCTION( _sin, sin )
663 UNARY_MATH_FUNCTION( _cos, cos )
664 UNARY_MATH_FUNCTION( _tan, tan )
665 UNARY_MATH_FUNCTION( _asin, asin )
666 UNARY_MATH_FUNCTION( _acos, acos )
667 UNARY_MATH_FUNCTION( _atan, atan )
668 UNARY_MATH_FUNCTION( _sinh, sinh )
669 UNARY_MATH_FUNCTION( _cosh, cosh )
670 UNARY_MATH_FUNCTION( _tanh, tanh )
671 UNARY_MATH_FUNCTION( _asinh, asinh )
672 UNARY_MATH_FUNCTION( _acosh, acosh )
673 UNARY_MATH_FUNCTION( _atanh, atanh )
674 UNARY_MATH_FUNCTION( _log, log )
675 UNARY_MATH_FUNCTION( _exp, exp )
676
677
678#undef UNARY_MATH_FUNCTION
679
680 void StackElement::makeVectorIfNecessary( const StackElement& other ) {
681
682 if( isVector() ) {
683 return;
684 }
685 if( other.isVector() ) {
686 makeVector( other.size() );
687 }
688
689 return;
690 }
691
692 void StackElement::makeVectorIfNecessary(const std::vector< int >& other ) {
693
694 if( isVector() ) {
695 return;
696 }
697 makeVector( other.size() );
698
699 return;
700 }
701
702 void
703 StackElement::makeVectorIfNecessary( const std::vector< double >& other ) {
704
705 if( isVector() ) {
706 return;
707 }
708 makeVector( other.size() );
709
710 return;
711 }
712
713 void StackElement::makeDoubleIfNecessary( const StackElement& other ) {
714
715 if( ( m_type == SE_INT ) && ( other.m_type == SE_DOUBLE ) ) {
716 makeDouble();
717 } else if( ( m_type == SE_VECINT ) && ( other.m_type == SE_VECDOUBLE ) ) {
718 makeDouble();
719 }
720
721 return;
722 }
723
724 void StackElement::makeDoubleIfNecessary( int ) {
725
726 return;
727 }
728
729 void StackElement::makeDoubleIfNecessary( double ) {
730
731 if( m_type == SE_INT ) {
732 makeDouble();
733 }
734
735 return;
736 }
737
738 void StackElement::makeDoubleIfNecessary( const std::vector< int >& ) {
739
740 return;
741 }
742
743 void StackElement::makeDoubleIfNecessary( const std::vector< double >& ) {
744
745 if( m_type == SE_VECINT ) {
746 makeDouble();
747 }
748
749 return;
750 }
751
752 void StackElement::ensureCompatible( const StackElement& other ) const {
753
754 if( this->m_type != other.m_type ) {
755 throw std::runtime_error( "Incompatible stack elements" );
756 }
757
758 return;
759 }
760
761 template<>
762 void
763 StackElement::ensureCompatibleVectors( const StackElement& other ) const {
764
765 if( isScalar() ) {
766 return;
767 }
768
769 const std::size_t ourlen = size();
770 if( ourlen != other.size() ) {
771 throw std::runtime_error( "Incompatible vectors - different length" );
772 }
773 }
774
775 std::ostream &operator<<( std::ostream& os,
776 const StackElement& el ) {
777
778 switch( el.m_type ) {
779
780 case StackElement::SE_INT:
781 os << "(int)" << el.m_intVal;
782 break;
783
784 case StackElement::SE_DOUBLE:
785 os << "(double)" << el.m_doubleVal;
786 break;
787
788 case StackElement::SE_VECINT:
789 os << "(vec<int>)" << el.m_vecIntVal;
790 break;
791
792 case StackElement::SE_VECDOUBLE:
793 os << "(vec<double>)" << el.m_vecDoubleVal;
794 break;
795
796 case StackElement::SE_UNK:
797 os << "SE_UNK";
798 break;
799
800 default:
801 break;
802 }
803
804 return os;
805 }
806
807} // namespace ExpressionParsing
std::vector< size_t > vec
#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.
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.
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)
bool isProxy() const
Check if the object takes its value from a StoreGate object.
StackElement _pow(const T &n)
Function raising the object's value to the n'th power.
T scalarValue() const
Evaluate the value of the object into the requested scalar type.
bool isScalar() const
Check if the object describes a scalar value.
@ 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.
ElementType m_type
The type of the variable held by the object.
int m_intVal
The value of the object represented as an integer.
void makeVector(std::size_t n)
Function converting a possibly scalar value into a vector.
StackElement()
Default constructor.
std::atomic< bool > m_determinedVariableType
Internal flag showing whether the type of the variable was already determined.
std::vector< int > m_vecIntVal
The value of the object represented as a vector of integers.
double m_doubleVal
The value of the object represented as a double.
std::atomic< IProxyLoader::VariableType > m_variableType
Type of the variable provided by the proxy loader.
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)