1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: QtxEvalExpr.cxx
23 // Author: Alexander SOLOVYOV, Sergey TELKOV
25 #include "QtxEvalExpr.h"
33 \brief String expression evaluator.
39 The evaluator is initalized by standard operations. Use another constructor with parameter
40 \a stdSets = \c false to avoid initialization of evaluator with standard operations.
42 \param expr expression to be evaluated
44 QtxEvalExpr::QtxEvalExpr( const QString& expr )
46 intialize( true, expr );
51 \param stdSets if \c true, the evaluator is initalized by standard operations
52 \param expr expression to be evaluated
54 QtxEvalExpr::QtxEvalExpr( const bool stdSets, const QString& expr )
56 intialize( stdSets, expr );
62 QtxEvalExpr::~QtxEvalExpr()
68 \brief Initialize the evaluator.
69 \param stdSets if \c true, the evaluator is initalized by standard operations
70 \param expr expression to be evaluated
72 void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
74 myParser = new QtxEvalParser();
77 myParser->setAutoDeleteOperationSets( true );
78 myParser->insertOperationSet( new QtxEvalSetLogic() );
79 myParser->insertOperationSet( new QtxEvalSetArithmetic() );
80 myParser->insertOperationSet( new QtxEvalSetString() );
81 myParser->insertOperationSet( new QtxEvalSetMath() );
82 myParser->insertOperationSet( new QtxEvalSetSets() );
83 myParser->insertOperationSet( new QtxEvalSetConst() );
85 setExpression( expr );
89 \brief Evaluate the expression.
90 \param expr expression to be evaluated
91 \return result of the evaluation
93 QVariant QtxEvalExpr::calculate( const QString& expr )
95 if ( !expr.isEmpty() )
96 setExpression( expr );
97 return myParser->calculate();
101 \brief Get the expression.
102 \return expression string
104 QString QtxEvalExpr::expression() const
110 \brief Set the expression.
111 \param expr expression string
113 void QtxEvalExpr::setExpression( const QString& expr )
115 if ( expr == expression() )
119 myParser->setExpression( myExpr );
123 \brief Get the code of latest parsing error.
124 \return the code of the last error
126 QtxEvalExpr::Error QtxEvalExpr::error() const
128 return myParser->error();
132 \brief Get the expression parser.
133 \return expression parser
135 QtxEvalParser* QtxEvalExpr::parser() const
141 \brief Get current set of operations.
142 \return operations set
143 \sa insertOperationSet(), removeOperationSet(), operationSet()
145 QList<QtxEvalSet*> QtxEvalExpr::operationSets() const
147 return myParser->operationSets();
151 \brief Install the operation.
152 \param operation to be added
153 \param idx index in the list at which the operation shoud be inserted
154 \sa operationSets(), removeOperationSet(), operationSet()
156 void QtxEvalExpr::insertOperationSet( QtxEvalSet* set, const int idx )
158 myParser->insertOperationSet( set, idx );
162 \brief Remove the operation.
163 \param operation to be removed
164 \sa operationSets(), insertOperationSet(), operationSet()
166 void QtxEvalExpr::removeOperationSet( QtxEvalSet* set )
168 myParser->removeOperationSet( set );
172 \brief Get the operation by name.
173 \param name operation name
174 \return operation of 0 if not found
175 \sa operationSets(), insertOperationSet(), removeOperationSet()
177 QtxEvalSet* QtxEvalExpr::operationSet( const QString& name ) const
179 return myParser->operationSet( name );
183 \brief Get the 'auto-delete operations' flag value.
184 \return \c true if all operations shoud be automatically deleted when the evaluator is destroyed
185 \sa setAutoDeleteOperationSets()
187 bool QtxEvalExpr::autoDeleteOperationSets() const
189 return myParser->autoDeleteOperationSets();
193 \brief Set the 'auto-delete operations' flag value.
194 \param on if \c true, all operations shoud be automatically deleted when the evaluator is destroyed
195 \sa autoDeleteOperationSets()
197 void QtxEvalExpr::setAutoDeleteOperationSets( const bool on )
199 myParser->setAutoDeleteOperationSets( on );
204 \brief Expression parser.
206 This class provides the functionality to calculate value of the expression using defined set of operations.
207 Standard operations (arithmetics, logic, strings, etc) are implemented in the corresponding successors of the
208 QtxEvalSet class: QtxEvalSetArithmetic, QtxEvalSetLogic, QtxEvalSetMath, QtxEvalSetString, ...
210 The parser allows using parameters with help of methods has(), set(), remove(), value(). It uses
211 postfix representation of expressions and uses class QtxEvalSet in order to make certain operation.
213 Every instance of parser contains only one postfix - thus, if the expression is changed, the postfix
214 must be rebuilt. In order to increase performance of frequent calculations for many of expressions it is
215 recommended to use different instances of the parser for each expression.
221 QtxEvalParser::QtxEvalParser()
224 setError( QtxEvalExpr::OK );
230 QtxEvalParser::~QtxEvalParser()
232 if ( autoDeleteOperationSets() )
233 qDeleteAll( mySets );
237 \brief Get current operations set.
238 \return current operations set
240 QList<QtxEvalSet*> QtxEvalParser::operationSets() const
246 \brief Get the operations set by \a name.
247 \param name the name of the operation set
248 \return operation set or 0 if not found
250 QtxEvalSet* QtxEvalParser::operationSet( const QString& name ) const
253 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !set; ++it )
255 if ( (*it)->name() == name )
262 \brief Install the operations set.
263 \param operations set to be added
264 \param idx index in the list at which the operations set shoud be inserted
265 \sa operationSets(), removeOperationSet(), operationSet()
267 void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
269 if ( mySets.contains( set ) )
272 int index = idx < 0 ? mySets.count() : idx;
273 index = qMin( index, mySets.count() );
274 mySets.insert( index, set );
278 \brief Remove the operations set.
279 \param operations set to be removed
280 \sa operationSets(), insertOperationSet(), operationSet()
282 void QtxEvalParser::removeOperationSet( QtxEvalSet* set )
284 mySets.removeAll( set );
288 \brief Get the 'auto-delete operations' flag value.
289 \return \c true if all operations shoud be automatically deleted when the parser is destroyed
290 \sa setAutoDeleteOperationSets()
292 bool QtxEvalParser::autoDeleteOperationSets() const
298 \brief Set the 'auto-delete operations' flag value.
299 \param on if \c true, all operations shoud be automatically deleted when the parser is destroyed
300 \sa autoDeleteOperationSets()
302 void QtxEvalParser::setAutoDeleteOperationSets( const bool on )
308 \brief Search elements of the list as substrings starting from \a offset.
309 \param list list of substrings
310 \param str string in which the searching is performed
311 \param offset starting index for search
312 \param matchLen returning matching length of any substring
313 \param listind returning index of the found substring in the \a list
314 \return position of first found substring inside the \a str or -1 if no matches is found
316 int QtxEvalParser::search( const QStringList& list, const QString& str,
317 int offset, int& matchLen, int& listind )
320 QStringList::const_iterator anIt = list.begin(), aLast = list.end();
321 for ( int ind = 0; anIt != aLast; anIt++, ind++ )
323 int pos = str.indexOf( *anIt, offset );
324 if ( pos >= 0 && ( min < 0 || min > pos ||
325 ( min == pos && matchLen < (int)(*anIt).length() ) ) )
329 matchLen = (*anIt).length();
338 \brief Get the substring field from the string \a str.
339 \param str source string
340 \param pos start position of the substring
341 \param len length of the substring
342 \return substring (leading and trailing spaces are truncated)
344 QString QtxEvalParser::note( const QString& str, int pos, int len )
346 return str.mid( pos, len ).trimmed();
350 \brief Prepare to the parsing.
352 Performs the first step of the parsing:
354 - determine tokens types
355 - create unsorted pseudo-postfix (with brackets)
357 \param expr string expression
358 \param post postfix to be created
359 \return \c true on success and \c false if error is found
361 bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
364 int len = expr.length();
365 QStack<int> aBracketStack;
366 QStringList anOpers, anOpenBr, aCloseBr;
367 if ( !checkOperations() )
370 bracketsList( anOpenBr, true );
371 bracketsList( aCloseBr, false );
372 operationList( anOpers );
374 while ( pos < len && error() == QtxEvalExpr::OK )
377 while ( pos < len && expr[pos].isSpace() )
382 int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1;
383 int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind );
384 int cPos = oPos == pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind );
385 int opPos = search( anOpers, expr, pos, mLen, op_ind );
387 if ( expr[pos] == QChar( '\'' ) )
390 while ( vpos < (int)expr.length() && expr[vpos] != QChar( '\'' ) )
393 mLen = vpos - pos + 1;
395 int res = createValue( note( expr, pos, mLen ), item.myValue );
396 item.myType = res ? Value : Param;
404 aBracketStack.push( br_ind );
405 item.myValue = note( expr, pos, mBrLen );
409 else if ( cPos == pos )
411 if ( aBracketStack.count() == 0 )
413 setError( QtxEvalExpr::ExcessClose );
416 if ( br_ind != aBracketStack.top() )
418 setError( QtxEvalExpr::BracketsNotMatch );
424 item.myValue = note( expr, pos, mBrLen );
435 item.myValue = note( expr, pos, mLen );
436 item.myType = Binary;
439 post.insert( post.count() - 1, item );
446 if ( oPos != pos && cPos != pos )
449 for ( i = pos + 1; i < (int)expr.length(); i++ )
451 if ( expr[i].isSpace() )
456 if ( oPos >= 0 && oPos < vpos )
458 if ( cPos >= 0 && cPos < vpos )
460 if ( opPos >= 0 && opPos < vpos )
463 while( vpos < (int)expr.length() &&
464 ( expr[vpos].isLetter() || expr[vpos].isDigit() || expr[vpos]=='_' ) )
468 bool res = createValue( note( expr, pos, mLen ), item.myValue );
469 item.myType = res ? Value : Param;
474 pos += mBrLen + mLen;
479 for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
481 if ( (*anIt).myType == Open )
483 else if ( (*anIt).myType == Close )
489 setError( QtxEvalExpr::ExcessClose );
496 setError( QtxEvalExpr::CloseExpected );
498 return error() == QtxEvalExpr::OK;
502 \brief Analyze the operations used.
504 Second step of the parsing: analyze the types of the operations used in the expression.
506 \param post unsorted postfix
507 \return \c true on success and \c false if error is found
509 bool QtxEvalParser::setOperationTypes( Postfix& post )
511 if ( !checkOperations() )
514 QStringList anOpen, aClose;
515 bracketsList( anOpen, true );
516 bracketsList( aClose, false );
518 Postfix::iterator aPrev, aNext;
519 for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
525 if ( (*anIt).myType != Binary )
528 if ( ( anIt == post.begin() || (*aPrev).myType == Open ||
529 (*aPrev).myType == Pre || (*aPrev).myType == Binary ) && aNext != post.end() &&
530 ( (*aNext).myType == Value || (*aNext).myType == Param ||
531 (*aNext).myType == Open || (*aNext).myType == Binary ) )
532 (*anIt).myType = Pre;
533 else if ( anIt != post.begin() && ( (*aPrev).myType == Close || (*aPrev).myType == Param ||
534 (*aPrev).myType == Value || (*aPrev).myType == Pre ||
535 (*aPrev).myType == Post || (*aPrev).myType == Binary ) &&
536 ( aNext == post.end() || (*aNext).myType == Close ) )
537 (*anIt).myType = Post;
539 if ( anOpen.contains( (*anIt).myValue.toString() ) )
540 (*anIt).myType = Pre;
541 else if ( aClose.contains( (*anIt).myValue.toString() ) )
542 (*anIt).myType = Post;
545 return error() == QtxEvalExpr::OK;
549 \brief Get the number of the globar brackets pairs.
551 For example, the expression '((2+3))' has 2 global brackets pairs.
553 \param post postfix to be checked
554 \param f starting position for the search
555 \param l last position for the search
556 \return number of brackets pairs
558 int QtxEvalParser::globalBrackets( const QtxEvalParser::Postfix& post, int f, int l )
565 int min_br_num = (l-f+1)*5;
567 for( i=f; i<=l; i++ )
568 if( post[ i ].myType==QtxEvalParser::Open )
572 for( i=l; i>=f; i-- )
573 if( post[ i ].myType==QtxEvalParser::Close )
578 br = start_br<fin_br ? start_br : fin_br;
579 for( i=f+br; i<=l-br; i++ )
581 if( post[i].myType==QtxEvalParser::Open )
583 else if( post[i].myType==QtxEvalParser::Close )
585 if( br_num<min_br_num )
589 return br+min_br_num;
593 \brief Sort the operations in the postfix.
595 Third step of parsing: sort the postfix operations in order to convert it to real postfix.
597 \param post source postfix
598 \param res returning resulting postfix
599 \param anOpen list of open brackets
600 \param aClose list of close brackets
601 \param f start index of postfix for sorting
602 \param l last index of postfix for sorting
603 \return \c true on success and \c false if error is found
605 bool QtxEvalParser::sort( const Postfix& post, Postfix& res, const QStringList& anOpen,
606 const QStringList& aClose, int f, int l )
615 l = post.count() - 1;
617 int br = globalBrackets( post, f, l );
621 if ( f == l && f >= 0 )
622 res.append( post[f] );
627 if ( !checkOperations() )
632 QList<PostfixItemType> min_types;
634 for ( int i = 0, j = f; j <= l; i++, j++ )
636 const PostfixItem& item = post[j];
637 PostfixItemType tt = item.myType;
638 if ( tt == Binary || tt == Pre || tt == Post )
640 int cur_pr = priority( item.myValue.toString(), tt == Binary );
643 if ( min < 0 || min >= cur_pr )
647 argmin.append( f + i );
648 min_types.append( tt );
654 argmin.append( f + i );
655 min_types.clear(); min_types.append( tt );
661 setError( QtxEvalExpr::InvalidOperation );
665 else if ( tt == Open )
667 QString opBr = item.myValue.toString();
668 int ind = anOpen.indexOf( opBr ), brValue = 0;
671 const PostfixItem& anItem = post[j];
672 if ( anItem.myType == Open )
675 if ( anItem.myType == Close )
678 QString clBr = anItem.myValue.toString();
679 if ( aClose.indexOf( clBr ) == ind && brValue == 0 )
687 setError( QtxEvalExpr::CloseExpected );
693 if ( error() == QtxEvalExpr::OK )
698 QList<Postfix> parts;
699 QIntList::const_iterator anIt = argmin.begin(), aLast = argmin.end();
700 bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 );
703 for ( ; anIt != aLast && ok; anIt++ )
705 QIntList::const_iterator aNext = anIt; aNext++;
706 ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext == aLast ? l : *aNext - 1 );
714 QStack<PostfixItem> aStack;
715 QList<Postfix>::const_iterator aPIt = parts.begin();
716 QList<PostfixItemType>::const_iterator aTIt = min_types.begin();
719 anIt = argmin.begin();
720 for ( ; anIt != aLast; anIt++, aPIt++, aTIt++ )
724 if ( anOpen.contains( post[*anIt].myValue.toString() ) == 0 )
727 aStack.push( post[ *anIt ] );
731 res.append( post[*anIt] );
738 while ( !aStack.isEmpty() )
740 res.append( aStack.top() );
743 res.append( post[*anIt] );
746 while ( !aStack.isEmpty() )
748 res.append( aStack.top() );
753 { //there are no operations
754 for ( int k = f; k <= l; k++ )
756 if ( post.at( k ).myType==Value || post.at( k ).myType == Param )
757 res.append( post.at( k ) );
762 return error() == QtxEvalExpr::OK;
766 \brief Parse the expression and build the posfix.
768 If by parsing error is found, the function returns \c false. In this case the code of the error
769 can be retrieved with error() method.
771 \param expr string expression
772 \return \c true on success and \c false if error is found
774 bool QtxEvalParser::parse( const QString& expr )
778 if ( !checkOperations() )
782 QStringList opens, closes;
784 setError( QtxEvalExpr::OK );
785 bracketsList( opens, true );
786 bracketsList( closes, false );
788 return prepare( expr, p ) && setOperationTypes( p ) && sort( p, myPostfix, opens, closes );
792 \brief Calculate the operation.
794 The result of the operation is returned in the parameter \a v1.
796 \param op operation name
797 \param v1 first argument (not valid for unary prefix operations)
798 \param v2 second argument (not valid for unary postfix operations)
799 \return \c true on success and \c false if error is found
801 bool QtxEvalParser::calculate( const QString& op, QVariant& v1, QVariant& v2 )
803 QtxEvalExpr::Error err = isValid( op, v1.type(), v2.type() );
804 if ( err == QtxEvalExpr::OK )
805 setError( calculation( op, v1, v2 ) );
809 return error() == QtxEvalExpr::OK;
813 \brief Calculate the expression without postfix rebuilding.
814 \return QVariant as result (it is invalid if there were errors during calculation)
816 QVariant QtxEvalParser::calculate()
818 if ( !checkOperations() )
821 setError( QtxEvalExpr::OK );
823 QStringList anOpen, aClose;
824 bracketsList( anOpen, true );
825 bracketsList( aClose, false );
827 QStack<QVariant> aStack;
828 Postfix::iterator anIt = myPostfix.begin(), aLast = myPostfix.end();
829 for ( ; anIt != aLast && error() == QtxEvalExpr::OK; anIt++ )
831 QString nn = (*anIt).myValue.toString();
832 if ( (*anIt).myType == Param )
834 if ( hasParameter( nn ) )
836 QVariant& v = myParams[nn];
840 setError( QtxEvalExpr::InvalidToken );
843 setError( QtxEvalExpr::InvalidToken );
845 else if ( (*anIt).myType == Value )
846 aStack.push( (*anIt).myValue );
847 else if ( (*anIt).myType == Pre || (*anIt).myType == Post )
849 if ( anOpen.contains( nn ) )
852 if ( calculate( nn, inv, inv ) )
853 aStack.push( QVariant() );
855 else if ( aClose.contains( nn ) )
860 if ( aStack.isEmpty() )
862 setError( QtxEvalExpr::StackUnderflow );
865 if ( aStack.top().isValid() )
867 set.append( aStack.top() );
877 QVariant qSet = set, inv;
878 if ( calculate( nn, qSet, inv ) )
881 else if ( aStack.count() >= 1 )
884 QVariant* v1 = &aStack.top(), *v2 = &inv; //"post-" case
885 if ( (*anIt).myType == Pre )
890 calculate( nn, *v1, *v2 );
893 setError( QtxEvalExpr::StackUnderflow );
895 else if ( (*anIt).myType == Binary )
897 if ( aStack.count() >= 2 )
899 QVariant v2 = aStack.top();
901 calculate( nn, aStack.top(), v2 );
904 setError( QtxEvalExpr::StackUnderflow );
909 if ( error() == QtxEvalExpr::OK )
911 int count = aStack.count();
913 setError( QtxEvalExpr::StackUnderflow );
914 else if( count == 1 )
917 setError( QtxEvalExpr::ExcessData );
923 \brief Change the expression, rebuild the postfix and calculate it.
924 \param expr new expression
925 \return QVariant as result (it is invalid if there were errors during calculation)
927 QVariant QtxEvalParser::calculate( const QString& expr )
929 setExpression( expr );
934 \brief Change the expression and rebuild the postfix.
935 \param expr new expression
936 \return \c true on success and \c false if error is found
938 bool QtxEvalParser::setExpression( const QString& expr )
940 return parse( expr );
944 \brief Check if the parser contains specified parameter.
945 \param name parameter name
946 \return \c true, if the parser contains parameter
948 bool QtxEvalParser::hasParameter( const QString& name ) const
950 return myParams.contains( name.trimmed() );
954 \brief Set parameters value.
955 \param name parameter name
956 \param value parameter value
958 void QtxEvalParser::setParameter( const QString& name, const QVariant& value )
960 myParams.insert( name.trimmed(), value );
964 \brief Remove parameter.
965 \param name parameter name
966 \return \c true on success
968 bool QtxEvalParser::removeParameter( const QString& name )
970 return myParams.remove( name.trimmed() );
974 \brief Get the parameter value.
975 \param name parameter name
976 \return parameter value or invalud QVariant if there is no such parameter
978 QVariant QtxEvalParser::parameter( const QString& name ) const
981 if ( myParams.contains( name.trimmed() ) )
982 res = myParams[name.trimmed()].toString();
987 \brief Search first parameter with assigned invalid value.
988 \param name used to retrieve the name of the parameter if it is found
989 \return \c true if parameter is found
991 bool QtxEvalParser::firstInvalid( QString& name ) const
993 for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
995 if ( !anIt.value().isValid() )
1005 \brief Remove all parameters with assigned invalid values.
1007 void QtxEvalParser::removeInvalids()
1009 QStringList toDelete;
1010 for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
1012 if ( !anIt.value().isValid() )
1013 toDelete.append( anIt.key() );
1016 for ( QStringList::const_iterator aLIt = toDelete.begin(); aLIt != toDelete.end(); aLIt++ )
1017 myParams.remove( *aLIt );
1021 \brief Get the code of the latest parsing error.
1022 \return last error code
1024 QtxEvalExpr::Error QtxEvalParser::error() const
1030 \brief Set the error vode.
1032 \param err error code
1034 void QtxEvalParser::setError( QtxEvalExpr::Error err )
1040 \brief Dump the current postfix contents to the string.
1041 \return string representation of the internal parser postfix
1043 QString QtxEvalParser::dump() const
1045 return dump( myPostfix );
1049 \brief Dump the postfix contents to the string.
1050 \param post postfix to be dumped
1051 \return string representation of the postfix
1053 QString QtxEvalParser::dump( const Postfix& post ) const
1057 if ( !checkOperations() )
1060 for ( Postfix::const_iterator anIt = post.begin(); anIt != post.end(); anIt++ )
1062 if ( (*anIt).myType == Value && (*anIt).myValue.type() == QVariant::String )
1063 res += "'" + (*anIt).myValue.toString() + "'";
1065 res += (*anIt).myValue.toString();
1067 if ( (*anIt).myType == Pre )
1069 else if ( (*anIt).myType == Post )
1071 else if ( (*anIt).myType == Binary )
1081 \brief Get the list of the parameters names.
1082 \return parameters names
1084 QStringList QtxEvalParser::parameters() const
1087 for ( Postfix::const_iterator anIt = myPostfix.begin(); anIt != myPostfix.end(); anIt++ )
1089 if ( (*anIt).myType == Param )
1091 QString name = (*anIt).myValue.toString();
1092 if ( !lst.contains( name ) )
1100 \brief Remove all parameters.
1102 void QtxEvalParser::clearParameters()
1108 \brief Get the string representation for the list of QVariant values.
1109 \param list list to be converted
1110 \return string representation for the list
1112 QString QtxEvalParser::toString( const QList<QVariant>& list )
1114 QString res = "set : [ ";
1115 for ( QList<QVariant>::const_iterator anIt = list.begin(); anIt != list.end(); anIt++ )
1116 res += (*anIt).toString() + " ";
1122 \brief Get names of all operations used in the expression.
1123 \param list returning list of the operations names
1125 void QtxEvalParser::operationList( QStringList& list ) const
1127 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1130 QtxEvalSet* set = *it;
1131 set->operationList( custom );
1132 for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1134 if ( !list.contains( *sIt ) )
1135 list.append( *sIt );
1141 \brief Get list of brackets.
1142 \param list returning list of brackets
1143 \param open if \c true, collect opening brackets, or closing brackets otherwise
1145 void QtxEvalParser::bracketsList( QStringList& list, bool open ) const
1147 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1150 QtxEvalSet* set = *it;
1151 set->bracketsList( custom, open );
1152 for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1154 if ( !list.contains( *sIt ) )
1155 list.append( *sIt );
1161 \brief Create value.
1162 \param str parsed string
1163 \param val returning value
1164 \return \c true on success
1166 bool QtxEvalParser::createValue( const QString& str, QVariant& val ) const
1169 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !ok; ++it )
1170 ok = (*it)->createValue( str, val );
1175 \brief Get the operation priority level.
1177 \param isBin \c true if the operation is binary and \c false if it is unary
1178 \return operation priority
1180 int QtxEvalParser::priority( const QString& op, bool isBin ) const
1184 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
1185 priority = (*it)->priority( op, isBin );
1187 return priority > 0 ? priority + i * 50 : 0;
1191 \brief Check operation validity.
1193 If the operation is valid, QtxEvalExpr::OK is returned.
1196 \param t1 first operand type
1197 \param t2 second operand type
1198 \return error code (QtxEvalExpr::Error)
1200 QtxEvalExpr::Error QtxEvalParser::isValid( const QString& op,
1201 const QVariant::Type t1, const QVariant::Type t2 ) const
1203 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1204 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1206 err = (*it)->isValid( op, t1, t2 );
1207 if ( err == QtxEvalExpr::OK )
1214 \brief Perform calculation
1216 The result of the operation is returned in the parameter \a v1.
1217 If the operation is calculated correctly, the function returns QtxEvalExpr::OK.
1219 \param op operation name
1220 \param v1 first argument (not valid for unary prefix operations)
1221 \param v2 second argument (not valid for unary postfix operations)
1222 \return error code (QtxEvalExpr::Error)
1224 QtxEvalExpr::Error QtxEvalParser::calculation( const QString& op, QVariant& v1, QVariant& v2 ) const
1227 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1231 if ( (*it)->isValid( op, v1.type(), v2.type() ) == QtxEvalExpr::OK )
1233 QtxEvalExpr::Error err = (*it)->calculate( op, nv1, nv2 );
1234 if ( err == QtxEvalExpr::OK || err == QtxEvalExpr::InvalidResult )
1242 return QtxEvalExpr::InvalidOperation;
1246 \brief Check current operations set.
1247 \return \c false if current set of operations is empty
1249 bool QtxEvalParser::checkOperations() const
1251 if ( !mySets.isEmpty() )
1254 QtxEvalParser* that = (QtxEvalParser*)this;
1255 that->setError( QtxEvalExpr::OperationsNull );
1261 \brief Generic class for all the operations sets used in expressions.
1267 QtxEvalSet::QtxEvalSet()
1274 QtxEvalSet::~QtxEvalSet()
1279 \fn void QtxEvalSet::operationList( QStringList& list ) const;
1280 \brief Get the list of possible operations.
1281 \param list returning list of operations supported by the class
1285 \fn void QtxEvalSet::bracketsList( QStringList& list, bool open ) const;
1286 \brief Get list of brackets.
1287 \param list returning list of brackets
1288 \param open if \c true, collect opening brackets, or closing brackets otherwise
1292 \brief Create value from its string representation.
1294 By default, the string value is set, that corresponds to the parameter.
1295 Base implementation always returns \c false (it means that string
1296 is evaluated to the parameter).
1297 Successor class can re-implement this method to return \c true
1298 if the argument being parsed can be evaluated as custom value.
1300 \param str string representration of the value
1301 \param val returning value
1302 \return \c true if \a str can be evaluated as custom value and \c false
1303 otherwise (parameter)
1305 bool QtxEvalSet::createValue( const QString& str, QVariant& val ) const
1312 \fn int QtxEvalSet::priority( const QString& op, bool isBin ) const;
1313 \brief Get the operation priority.
1315 Operation priority counts from 1.
1316 If the operation is impossible, this function should return value <= 0.
1319 \param isBin \c true if the operation is binary and \c false if it is unary
1320 \return operation priority
1324 \fn QtxEvalExpr::Error QtxEvalSet::isValid( const QString& op, const QVariant::Type t1,
1325 const QVariant::Type t2 ) const;
1326 \brief Check operation validity.
1328 If the operation is valid, QtxEvalExpr::OK is returned.
1329 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1330 or QtxEvalExpr::InvalidOperation.
1333 \param t1 first operand type
1334 \param t2 second operand type
1335 \return error code (QtxEvalExpr::Error)
1339 \fn QtxEvalExpr::Error QtxEvalSet::calculate( const QString& op, QVariant& v1,
1340 QVariant& v2 ) const;
1341 \brief Calculate the operation.
1343 Process binary operation with values \a v1 and \a v2.
1344 For unary operation the \v2 is invalid.
1345 The result of the operation is returned in the parameter \a v1.
1347 \param op operation name
1348 \param v1 first argument (not valid for unary prefix operations)
1349 \param v2 second argument (not valid for unary postfix operations)
1350 \return error code (QtxEvalExpr::Error)
1354 \fn QString QtxEvalSet::name() const;
1355 \brief Get unique operations set name.
1357 Should be redefined in the successor classes.
1359 \return operations set name
1363 \class QtxEvalSetBase
1364 \brief Generic class. Provides functionality for standard operations sets.
1370 QtxEvalSetBase::QtxEvalSetBase()
1377 QtxEvalSetBase::~QtxEvalSetBase()
1382 \brief Get list of brackets.
1383 \param list returning list of brackets
1384 \param open if \c true, collect opening brackets, or closing brackets otherwise
1386 void QtxEvalSetBase::bracketsList( QStringList& list, bool open ) const
1388 list.append( open ? "(" : ")" );
1392 \brief Get the list of possible operations.
1393 \param list returning list of operations supported by the class
1395 void QtxEvalSetBase::operationList( QStringList& list ) const
1401 \brief Add operation names to the internal list of operations.
1402 \param list operations to be added
1404 void QtxEvalSetBase::addOperations( const QStringList& list )
1406 for ( QStringList::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1408 if ( !myOpers.contains( *anIt ) )
1409 myOpers.append( *anIt );
1414 \brief Add operand types.
1415 \param list operand types to be added
1417 void QtxEvalSetBase::addTypes( const ListOfTypes& list )
1419 for ( ListOfTypes::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1421 if ( !myTypes.contains( *anIt ) )
1422 myTypes.append( *anIt );
1427 \brief Check operation validity.
1429 If the operation is valid, QtxEvalExpr::OK is returned.
1430 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1431 or QtxEvalExpr::InvalidOperation.
1434 \param t1 first operand type
1435 \param t2 second operand type
1436 \return error code (QtxEvalExpr::Error)
1438 QtxEvalExpr::Error QtxEvalSetBase::isValid( const QString& op,
1439 const QVariant::Type t1, const QVariant::Type t2 ) const
1441 if ( ( t1 == QVariant::Invalid || myTypes.contains( t1 ) ) &&
1442 ( t2 == QVariant::Invalid || myTypes.contains( t2 ) ) &&
1443 ( t1 != QVariant::Invalid || t2 != QVariant::Invalid ) )
1445 if ( priority( op, t1 != QVariant::Invalid && t2 != QVariant::Invalid ) > 0 )
1446 return QtxEvalExpr::OK;
1448 return QtxEvalExpr::InvalidOperation;
1451 return QtxEvalExpr::OperandsNotMatch;
1455 \class QtxEvalSetArithmetic
1456 \brief Provides set of arithmetical operations for the parser.
1462 QtxEvalSetArithmetic::QtxEvalSetArithmetic()
1465 addOperations( QString( "+;-;*;/;=;<;>;<=;>=;<>;!=" ).split( ";" ) );
1468 aTypes.append( QVariant::Int );
1469 aTypes.append( QVariant::UInt );
1470 aTypes.append( QVariant::Double );
1477 QtxEvalSetArithmetic::~QtxEvalSetArithmetic()
1482 \brief Get operations set name.
1483 \return operations set name
1485 QString QtxEvalSetArithmetic::Name()
1487 return "Arithmetic";
1491 \brief Get operations set name.
1492 \return operations set name
1494 QString QtxEvalSetArithmetic::name() const
1500 \brief Create value from its string representation.
1502 Creates numbers from string representation.
1504 \param str string representration of the value
1505 \param val returning value
1506 \return \c true if \a str can be evaluated as custom value and \c false
1507 otherwise (parameter)
1509 bool QtxEvalSetArithmetic::createValue( const QString& str, QVariant& val ) const
1512 val = str.toInt( &ok );
1516 val = str.toDouble( &ok );
1518 ok = QtxEvalSetBase::createValue( str, val );
1524 \brief Get the operation priority.
1526 Operation priority counts from 1.
1527 If the operation is impossible, this function returns value <= 0.
1530 \param isBin \c true if the operation is binary and \c false if it is unary
1531 \return operation priority
1533 int QtxEvalSetArithmetic::priority( const QString& op, bool isBin ) const
1537 if ( op == "<" || op == ">" || op == "=" ||
1538 op == "<=" || op == ">=" || op == "<>" || op == "!=" )
1540 else if ( op == "+" || op == "-" )
1542 else if( op == "*" || op == "/" )
1547 else if ( op == "+" || op == "-" )
1554 \brief Calculate the operation.
1556 Process binary operation with values \a v1 and \a v2.
1557 For unary operation the \v2 is invalid.
1558 The result of the operation is returned in the parameter \a v1.
1560 \param op operation name
1561 \param v1 first argument (not valid for unary prefix operations)
1562 \param v2 second argument (not valid for unary postfix operations)
1563 \return error code (QtxEvalExpr::Error)
1565 QtxEvalExpr::Error QtxEvalSetArithmetic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1567 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1569 if ( v1.isValid() && v2.isValid() )
1571 // binary operations
1572 if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::UInt ) &&
1573 ( v2.type() == QVariant::Int || v2.type() == QVariant::UInt ) )
1575 int _v1 = v1.toInt();
1576 int _v2 = v2.toInt();
1580 else if ( op == "-" )
1582 else if ( op == "*" )
1584 else if ( op == "/" )
1588 if ( _v1 % _v2 == 0 )
1591 v1 = double( _v1 ) / double( _v2 );
1594 err = QtxEvalExpr::InvalidResult;
1596 else if ( op == "<" )
1598 else if ( op == ">" )
1600 else if ( op == "=" )
1602 else if ( op == "<=" )
1604 else if ( op == ">=" )
1606 else if ( op == "<>" || op == "!=" )
1609 else if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::Double ) &&
1610 ( v2.type() == QVariant::Int || v2.type() == QVariant::Double ) )
1612 double _v1 = v1.toDouble();
1613 double _v2 = v2.toDouble();
1617 else if ( op == "-" )
1619 else if ( op == "*" )
1621 else if ( op == "/" )
1626 err = QtxEvalExpr::InvalidResult;
1628 else if ( op == "<" )
1630 else if ( op == ">" )
1632 else if ( op == "=" )
1634 else if ( op == "<=" )
1636 else if ( op == ">=" )
1638 else if ( op == "<>" || op == "!=" )
1641 else // prefix operations
1645 if ( v2.type() == QVariant::Int )
1647 else if ( v2.type() == QVariant::Double )
1648 v2 = -v2.toDouble();
1657 \class QtxEvalSetLogic
1658 \brief Provides set of logical operations for the parser.
1664 QtxEvalSetLogic::QtxEvalSetLogic()
1667 addOperations( QString( "and;&&;or;||;xor;not;!;imp;=" ).split( ";" ) );
1670 aTypes.append( QVariant::Bool );
1671 aTypes.append( QVariant::Int );
1672 aTypes.append( QVariant::UInt );
1679 QtxEvalSetLogic::~QtxEvalSetLogic()
1684 \brief Get operations set name.
1685 \return operations set name
1687 QString QtxEvalSetLogic::Name()
1693 \brief Get operations set name.
1694 \return operations set name
1696 QString QtxEvalSetLogic::name() const
1702 \brief Create value from its string representation.
1704 Create \c true or \c false value from string representation.
1706 \param str string representration of the value
1707 \param val returning value
1708 \return \c true if \a str can be evaluated as custom value and \c false
1709 otherwise (parameter)
1711 bool QtxEvalSetLogic::createValue( const QString& str, QVariant& val ) const
1714 QString valStr = str.toLower();
1715 if ( valStr == "true" || valStr == "yes" )
1716 val = QVariant( true );
1717 else if ( valStr == "false" || valStr == "no" )
1718 val = QVariant( false );
1720 ok = QtxEvalSetBase::createValue( str, val );
1726 \brief Get the operation priority.
1728 Operation priority counts from 1.
1729 If the operation is impossible, this function returns value <= 0.
1732 \param isBin \c true if the operation is binary and \c false if it is unary
1733 \return operation priority
1735 int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
1739 if ( op == "and" || op == "or" || op == "xor" || op == "&&" || op == "||" || op == "imp" )
1741 else if ( op == "=" )
1746 else if ( op == "not" || op == "!" )
1753 \brief Calculate the operation.
1755 Process binary operation with values \a v1 and \a v2.
1756 For unary operation the \v2 is invalid.
1757 The result of the operation is returned in the parameter \a v1.
1759 \param op operation name
1760 \param v1 first argument (not valid for unary prefix operations)
1761 \param v2 second argument (not valid for unary postfix operations)
1762 \return error code (QtxEvalExpr::Error)
1764 QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1766 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1767 int val1 = intValue( v1 );
1768 int val2 = intValue( v2 );
1769 if ( v1.isValid() && v2.isValid() )
1771 if ( op == "and" || op == "&&" )
1773 else if ( op == "or" || op == "||" )
1775 else if ( op == "xor" )
1776 v1 = ( !val1 && val2 ) || ( val1 && !val2 );
1777 else if ( op == "imp" )
1779 else if ( op == "=" )
1782 else if ( op == "not" || op == "!" )
1789 \brief Convert value to the integer.
1791 Note: the value is converted to the integer (not boolean) in order
1792 to compare integer numbers correctly.
1794 \param v value being converted
1795 \return converted value
1797 int QtxEvalSetLogic::intValue( const QVariant& v ) const
1802 case QVariant::Bool:
1803 res = v.toBool() ? 1 : 0;
1806 case QVariant::UInt:
1816 \class QtxEvalSetMath
1817 \brief Provides a set of more complex operations (mathematical functions)
1818 for the parser (sqrt, sin, cos, etc).
1824 QtxEvalSetMath::QtxEvalSetMath()
1827 addOperations( QString( "sqrt;abs;sin;cos;rad2grad;grad2rad" ).split( ";" ) );
1830 aTypes.append( QVariant::Int );
1831 aTypes.append( QVariant::Double );
1838 QtxEvalSetMath::~QtxEvalSetMath()
1843 \brief Get operations set name.
1844 \return operations set name
1846 QString QtxEvalSetMath::Name()
1852 \brief Get operations set name.
1853 \return operations set name
1855 QString QtxEvalSetMath::name() const
1861 \brief Create value from its string representation.
1863 Creates numbers from string representation.
1865 \param str string representration of the value
1866 \param val returning value
1867 \return \c true if \a str can be evaluated as custom value and \c false
1868 otherwise (parameter)
1870 bool QtxEvalSetMath::createValue( const QString& str, QVariant& val ) const
1873 val = str.toInt( &ok );
1877 val = str.toDouble( &ok );
1879 ok = QtxEvalSetBase::createValue( str, val );
1885 \brief Get the operation priority.
1887 Operation priority counts from 1.
1888 If the operation is impossible, this function returns value <= 0.
1891 \param isBin \c true if the operation is binary and \c false if it is unary
1892 \return operation priority
1894 int QtxEvalSetMath::priority( const QString& op, bool isBin ) const
1898 else if ( op == "sqrt" || op == "abs" || op == "sin" ||
1899 op == "cos" || op == "rad2grad" || op == "grad2rad" )
1906 \brief Calculate the operation.
1908 Process binary operation with values \a v1 and \a v2.
1909 For unary operation the \v2 is invalid.
1910 The result of the operation is returned in the parameter \a v1.
1912 \param op operation name
1913 \param v1 first argument (not valid for unary prefix operations)
1914 \param v2 second argument (not valid for unary postfix operations)
1915 \return error code (QtxEvalExpr::Error)
1917 QtxEvalExpr::Error QtxEvalSetMath::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1919 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1920 double val = v2.toDouble();
1926 err = QtxEvalExpr::InvalidResult;
1928 else if ( op == "abs" )
1930 if ( v2.type() == QVariant::Int )
1931 v2 = abs( v2.toInt() );
1933 v2 = fabs( v2.toDouble() );
1935 else if ( op == "sin" )
1937 else if ( op == "cos" )
1939 else if ( op == "grad2rad" )
1940 v2 = val * 3.14159256 / 180.0;
1941 else if ( op == "rad2grad" )
1942 v2 = val * 180.0 / 3.14159256;
1948 \class QtxEvalSetString
1949 \brief Provides set of string operations for the parser.
1955 QtxEvalSetString::QtxEvalSetString()
1958 addOperations( QString( "+;=;<;>;<=;>=;<>;!=;length;lower;upper" ).split( ";" ) );
1961 aTypes.append( QVariant::Int );
1962 aTypes.append( QVariant::Double );
1963 aTypes.append( QVariant::String );
1970 QtxEvalSetString::~QtxEvalSetString()
1975 \brief Get operations set name.
1976 \return operations set name
1978 QString QtxEvalSetString::Name()
1984 \brief Get operations set name.
1985 \return operations set name
1987 QString QtxEvalSetString::name() const
1993 \brief Create value from its string representation.
1995 Creates string value from Qt string representation.
1997 \param str string representration of the value
1998 \param val returning value
1999 \return \c true if \a str can be evaluated as custom value and \c false
2000 otherwise (parameter)
2002 bool QtxEvalSetString::createValue( const QString& str, QVariant& val ) const
2005 if ( str.length() > 1 && str[0] == '\'' && str[str.length() - 1] == '\'' )
2007 val = str.mid( 1, str.length() - 2 );
2011 ok = QtxEvalSetBase::createValue( str, val );
2016 \brief Get the operation priority.
2018 Operation priority counts from 1.
2019 If the operation is impossible, this function returns value <= 0.
2022 \param isBin \c true if the operation is binary and \c false if it is unary
2023 \return operation priority
2025 int QtxEvalSetString::priority( const QString& op, bool isBin ) const
2031 else if ( op == "=" || op == "<" || op == ">" ||
2032 op == "<=" || op == ">=" || op == "<>" || op == "!=" )
2037 else if ( op == "length" || op == "lower" || op=="upper" )
2044 \brief Calculate the operation.
2046 Process binary operation with values \a v1 and \a v2.
2047 For unary operation the \v2 is invalid.
2048 The result of the operation is returned in the parameter \a v1.
2050 \param op operation name
2051 \param v1 first argument (not valid for unary prefix operations)
2052 \param v2 second argument (not valid for unary postfix operations)
2053 \return error code (QtxEvalExpr::Error)
2055 QtxEvalExpr::Error QtxEvalSetString::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2057 QtxEvalExpr::Error err = QtxEvalExpr::OK;
2058 if ( v1.isValid() && v2.isValid() )
2060 QString _v1 = v1.toString();
2061 QString _v2 = v2.toString();
2064 else if ( op == "=" )
2066 else if ( op == "<" )
2068 else if ( op == ">" )
2070 else if ( op == "<>" || op == "!=" )
2072 else if ( op == "<=" )
2073 v1 = _v1 < _v2 || _v1 == _v2;
2074 else if ( op == ">=" )
2075 v1 = _v1 > _v2 || _v1 == _v2;
2077 else if ( !v1.isValid() && v2.isValid() )
2079 QString val = v2.toString();
2080 if ( op == "length" )
2081 v2 = (int)val.length();
2082 else if ( op == "lower" )
2084 else if ( op == "upper" )
2091 \class QtxEvalSetSets
2092 \brief Provides set of operations with sequences for the parser.
2098 QtxEvalSetSets::QtxEvalSetSets()
2101 addOperations( QString( "{;};=;<>;!=;+;-;*;in;count" ).split( ";" ) );
2104 aTypes.append( QVariant::List );
2111 QtxEvalSetSets::~QtxEvalSetSets()
2116 \brief Get operations set name.
2117 \return operations set name
2119 QString QtxEvalSetSets::Name()
2125 \brief Get operations set name.
2126 \return operations set name
2128 QString QtxEvalSetSets::name() const
2134 \brief Get list of brackets.
2135 \param list returning list of brackets
2136 \param open if \c true, collect opening brackets, or closing brackets otherwise
2138 void QtxEvalSetSets::bracketsList( QStringList& list, bool open ) const
2140 list.append( open ? "{" : "}" );
2141 QtxEvalSetBase::bracketsList( list, open );
2145 \brief Get the operation priority.
2147 Operation priority counts from 1.
2148 If the operation is impossible, this function returns value <= 0.
2151 \param isBin \c true if the operation is binary and \c false if it is unary
2152 \return operation priority
2154 int QtxEvalSetSets::priority( const QString& op, bool isBin ) const
2158 if ( op == "=" || op == "<>" || op == "!=" )
2160 else if ( op == "+" || op == "-" || op == "*" )
2162 else if ( op == "in" )
2167 else if ( op == "{" || op == "}" )
2169 else if ( op == "count" )
2176 \brief Check operation validity.
2178 If the operation is valid, QtxEvalExpr::OK is returned.
2179 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
2180 or QtxEvalExpr::InvalidOperation.
2183 \param t1 first operand type
2184 \param t2 second operand type
2185 \return error code (QtxEvalExpr::Error)
2187 QtxEvalExpr::Error QtxEvalSetSets::isValid( const QString& op,
2188 const QVariant::Type t1, const QVariant::Type t2 ) const
2191 return QtxEvalExpr::OK;
2194 return QtxEvalSetBase::isValid( op, t1, t2 );
2196 if ( t1 != QVariant::Invalid && t2 == QVariant::List )
2197 return QtxEvalExpr::OK;
2199 return QtxEvalExpr::OperandsNotMatch;
2203 \brief Add new value \a v to the sequence \a set.
2205 \param v value to be added
2207 void QtxEvalSetSets::add( ValueSet& set, const QVariant& v )
2209 if ( v.isValid() && !set.contains( v ) )
2214 \brief Add all values from sequence \a s2 to the sequence \a s1.
2215 \param s1 destination sequence
2216 \param s2 source sequence
2218 void QtxEvalSetSets::add( ValueSet& s1, const ValueSet& s2 )
2220 for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2225 \brief Remove value \a v from sequence \a set.
2227 \param v value to be removed
2229 void QtxEvalSetSets::remove( ValueSet& set, const QVariant& v )
2235 \brief Remove all values listed in the sequence \a s2 from the sequence \a s1.
2236 \param s1 sequence from which items are removed
2237 \param s2 sequence which items are removed
2239 void QtxEvalSetSets::remove( ValueSet& s1, const ValueSet& s2 )
2241 for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2242 s1.removeAll( *anIt );
2246 \brief Calculate the operation.
2248 Process binary operation with values \a v1 and \a v2.
2249 For unary operation the \v2 is invalid.
2250 The result of the operation is returned in the parameter \a v1.
2252 \param op operation name
2253 \param v1 first argument (not valid for unary prefix operations)
2254 \param v2 second argument (not valid for unary postfix operations)
2255 \return error code (QtxEvalExpr::Error)
2257 QtxEvalExpr::Error QtxEvalSetSets::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2259 QtxEvalExpr::Error err = QtxEvalExpr::OK;
2266 add( aNewList, v1.toList() );
2269 else if ( op == "=" || op == "<>" || op == "!=" || op == "+" || op == "-" || op == "*" )
2272 add( aNewList, v1.toList() );
2273 if ( op == "=" || op == "<>" || op == "!=" || op == "-" )
2275 remove( aNewList, v2.toList() );
2277 v1 = aNewList.isEmpty() && v1.toList().count() == v2.toList().count();
2278 else if ( op == "<>" || op == "!=" )
2279 v1 = !aNewList.isEmpty() || v1.toList().count() != v2.toList().count();
2283 else if ( op == "+" )
2285 add( aNewList, v2.toList() );
2288 else if ( op == "*" )
2291 add( toDelete, aNewList );
2292 remove( toDelete, v2.toList() );
2293 remove( aNewList, toDelete );
2297 else if ( op== "count" )
2298 v2 = (int)v2.toList().count();
2299 else if ( op == "in" )
2301 if ( v1.type() == QVariant::List )
2304 ValueSet lst1 = v1.toList();
2305 ValueSet lst2 = v2.toList();
2306 for ( ValueSet::const_iterator anIt = lst1.begin(); anIt != lst1.end() && res; ++anIt )
2307 res = lst2.contains( *anIt );
2312 v1 = QVariant( v2.toList().contains( v1 ) );
2319 \class QtxEvalSetConst
2320 \brief Provides different standard constants.
2322 QtxEvalSetConst::QtxEvalSetConst()
2330 QtxEvalSetConst::~QtxEvalSetConst()
2335 \brief Get operations set name.
2336 \return operations set name
2338 QString QtxEvalSetConst::Name()
2344 \brief Get operations set name.
2345 \return operations set name
2347 QString QtxEvalSetConst::name() const
2353 \brief Create value from its string representation.
2355 Convert constant name to its value.
2357 \param str string representration of the constant
2358 \param val returning value
2359 \return \c true if \a str can be evaluated as custom value and \c false
2360 otherwise (parameter)
2362 bool QtxEvalSetConst::createValue( const QString& str, QVariant& val ) const
2365 if ( str == "pi" ) // PI number
2366 val = QVariant( 3.141593 );
2367 else if ( str == "exp" ) // Exponent value (e)
2368 val = QVariant( 2.718282 );
2369 else if ( str == "g" ) // Free fall acceleration (g)
2370 val = QVariant( 9.80665 );
2378 \brief Get the list of possible operations.
2379 \param list returning list of operations supported by the class (not used)
2381 void QtxEvalSetConst::operationList( QStringList& /*list*/ ) const
2386 \brief Get list of brackets.
2387 \param list returning list of brackets (not used)
2388 \param open if \c true, collect opening brackets, or closing brackets otherwise (not used)
2390 void QtxEvalSetConst::bracketsList( QStringList& /*list*/, bool /*open*/ ) const
2395 \brief Get the operation priority.
2397 Operation priority counts from 1.
2398 If the operation is impossible, this function returns value <= 0.
2400 \param op operation (not used)
2401 \param isBin \c true if the operation is binary and \c false if it is unary (not used)
2402 \return operation priority
2404 int QtxEvalSetConst::priority( const QString& /*op*/, bool /*isBin*/ ) const
2410 \brief Check operation validity.
2412 Always returns QtxEvalExpr::InvalidOperation.
2414 \param op operation (not used)
2415 \param t1 first operand type (not used)
2416 \param t2 second operand type (not used)
2417 \return error code (QtxEvalExpr::Error)
2419 QtxEvalExpr::Error QtxEvalSetConst::isValid( const QString& /*op*/,
2420 const QVariant::Type /*t1*/,
2421 const QVariant::Type /*t2*/ ) const
2423 return QtxEvalExpr::InvalidOperation;
2427 \brief Calculate the operation.
2429 Always returns QtxEvalExpr::InvalidOperation.
2431 \param op operation name (not used)
2432 \param v1 first argument (not valid for unary prefix operations) (not used)
2433 \param v2 second argument (not valid for unary postfix operations) (not used)
2434 \return error code (QtxEvalExpr::Error)
2436 QtxEvalExpr::Error QtxEvalSetConst::calculate( const QString&, QVariant&, QVariant& ) const
2438 return QtxEvalExpr::InvalidOperation;