19 template<
typename T >
20 std::ostream&
operator <<( std::ostream& os,
const std::vector< T >&
vec ) {
23 for( std::size_t i = 0;
i <
vec.size(); ++
i ) {
25 if( ( i + 1 ) <
vec.size() ) {
64 StackElement& StackElement::operator=(
const std::vector< int >& rhs ) {
75 StackElement& StackElement::operator=( std::vector< int >&& rhs ) {
86 StackElement& StackElement::operator=(
const std::vector< double >& rhs ) {
98 StackElement& StackElement::operator=( std::vector< double >&& rhs ) {
113 if (this->
m_moved)
throw std::logic_error(
"Content already moved");
120 temp.m_intVal = !( temp.m_intVal );
125 temp.m_intVal = !( temp.m_doubleVal );
129 for( std::size_t i = 0; i < temp.m_vecIntVal.size(); ++i ) {
130 temp.m_vecIntVal[ i ] = !( temp.m_vecIntVal[ i ] );
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 ] );
143 throw std::runtime_error(
"! operator called on unknown "
155 if (this->
m_moved)
throw std::logic_error(
"Content already moved");
163 temp.m_intVal = -( this->
m_intVal );
171 for( std::size_t i = 0; i < temp.m_vecIntVal.size(); ++i ) {
172 temp.m_vecIntVal[ i ] = -( temp.m_vecIntVal[ i ] );
177 for( std::size_t i = 0; i < temp.m_vecDoubleVal.size(); ++i ) {
178 temp.m_vecDoubleVal[ i ] = -( temp.m_vecDoubleVal[ i ] );
183 throw std::runtime_error(
"- operator called on unknown "
193#define IMPL_ASSIGN_OP( OP ) \
194 StackElement& StackElement::operator OP( StackElement& rhs ) { \
195 makeVectorIfNecessary( rhs ); \
196 makeDoubleIfNecessary( rhs ); \
199 m_intVal OP rhs.scalarValue< int >(); \
202 m_doubleVal OP rhs.scalarValue< double >(); \
205 *this OP rhs.vectorValue< int >( m_vecIntVal.size() ); \
208 *this OP rhs.vectorValue< double >( m_vecDoubleVal.size() ); \
211 throw std::runtime_error( "StackElement ill-defined in " \
226 StackElement::ElementType StackElement::getType()
const {
231 bool StackElement::isScalar()
const {
236 bool StackElement::isVector()
const {
241 bool StackElement::isProxy()
const {
246 int StackElement::asInt()
const {
249 throw std::runtime_error(
"asInt() only valid for SE_INT" );
255 bool StackElement::asBool()
const {
258 throw std::runtime_error(
"asBool() only valid for non-vector types" );
266 StackElement::vectorValue( std::size_t sizeIfScalar ) {
268 if (this->
m_moved)
throw std::logic_error(
"Content already moved");
282 return std::vector<int>( sizeIfScalar,
m_intVal );
286 return std::vector<int>( sizeIfScalar,
static_cast< int >(
m_doubleVal ) );
290 throw std::runtime_error(
"(int) vectorValue(): Unsupported "
294 return std::vector<int>();
298 std::vector< double >
299 StackElement::vectorValue(
size_t sizeIfScalar ) {
301 if (this->
m_moved)
throw std::logic_error(
"Content already moved");
316 return std::vector<double>(sizeIfScalar,
static_cast< double >(
m_intVal ) );
320 return std::vector<double>(sizeIfScalar,
m_doubleVal );
324 throw std::runtime_error(
"(dbl) vectorValue(): Unsupported "
328 return std::vector<double>();
331 void StackElement::makeInt() {
340 m_vecIntVal.push_back(
static_cast< int >( value ) );
347 void StackElement::makeDouble() {
363 void StackElement::makeVector( std::size_t n ) {
415 tmp=std::vector<double>();
419 throw std::runtime_error(
"Got VT_UNK - unknown identifier: " +
428 template <
class T_CompHelper,
class T>
429 std::vector<int>
compareVector(std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
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]);
439 template <
class T_CompHelper,
class T>
440 std::vector<int>
compareVectorAlt(
const std::vector<T> &&a, std::vector<T> &&b,T_CompHelper helper)
445 template <
class T_CompHelper>
446 std::vector<int>
compareVector(std::vector<int> &&a,
const std::vector<int> &&b,T_CompHelper helper)
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]);
452 return std::vector<int>(std::move(a));
455 template <
class T_CompHelper>
456 std::vector<int>
compareVectorAlt(
const std::vector<int> &&a, std::vector<int> &&b,T_CompHelper helper)
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]);
462 return std::vector<int>(std::move(b));
465 template <
class T_CompHelper>
469 throw std::runtime_error(
"ERROR: Can't operate on SE_UNK "
472 if(
isScalar() && other.isScalar() ) {
479 if (
isVector() && other.isVector() && this->size() != other.size()) {
480 throw std::runtime_error(
"Incompatible vectors - different length" );
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; } };
519 throw std::runtime_error(
"Can't use vector as exponent" );
521 return _pow( n.scalarValue<
double >() );
602 if (this->
m_moved)
throw std::logic_error(
"Content already moved");
609 m_intVal = std::abs( temp.m_intVal );
618 for(
int &value : temp.m_vecIntVal ) {
619 value = std::abs( value );
626 for(
double &value : temp.m_vecDoubleVal ) {
627 value = std::abs( value );
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; \
646 if( temp.m_type == SE_DOUBLE ) { \
647 temp.m_doubleVal = BASEFUNC( temp.m_doubleVal ); \
649 } else if( temp.m_type == SE_VECDOUBLE ) { \
650 for( double& value : temp.m_vecDoubleVal ) { \
651 value = BASEFUNC( value ); \
678#undef UNARY_MATH_FUNCTION
680 void StackElement::makeVectorIfNecessary(
const StackElement& other ) {
685 if( other.isVector() ) {
692 void StackElement::makeVectorIfNecessary(
const std::vector< int >& other ) {
703 StackElement::makeVectorIfNecessary(
const std::vector< double >& other ) {
713 void StackElement::makeDoubleIfNecessary(
const StackElement& other ) {
724 void StackElement::makeDoubleIfNecessary(
int ) {
729 void StackElement::makeDoubleIfNecessary(
double ) {
738 void StackElement::makeDoubleIfNecessary(
const std::vector< int >& ) {
743 void StackElement::makeDoubleIfNecessary(
const std::vector< double >& ) {
752 void StackElement::ensureCompatible(
const StackElement& other )
const {
754 if( this->
m_type != other.m_type ) {
755 throw std::runtime_error(
"Incompatible stack elements" );
763 StackElement::ensureCompatibleVectors(
const StackElement& other )
const {
769 const std::size_t ourlen =
size();
770 if( ourlen != other.size() ) {
771 throw std::runtime_error(
"Incompatible vectors - different length" );
778 switch( el.m_type ) {
780 case StackElement::SE_INT:
781 os <<
"(int)" << el.m_intVal;
784 case StackElement::SE_DOUBLE:
785 os <<
"(double)" << el.m_doubleVal;
788 case StackElement::SE_VECINT:
789 os <<
"(vec<int>)" << el.m_vecIntVal;
792 case StackElement::SE_VECDOUBLE:
793 os <<
"(vec<double>)" << el.m_vecDoubleVal;
796 case StackElement::SE_UNK:
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.
std::atomic< bool > m_moved
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)