1 // Copyright (C) 2007-2023 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: QtxEvalExpr.cxx
21 // Author: Alexander SOLOVYOV, Sergey TELKOV
23 #include "QtxEvalExpr.h"
31 \brief String expression evaluator.
37 The evaluator is initalized by standard operations. Use another constructor with parameter
38 \a stdSets = \c false to avoid initialization of evaluator with standard operations.
40 \param expr expression to be evaluated
42 QtxEvalExpr::QtxEvalExpr( const QString& expr )
44 intialize( true, expr );
49 \param stdSets if \c true, the evaluator is initalized by standard operations
50 \param expr expression to be evaluated
52 QtxEvalExpr::QtxEvalExpr( const bool stdSets, const QString& expr )
54 intialize( stdSets, expr );
60 QtxEvalExpr::~QtxEvalExpr()
66 \brief Initialize the evaluator.
67 \param stdSets if \c true, the evaluator is initalized by standard operations
68 \param expr expression to be evaluated
70 void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
72 myParser = new QtxEvalParser();
75 myParser->setAutoDeleteOperationSets( true );
76 myParser->insertOperationSet( new QtxEvalSetLogic() );
77 myParser->insertOperationSet( new QtxEvalSetArithmetic() );
78 myParser->insertOperationSet( new QtxEvalSetString() );
79 myParser->insertOperationSet( new QtxEvalSetMath() );
80 myParser->insertOperationSet( new QtxEvalSetSets() );
81 myParser->insertOperationSet( new QtxEvalSetConst() );
83 setExpression( expr );
87 \brief Evaluate the expression.
88 \param expr expression to be evaluated
89 \return result of the evaluation
91 QVariant QtxEvalExpr::calculate( const QString& expr )
93 if ( !expr.isEmpty() )
94 setExpression( expr );
95 return myParser->calculate();
99 \brief Get the expression.
100 \return expression string
102 QString QtxEvalExpr::expression() const
108 \brief Set the expression.
109 \param expr expression string
111 void QtxEvalExpr::setExpression( const QString& expr )
113 if ( expr == expression() )
117 myParser->setExpression( myExpr );
121 \brief Get the code of latest parsing error.
122 \return the code of the last error
124 QtxEvalExpr::Error QtxEvalExpr::error() const
126 return myParser->error();
130 \brief Get the expression parser.
131 \return expression parser
133 QtxEvalParser* QtxEvalExpr::parser() const
139 \brief Get current set of operations.
140 \return operations set
141 \sa insertOperationSet(), removeOperationSet(), operationSet()
143 QList<QtxEvalSet*> QtxEvalExpr::operationSets() const
145 return myParser->operationSets();
149 \brief Install the operation.
150 \param operation to be added
151 \param idx index in the list at which the operation shoud be inserted
152 \sa operationSets(), removeOperationSet(), operationSet()
154 void QtxEvalExpr::insertOperationSet( QtxEvalSet* set, const int idx )
156 myParser->insertOperationSet( set, idx );
160 \brief Remove the operation.
161 \param operation to be removed
162 \sa operationSets(), insertOperationSet(), operationSet()
164 void QtxEvalExpr::removeOperationSet( QtxEvalSet* set )
166 myParser->removeOperationSet( set );
170 \brief Get the operation by name.
171 \param name operation name
172 \return operation of 0 if not found
173 \sa operationSets(), insertOperationSet(), removeOperationSet()
175 QtxEvalSet* QtxEvalExpr::operationSet( const QString& name ) const
177 return myParser->operationSet( name );
181 \brief Get the 'auto-delete operations' flag value.
182 \return \c true if all operations shoud be automatically deleted when the evaluator is destroyed
183 \sa setAutoDeleteOperationSets()
185 bool QtxEvalExpr::autoDeleteOperationSets() const
187 return myParser->autoDeleteOperationSets();
191 \brief Set the 'auto-delete operations' flag value.
192 \param on if \c true, all operations shoud be automatically deleted when the evaluator is destroyed
193 \sa autoDeleteOperationSets()
195 void QtxEvalExpr::setAutoDeleteOperationSets( const bool on )
197 myParser->setAutoDeleteOperationSets( on );
202 \brief Expression parser.
204 This class provides the functionality to calculate value of the expression using defined set of operations.
205 Standard operations (arithmetics, logic, strings, etc) are implemented in the corresponding successors of the
206 QtxEvalSet class: QtxEvalSetArithmetic, QtxEvalSetLogic, QtxEvalSetMath, QtxEvalSetString, ...
208 The parser allows using parameters with help of methods has(), set(), remove(), value(). It uses
209 postfix representation of expressions and uses class QtxEvalSet in order to make certain operation.
211 Every instance of parser contains only one postfix - thus, if the expression is changed, the postfix
212 must be rebuilt. In order to increase performance of frequent calculations for many of expressions it is
213 recommended to use different instances of the parser for each expression.
219 QtxEvalParser::QtxEvalParser()
222 setError( QtxEvalExpr::OK );
228 QtxEvalParser::~QtxEvalParser()
230 if ( autoDeleteOperationSets() )
231 qDeleteAll( mySets );
235 \brief Get current operations set.
236 \return current operations set
238 QList<QtxEvalSet*> QtxEvalParser::operationSets() const
244 \brief Get the operations set by \a name.
245 \param name the name of the operation set
246 \return operation set or 0 if not found
248 QtxEvalSet* QtxEvalParser::operationSet( const QString& name ) const
251 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !set; ++it )
253 if ( (*it)->name() == name )
260 \brief Install the operations set.
261 \param operations set to be added
262 \param idx index in the list at which the operations set shoud be inserted
263 \sa operationSets(), removeOperationSet(), operationSet()
265 void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
267 if ( mySets.contains( set ) )
270 int index = idx < 0 ? mySets.count() : idx;
271 index = qMin( index, mySets.count() );
272 mySets.insert( index, set );
276 \brief Remove the operations set.
277 \param operations set to be removed
278 \sa operationSets(), insertOperationSet(), operationSet()
280 void QtxEvalParser::removeOperationSet( QtxEvalSet* set )
282 mySets.removeAll( set );
286 \brief Get the 'auto-delete operations' flag value.
287 \return \c true if all operations shoud be automatically deleted when the parser is destroyed
288 \sa setAutoDeleteOperationSets()
290 bool QtxEvalParser::autoDeleteOperationSets() const
296 \brief Set the 'auto-delete operations' flag value.
297 \param on if \c true, all operations shoud be automatically deleted when the parser is destroyed
298 \sa autoDeleteOperationSets()
300 void QtxEvalParser::setAutoDeleteOperationSets( const bool on )
306 \brief Search elements of the list as substrings starting from \a offset.
307 \param list list of substrings
308 \param str string in which the searching is performed
309 \param offset starting index for search
310 \param matchLen returning matching length of any substring
311 \param listind returning index of the found substring in the \a list
312 \return position of first found substring inside the \a str or -1 if no matches is found
314 int QtxEvalParser::search( const QStringList& list, const QString& str,
315 int offset, int& matchLen, int& listind )
318 QStringList::const_iterator anIt = list.begin(), aLast = list.end();
319 for ( int ind = 0; anIt != aLast; anIt++, ind++ )
321 int pos = str.indexOf( *anIt, offset );
322 if ( pos >= 0 && ( min < 0 || min > pos ||
323 ( min == pos && matchLen < (int)(*anIt).length() ) ) )
327 matchLen = (*anIt).length();
336 \brief Get the substring field from the string \a str.
337 \param str source string
338 \param pos start position of the substring
339 \param len length of the substring
340 \return substring (leading and trailing spaces are truncated)
342 QString QtxEvalParser::note( const QString& str, int pos, int len )
344 return str.mid( pos, len ).trimmed();
348 \brief Prepare to the parsing.
350 Performs the first step of the parsing:
352 - determine tokens types
353 - create unsorted pseudo-postfix (with brackets)
355 \param expr string expression
356 \param post postfix to be created
357 \return \c true on success and \c false if error is found
359 bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
362 int len = expr.length();
363 QStack<int> aBracketStack;
364 QStringList anOpers, anOpenBr, aCloseBr;
365 if ( !checkOperations() )
368 bracketsList( anOpenBr, true );
369 bracketsList( aCloseBr, false );
370 operationList( anOpers );
372 while ( pos < len && error() == QtxEvalExpr::OK )
375 while ( pos < len && expr[pos].isSpace() )
380 int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1;
381 int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind );
382 int cPos = oPos == pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind );
383 int opPos = search( anOpers, expr, pos, mLen, op_ind );
385 if ( expr[pos] == QChar( '\'' ) )
388 while ( vpos < (int)expr.length() && expr[vpos] != QChar( '\'' ) )
391 mLen = vpos - pos + 1;
393 int res = createValue( note( expr, pos, mLen ), item.myValue );
394 item.myType = res ? Value : Param;
402 aBracketStack.push( br_ind );
403 item.myValue = note( expr, pos, mBrLen );
407 else if ( cPos == pos )
409 if ( aBracketStack.count() == 0 )
411 setError( QtxEvalExpr::ExcessClose );
414 if ( br_ind != aBracketStack.top() )
416 setError( QtxEvalExpr::BracketsNotMatch );
422 item.myValue = note( expr, pos, mBrLen );
433 item.myValue = note( expr, pos, mLen );
434 item.myType = Binary;
437 post.insert( post.count() - 1, item );
444 if ( oPos != pos && cPos != pos )
447 for ( i = pos + 1; i < (int)expr.length(); i++ )
449 if ( expr[i].isSpace() )
454 if ( oPos >= 0 && oPos < vpos )
456 if ( cPos >= 0 && cPos < vpos )
458 if ( opPos >= 0 && opPos < vpos )
461 while( vpos < (int)expr.length() &&
462 ( expr[vpos].isLetter() || expr[vpos].isDigit() || expr[vpos]=='_' ) )
466 bool res = createValue( note( expr, pos, mLen ), item.myValue );
467 item.myType = res ? Value : Param;
472 pos += mBrLen + mLen;
477 for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
479 if ( (*anIt).myType == Open )
481 else if ( (*anIt).myType == Close )
487 setError( QtxEvalExpr::ExcessClose );
494 setError( QtxEvalExpr::CloseExpected );
496 return error() == QtxEvalExpr::OK;
500 \brief Analyze the operations used.
502 Second step of the parsing: analyze the types of the operations used in the expression.
504 \param post unsorted postfix
505 \return \c true on success and \c false if error is found
507 bool QtxEvalParser::setOperationTypes( Postfix& post )
509 if ( !checkOperations() )
512 QStringList anOpen, aClose;
513 bracketsList( anOpen, true );
514 bracketsList( aClose, false );
516 Postfix::iterator aPrev, aNext;
517 for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
523 if ( (*anIt).myType != Binary )
526 if ( ( anIt == post.begin() || (*aPrev).myType == Open ||
527 (*aPrev).myType == Pre || (*aPrev).myType == Binary ) && aNext != post.end() &&
528 ( (*aNext).myType == Value || (*aNext).myType == Param ||
529 (*aNext).myType == Open || (*aNext).myType == Binary ) )
530 (*anIt).myType = Pre;
531 else if ( anIt != post.begin() && ( (*aPrev).myType == Close || (*aPrev).myType == Param ||
532 (*aPrev).myType == Value || (*aPrev).myType == Pre ||
533 (*aPrev).myType == Post || (*aPrev).myType == Binary ) &&
534 ( aNext == post.end() || (*aNext).myType == Close ) )
535 (*anIt).myType = Post;
537 if ( anOpen.contains( (*anIt).myValue.toString() ) )
538 (*anIt).myType = Pre;
539 else if ( aClose.contains( (*anIt).myValue.toString() ) )
540 (*anIt).myType = Post;
543 return error() == QtxEvalExpr::OK;
547 \brief Get the number of the globar brackets pairs.
549 For example, the expression '((2+3))' has 2 global brackets pairs.
551 \param post postfix to be checked
552 \param f starting position for the search
553 \param l last position for the search
554 \return number of brackets pairs
556 int QtxEvalParser::globalBrackets( const QtxEvalParser::Postfix& post, int f, int l )
563 int min_br_num = (l-f+1)*5;
565 for( i=f; i<=l; i++ )
566 if( post[ i ].myType==QtxEvalParser::Open )
570 for( i=l; i>=f; i-- )
571 if( post[ i ].myType==QtxEvalParser::Close )
576 br = start_br<fin_br ? start_br : fin_br;
577 for( i=f+br; i<=l-br; i++ )
579 if( post[i].myType==QtxEvalParser::Open )
581 else if( post[i].myType==QtxEvalParser::Close )
583 if( br_num<min_br_num )
587 return br+min_br_num;
591 \brief Sort the operations in the postfix.
593 Third step of parsing: sort the postfix operations in order to convert it to real postfix.
595 \param post source postfix
596 \param res returning resulting postfix
597 \param anOpen list of open brackets
598 \param aClose list of close brackets
599 \param f start index of postfix for sorting
600 \param l last index of postfix for sorting
601 \return \c true on success and \c false if error is found
603 bool QtxEvalParser::sort( const Postfix& post, Postfix& res, const QStringList& anOpen,
604 const QStringList& aClose, int f, int l )
613 l = post.count() - 1;
615 int br = globalBrackets( post, f, l );
619 if ( f == l && f >= 0 )
620 res.append( post[f] );
625 if ( !checkOperations() )
630 QList<PostfixItemType> min_types;
632 for ( int i = 0, j = f; j <= l; i++, j++ )
634 const PostfixItem& item = post[j];
635 PostfixItemType tt = item.myType;
636 if ( tt == Binary || tt == Pre || tt == Post )
638 int cur_pr = priority( item.myValue.toString(), tt == Binary );
641 if ( min < 0 || min >= cur_pr )
645 argmin.append( f + i );
646 min_types.append( tt );
652 argmin.append( f + i );
653 min_types.clear(); min_types.append( tt );
659 setError( QtxEvalExpr::InvalidOperation );
663 else if ( tt == Open )
665 QString opBr = item.myValue.toString();
666 int ind = anOpen.indexOf( opBr ), brValue = 0;
669 const PostfixItem& anItem = post[j];
670 if ( anItem.myType == Open )
673 if ( anItem.myType == Close )
676 QString clBr = anItem.myValue.toString();
677 if ( aClose.indexOf( clBr ) == ind && brValue == 0 )
685 setError( QtxEvalExpr::CloseExpected );
691 if ( error() == QtxEvalExpr::OK )
696 QList<Postfix> parts;
697 QIntList::const_iterator anIt = argmin.begin(), aLast = argmin.end();
698 bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 );
701 for ( ; anIt != aLast && ok; anIt++ )
703 QIntList::const_iterator aNext = anIt; aNext++;
704 ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext == aLast ? l : *aNext - 1 );
712 QStack<PostfixItem> aStack;
713 QList<Postfix>::const_iterator aPIt = parts.begin();
714 QList<PostfixItemType>::const_iterator aTIt = min_types.begin();
717 anIt = argmin.begin();
718 for ( ; anIt != aLast; anIt++, aPIt++, aTIt++ )
722 if ( anOpen.contains( post[*anIt].myValue.toString() ) == 0 )
725 aStack.push( post[ *anIt ] );
729 res.append( post[*anIt] );
736 while ( !aStack.isEmpty() )
738 res.append( aStack.top() );
741 res.append( post[*anIt] );
744 while ( !aStack.isEmpty() )
746 res.append( aStack.top() );
751 { //there are no operations
752 for ( int k = f; k <= l; k++ )
754 if ( post.at( k ).myType==Value || post.at( k ).myType == Param )
755 res.append( post.at( k ) );
760 return error() == QtxEvalExpr::OK;
764 \brief Parse the expression and build the posfix.
766 If by parsing error is found, the function returns \c false. In this case the code of the error
767 can be retrieved with error() method.
769 \param expr string expression
770 \return \c true on success and \c false if error is found
772 bool QtxEvalParser::parse( const QString& expr )
776 if ( !checkOperations() )
780 QStringList opens, closes;
782 setError( QtxEvalExpr::OK );
783 bracketsList( opens, true );
784 bracketsList( closes, false );
786 return prepare( expr, p ) && setOperationTypes( p ) && sort( p, myPostfix, opens, closes );
790 \brief Calculate the operation.
792 The result of the operation is returned in the parameter \a v1.
794 \param op operation name
795 \param v1 first argument (not valid for unary prefix operations)
796 \param v2 second argument (not valid for unary postfix operations)
797 \return \c true on success and \c false if error is found
799 bool QtxEvalParser::calculate( const QString& op, QVariant& v1, QVariant& v2 )
801 QtxEvalExpr::Error err = isValid( op, v1.type(), v2.type() );
802 if ( err == QtxEvalExpr::OK )
803 setError( calculation( op, v1, v2 ) );
807 return error() == QtxEvalExpr::OK;
811 \brief Calculate the expression without postfix rebuilding.
812 \return QVariant as result (it is invalid if there were errors during calculation)
814 QVariant QtxEvalParser::calculate()
816 if ( !checkOperations() )
819 setError( QtxEvalExpr::OK );
821 QStringList anOpen, aClose;
822 bracketsList( anOpen, true );
823 bracketsList( aClose, false );
825 QStack<QVariant> aStack;
826 Postfix::iterator anIt = myPostfix.begin(), aLast = myPostfix.end();
827 for ( ; anIt != aLast && error() == QtxEvalExpr::OK; anIt++ )
829 QString nn = (*anIt).myValue.toString();
830 if ( (*anIt).myType == Param )
832 if ( hasParameter( nn ) )
834 QVariant& v = myParams[nn];
838 setError( QtxEvalExpr::InvalidToken );
841 setError( QtxEvalExpr::InvalidToken );
843 else if ( (*anIt).myType == Value )
844 aStack.push( (*anIt).myValue );
845 else if ( (*anIt).myType == Pre || (*anIt).myType == Post )
847 if ( anOpen.contains( nn ) )
850 if ( calculate( nn, inv, inv ) )
851 aStack.push( QVariant() );
853 else if ( aClose.contains( nn ) )
858 if ( aStack.isEmpty() )
860 setError( QtxEvalExpr::StackUnderflow );
863 if ( aStack.top().isValid() )
865 set.append( aStack.top() );
875 QVariant qSet = set, inv;
876 if ( calculate( nn, qSet, inv ) )
879 else if ( aStack.count() >= 1 )
882 QVariant* v1 = &aStack.top(), *v2 = &inv; //"post-" case
883 if ( (*anIt).myType == Pre )
888 calculate( nn, *v1, *v2 );
891 setError( QtxEvalExpr::StackUnderflow );
893 else if ( (*anIt).myType == Binary )
895 if ( aStack.count() >= 2 )
897 QVariant v2 = aStack.top();
899 calculate( nn, aStack.top(), v2 );
902 setError( QtxEvalExpr::StackUnderflow );
907 if ( error() == QtxEvalExpr::OK )
909 int count = aStack.count();
911 setError( QtxEvalExpr::StackUnderflow );
912 else if( count == 1 )
915 setError( QtxEvalExpr::ExcessData );
921 \brief Change the expression, rebuild the postfix and calculate it.
922 \param expr new expression
923 \return QVariant as result (it is invalid if there were errors during calculation)
925 QVariant QtxEvalParser::calculate( const QString& expr )
927 setExpression( expr );
932 \brief Change the expression and rebuild the postfix.
933 \param expr new expression
934 \return \c true on success and \c false if error is found
936 bool QtxEvalParser::setExpression( const QString& expr )
938 return parse( expr );
942 \brief Check if the parser contains specified parameter.
943 \param name parameter name
944 \return \c true, if the parser contains parameter
946 bool QtxEvalParser::hasParameter( const QString& name ) const
948 return myParams.contains( name.trimmed() );
952 \brief Set parameters value.
953 \param name parameter name
954 \param value parameter value
956 void QtxEvalParser::setParameter( const QString& name, const QVariant& value )
958 myParams.insert( name.trimmed(), value );
962 \brief Remove parameter.
963 \param name parameter name
964 \return \c true on success
966 bool QtxEvalParser::removeParameter( const QString& name )
968 return myParams.remove( name.trimmed() );
972 \brief Get the parameter value.
973 \param name parameter name
974 \return parameter value or invalud QVariant if there is no such parameter
976 QVariant QtxEvalParser::parameter( const QString& name ) const
979 if ( myParams.contains( name.trimmed() ) )
980 res = myParams[name.trimmed()].toString();
985 \brief Search first parameter with assigned invalid value.
986 \param name used to retrieve the name of the parameter if it is found
987 \return \c true if parameter is found
989 bool QtxEvalParser::firstInvalid( QString& name ) const
991 for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
993 if ( !anIt.value().isValid() )
1003 \brief Remove all parameters with assigned invalid values.
1005 void QtxEvalParser::removeInvalids()
1007 QStringList toDelete;
1008 for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
1010 if ( !anIt.value().isValid() )
1011 toDelete.append( anIt.key() );
1014 for ( QStringList::const_iterator aLIt = toDelete.begin(); aLIt != toDelete.end(); aLIt++ )
1015 myParams.remove( *aLIt );
1019 \brief Get the code of the latest parsing error.
1020 \return last error code
1022 QtxEvalExpr::Error QtxEvalParser::error() const
1028 \brief Set the error vode.
1030 \param err error code
1032 void QtxEvalParser::setError( QtxEvalExpr::Error err )
1038 \brief Dump the current postfix contents to the string.
1039 \return string representation of the internal parser postfix
1041 QString QtxEvalParser::dump() const
1043 return dump( myPostfix );
1047 \brief Dump the postfix contents to the string.
1048 \param post postfix to be dumped
1049 \return string representation of the postfix
1051 QString QtxEvalParser::dump( const Postfix& post ) const
1055 if ( !checkOperations() )
1058 for ( Postfix::const_iterator anIt = post.begin(); anIt != post.end(); anIt++ )
1060 if ( (*anIt).myType == Value && (*anIt).myValue.type() == QVariant::String )
1061 res += "'" + (*anIt).myValue.toString() + "'";
1063 res += (*anIt).myValue.toString();
1065 if ( (*anIt).myType == Pre )
1067 else if ( (*anIt).myType == Post )
1069 else if ( (*anIt).myType == Binary )
1079 \brief Get the list of the parameters names.
1080 \return parameters names
1082 QStringList QtxEvalParser::parameters() const
1085 for ( Postfix::const_iterator anIt = myPostfix.begin(); anIt != myPostfix.end(); anIt++ )
1087 if ( (*anIt).myType == Param )
1089 QString name = (*anIt).myValue.toString();
1090 if ( !lst.contains( name ) )
1098 \brief Remove all parameters.
1100 void QtxEvalParser::clearParameters()
1106 \brief Get the string representation for the list of QVariant values.
1107 \param list list to be converted
1108 \return string representation for the list
1110 QString QtxEvalParser::toString( const QList<QVariant>& list )
1112 QString res = "set : [ ";
1113 for ( QList<QVariant>::const_iterator anIt = list.begin(); anIt != list.end(); anIt++ )
1114 res += (*anIt).toString() + " ";
1120 \brief Get names of all operations used in the expression.
1121 \param list returning list of the operations names
1123 void QtxEvalParser::operationList( QStringList& list ) const
1125 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1128 QtxEvalSet* set = *it;
1129 set->operationList( custom );
1130 for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1132 if ( !list.contains( *sIt ) )
1133 list.append( *sIt );
1139 \brief Get list of brackets.
1140 \param list returning list of brackets
1141 \param open if \c true, collect opening brackets, or closing brackets otherwise
1143 void QtxEvalParser::bracketsList( QStringList& list, bool open ) const
1145 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1148 QtxEvalSet* set = *it;
1149 set->bracketsList( custom, open );
1150 for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1152 if ( !list.contains( *sIt ) )
1153 list.append( *sIt );
1159 \brief Create value.
1160 \param str parsed string
1161 \param val returning value
1162 \return \c true on success
1164 bool QtxEvalParser::createValue( const QString& str, QVariant& val ) const
1167 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !ok; ++it )
1168 ok = (*it)->createValue( str, val );
1173 \brief Get the operation priority level.
1175 \param isBin \c true if the operation is binary and \c false if it is unary
1176 \return operation priority
1178 int QtxEvalParser::priority( const QString& op, bool isBin ) const
1182 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
1183 priority = (*it)->priority( op, isBin );
1185 return priority > 0 ? priority + i * 50 : 0;
1189 \brief Check operation validity.
1191 If the operation is valid, QtxEvalExpr::OK is returned.
1194 \param t1 first operand type
1195 \param t2 second operand type
1196 \return error code (QtxEvalExpr::Error)
1198 QtxEvalExpr::Error QtxEvalParser::isValid( const QString& op,
1199 const QVariant::Type t1, const QVariant::Type t2 ) const
1201 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1202 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1204 err = (*it)->isValid( op, t1, t2 );
1205 if ( err == QtxEvalExpr::OK )
1212 \brief Perform calculation
1214 The result of the operation is returned in the parameter \a v1.
1215 If the operation is calculated correctly, the function returns QtxEvalExpr::OK.
1217 \param op operation name
1218 \param v1 first argument (not valid for unary prefix operations)
1219 \param v2 second argument (not valid for unary postfix operations)
1220 \return error code (QtxEvalExpr::Error)
1222 QtxEvalExpr::Error QtxEvalParser::calculation( const QString& op, QVariant& v1, QVariant& v2 ) const
1225 for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1229 if ( (*it)->isValid( op, v1.type(), v2.type() ) == QtxEvalExpr::OK )
1231 QtxEvalExpr::Error err = (*it)->calculate( op, nv1, nv2 );
1232 if ( err == QtxEvalExpr::OK || err == QtxEvalExpr::InvalidResult )
1240 return QtxEvalExpr::InvalidOperation;
1244 \brief Check current operations set.
1245 \return \c false if current set of operations is empty
1247 bool QtxEvalParser::checkOperations() const
1249 if ( !mySets.isEmpty() )
1252 QtxEvalParser* that = (QtxEvalParser*)this;
1253 that->setError( QtxEvalExpr::OperationsNull );
1259 \brief Generic class for all the operations sets used in expressions.
1265 QtxEvalSet::QtxEvalSet()
1272 QtxEvalSet::~QtxEvalSet()
1277 \fn void QtxEvalSet::operationList( QStringList& list ) const;
1278 \brief Get the list of possible operations.
1279 \param list returning list of operations supported by the class
1283 \fn void QtxEvalSet::bracketsList( QStringList& list, bool open ) const;
1284 \brief Get list of brackets.
1285 \param list returning list of brackets
1286 \param open if \c true, collect opening brackets, or closing brackets otherwise
1290 \brief Create value from its string representation.
1292 By default, the string value is set, that corresponds to the parameter.
1293 Base implementation always returns \c false (it means that string
1294 is evaluated to the parameter).
1295 Successor class can re-implement this method to return \c true
1296 if the argument being parsed can be evaluated as custom value.
1298 \param str string representration of the value
1299 \param val returning value
1300 \return \c true if \a str can be evaluated as custom value and \c false
1301 otherwise (parameter)
1303 bool QtxEvalSet::createValue( const QString& str, QVariant& val ) const
1310 \fn int QtxEvalSet::priority( const QString& op, bool isBin ) const;
1311 \brief Get the operation priority.
1313 Operation priority counts from 1.
1314 If the operation is impossible, this function should return value <= 0.
1317 \param isBin \c true if the operation is binary and \c false if it is unary
1318 \return operation priority
1322 \fn QtxEvalExpr::Error QtxEvalSet::isValid( const QString& op, const QVariant::Type t1,
1323 const QVariant::Type t2 ) const;
1324 \brief Check operation validity.
1326 If the operation is valid, QtxEvalExpr::OK is returned.
1327 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1328 or QtxEvalExpr::InvalidOperation.
1331 \param t1 first operand type
1332 \param t2 second operand type
1333 \return error code (QtxEvalExpr::Error)
1337 \fn QtxEvalExpr::Error QtxEvalSet::calculate( const QString& op, QVariant& v1,
1338 QVariant& v2 ) const;
1339 \brief Calculate the operation.
1341 Process binary operation with values \a v1 and \a v2.
1342 For unary operation the \v2 is invalid.
1343 The result of the operation is returned in the parameter \a v1.
1345 \param op operation name
1346 \param v1 first argument (not valid for unary prefix operations)
1347 \param v2 second argument (not valid for unary postfix operations)
1348 \return error code (QtxEvalExpr::Error)
1352 \fn QString QtxEvalSet::name() const;
1353 \brief Get unique operations set name.
1355 Should be redefined in the successor classes.
1357 \return operations set name
1361 \class QtxEvalSetBase
1362 \brief Generic class. Provides functionality for standard operations sets.
1368 QtxEvalSetBase::QtxEvalSetBase()
1375 QtxEvalSetBase::~QtxEvalSetBase()
1380 \brief Get list of brackets.
1381 \param list returning list of brackets
1382 \param open if \c true, collect opening brackets, or closing brackets otherwise
1384 void QtxEvalSetBase::bracketsList( QStringList& list, bool open ) const
1386 list.append( open ? "(" : ")" );
1390 \brief Get the list of possible operations.
1391 \param list returning list of operations supported by the class
1393 void QtxEvalSetBase::operationList( QStringList& list ) const
1399 \brief Add operation names to the internal list of operations.
1400 \param list operations to be added
1402 void QtxEvalSetBase::addOperations( const QStringList& list )
1404 for ( QStringList::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1406 if ( !myOpers.contains( *anIt ) )
1407 myOpers.append( *anIt );
1412 \brief Add operand types.
1413 \param list operand types to be added
1415 void QtxEvalSetBase::addTypes( const ListOfTypes& list )
1417 for ( ListOfTypes::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1419 if ( !myTypes.contains( *anIt ) )
1420 myTypes.append( *anIt );
1425 \brief Check operation validity.
1427 If the operation is valid, QtxEvalExpr::OK is returned.
1428 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1429 or QtxEvalExpr::InvalidOperation.
1432 \param t1 first operand type
1433 \param t2 second operand type
1434 \return error code (QtxEvalExpr::Error)
1436 QtxEvalExpr::Error QtxEvalSetBase::isValid( const QString& op,
1437 const QVariant::Type t1, const QVariant::Type t2 ) const
1439 if ( ( t1 == QVariant::Invalid || myTypes.contains( t1 ) ) &&
1440 ( t2 == QVariant::Invalid || myTypes.contains( t2 ) ) &&
1441 ( t1 != QVariant::Invalid || t2 != QVariant::Invalid ) )
1443 if ( priority( op, t1 != QVariant::Invalid && t2 != QVariant::Invalid ) > 0 )
1444 return QtxEvalExpr::OK;
1446 return QtxEvalExpr::InvalidOperation;
1449 return QtxEvalExpr::OperandsNotMatch;
1453 \class QtxEvalSetArithmetic
1454 \brief Provides set of arithmetical operations for the parser.
1460 QtxEvalSetArithmetic::QtxEvalSetArithmetic()
1463 addOperations( QString( "+;-;*;/;=;<;>;<=;>=;<>;!=" ).split( ";" ) );
1466 aTypes.append( QVariant::Int );
1467 aTypes.append( QVariant::UInt );
1468 aTypes.append( QVariant::Double );
1475 QtxEvalSetArithmetic::~QtxEvalSetArithmetic()
1480 \brief Get operations set name.
1481 \return operations set name
1483 QString QtxEvalSetArithmetic::Name()
1485 return "Arithmetic";
1489 \brief Get operations set name.
1490 \return operations set name
1492 QString QtxEvalSetArithmetic::name() const
1498 \brief Create value from its string representation.
1500 Creates numbers from string representation.
1502 \param str string representration of the value
1503 \param val returning value
1504 \return \c true if \a str can be evaluated as custom value and \c false
1505 otherwise (parameter)
1507 bool QtxEvalSetArithmetic::createValue( const QString& str, QVariant& val ) const
1510 val = str.toInt( &ok );
1514 val = str.toDouble( &ok );
1516 ok = QtxEvalSetBase::createValue( str, val );
1522 \brief Get the operation priority.
1524 Operation priority counts from 1.
1525 If the operation is impossible, this function returns value <= 0.
1528 \param isBin \c true if the operation is binary and \c false if it is unary
1529 \return operation priority
1531 int QtxEvalSetArithmetic::priority( const QString& op, bool isBin ) const
1535 if ( op == "<" || op == ">" || op == "=" ||
1536 op == "<=" || op == ">=" || op == "<>" || op == "!=" )
1538 else if ( op == "+" || op == "-" )
1540 else if( op == "*" || op == "/" )
1545 else if ( op == "+" || op == "-" )
1552 \brief Calculate the operation.
1554 Process binary operation with values \a v1 and \a v2.
1555 For unary operation the \v2 is invalid.
1556 The result of the operation is returned in the parameter \a v1.
1558 \param op operation name
1559 \param v1 first argument (not valid for unary prefix operations)
1560 \param v2 second argument (not valid for unary postfix operations)
1561 \return error code (QtxEvalExpr::Error)
1563 QtxEvalExpr::Error QtxEvalSetArithmetic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1565 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1567 if ( v1.isValid() && v2.isValid() )
1569 // binary operations
1570 if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::UInt ) &&
1571 ( v2.type() == QVariant::Int || v2.type() == QVariant::UInt ) )
1573 int _v1 = v1.toInt();
1574 int _v2 = v2.toInt();
1578 else if ( op == "-" )
1580 else if ( op == "*" )
1582 else if ( op == "/" )
1586 if ( _v1 % _v2 == 0 )
1589 v1 = double( _v1 ) / double( _v2 );
1592 err = QtxEvalExpr::InvalidResult;
1594 else if ( op == "<" )
1596 else if ( op == ">" )
1598 else if ( op == "=" )
1600 else if ( op == "<=" )
1602 else if ( op == ">=" )
1604 else if ( op == "<>" || op == "!=" )
1607 else if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::Double ) &&
1608 ( v2.type() == QVariant::Int || v2.type() == QVariant::Double ) )
1610 double _v1 = v1.toDouble();
1611 double _v2 = v2.toDouble();
1615 else if ( op == "-" )
1617 else if ( op == "*" )
1619 else if ( op == "/" )
1624 err = QtxEvalExpr::InvalidResult;
1626 else if ( op == "<" )
1628 else if ( op == ">" )
1630 else if ( op == "=" )
1632 else if ( op == "<=" )
1634 else if ( op == ">=" )
1636 else if ( op == "<>" || op == "!=" )
1639 else // prefix operations
1643 if ( v2.type() == QVariant::Int )
1645 else if ( v2.type() == QVariant::Double )
1646 v2 = -v2.toDouble();
1655 \class QtxEvalSetLogic
1656 \brief Provides set of logical operations for the parser.
1662 QtxEvalSetLogic::QtxEvalSetLogic()
1665 addOperations( QString( "and;&&;or;||;xor;not;!;imp;=" ).split( ";" ) );
1668 aTypes.append( QVariant::Bool );
1669 aTypes.append( QVariant::Int );
1670 aTypes.append( QVariant::UInt );
1677 QtxEvalSetLogic::~QtxEvalSetLogic()
1682 \brief Get operations set name.
1683 \return operations set name
1685 QString QtxEvalSetLogic::Name()
1691 \brief Get operations set name.
1692 \return operations set name
1694 QString QtxEvalSetLogic::name() const
1700 \brief Create value from its string representation.
1702 Create \c true or \c false value from string representation.
1704 \param str string representration of the value
1705 \param val returning value
1706 \return \c true if \a str can be evaluated as custom value and \c false
1707 otherwise (parameter)
1709 bool QtxEvalSetLogic::createValue( const QString& str, QVariant& val ) const
1712 QString valStr = str.toLower();
1713 if ( valStr == "true" || valStr == "yes" )
1714 val = QVariant( true );
1715 else if ( valStr == "false" || valStr == "no" )
1716 val = QVariant( false );
1718 ok = QtxEvalSetBase::createValue( str, val );
1724 \brief Get the operation priority.
1726 Operation priority counts from 1.
1727 If the operation is impossible, this function returns value <= 0.
1730 \param isBin \c true if the operation is binary and \c false if it is unary
1731 \return operation priority
1733 int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
1737 if ( op == "and" || op == "or" || op == "xor" || op == "&&" || op == "||" || op == "imp" )
1739 else if ( op == "=" )
1744 else if ( op == "not" || op == "!" )
1751 \brief Calculate the operation.
1753 Process binary operation with values \a v1 and \a v2.
1754 For unary operation the \v2 is invalid.
1755 The result of the operation is returned in the parameter \a v1.
1757 \param op operation name
1758 \param v1 first argument (not valid for unary prefix operations)
1759 \param v2 second argument (not valid for unary postfix operations)
1760 \return error code (QtxEvalExpr::Error)
1762 QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1764 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1765 int val1 = intValue( v1 );
1766 int val2 = intValue( v2 );
1767 if ( v1.isValid() && v2.isValid() )
1769 if ( op == "and" || op == "&&" )
1771 else if ( op == "or" || op == "||" )
1773 else if ( op == "xor" )
1774 v1 = ( !val1 && val2 ) || ( val1 && !val2 );
1775 else if ( op == "imp" )
1777 else if ( op == "=" )
1780 else if ( op == "not" || op == "!" )
1787 \brief Convert value to the integer.
1789 Note: the value is converted to the integer (not boolean) in order
1790 to compare integer numbers correctly.
1792 \param v value being converted
1793 \return converted value
1795 int QtxEvalSetLogic::intValue( const QVariant& v ) const
1800 case QVariant::Bool:
1801 res = v.toBool() ? 1 : 0;
1804 case QVariant::UInt:
1814 \class QtxEvalSetMath
1815 \brief Provides a set of more complex operations (mathematical functions)
1816 for the parser (sqrt, sin, cos, etc).
1822 QtxEvalSetMath::QtxEvalSetMath()
1825 addOperations( QString( "sqrt;abs;sin;cos;rad2grad;grad2rad" ).split( ";" ) );
1828 aTypes.append( QVariant::Int );
1829 aTypes.append( QVariant::Double );
1836 QtxEvalSetMath::~QtxEvalSetMath()
1841 \brief Get operations set name.
1842 \return operations set name
1844 QString QtxEvalSetMath::Name()
1850 \brief Get operations set name.
1851 \return operations set name
1853 QString QtxEvalSetMath::name() const
1859 \brief Create value from its string representation.
1861 Creates numbers from string representation.
1863 \param str string representration of the value
1864 \param val returning value
1865 \return \c true if \a str can be evaluated as custom value and \c false
1866 otherwise (parameter)
1868 bool QtxEvalSetMath::createValue( const QString& str, QVariant& val ) const
1871 val = str.toInt( &ok );
1875 val = str.toDouble( &ok );
1877 ok = QtxEvalSetBase::createValue( str, val );
1883 \brief Get the operation priority.
1885 Operation priority counts from 1.
1886 If the operation is impossible, this function returns value <= 0.
1889 \param isBin \c true if the operation is binary and \c false if it is unary
1890 \return operation priority
1892 int QtxEvalSetMath::priority( const QString& op, bool isBin ) const
1896 else if ( op == "sqrt" || op == "abs" || op == "sin" ||
1897 op == "cos" || op == "rad2grad" || op == "grad2rad" )
1904 \brief Calculate the operation.
1906 Process binary operation with values \a v1 and \a v2.
1907 For unary operation the \v2 is invalid.
1908 The result of the operation is returned in the parameter \a v1.
1910 \param op operation name
1911 \param v1 first argument (not valid for unary prefix operations)
1912 \param v2 second argument (not valid for unary postfix operations)
1913 \return error code (QtxEvalExpr::Error)
1915 QtxEvalExpr::Error QtxEvalSetMath::calculate( const QString& op, QVariant& /*v1*/, QVariant& v2 ) const
1917 QtxEvalExpr::Error err = QtxEvalExpr::OK;
1918 double val = v2.toDouble();
1924 err = QtxEvalExpr::InvalidResult;
1926 else if ( op == "abs" )
1928 if ( v2.type() == QVariant::Int )
1929 v2 = abs( v2.toInt() );
1931 v2 = fabs( v2.toDouble() );
1933 else if ( op == "sin" )
1935 else if ( op == "cos" )
1937 else if ( op == "grad2rad" )
1938 v2 = val * 3.14159256 / 180.0;
1939 else if ( op == "rad2grad" )
1940 v2 = val * 180.0 / 3.14159256;
1946 \class QtxEvalSetString
1947 \brief Provides set of string operations for the parser.
1953 QtxEvalSetString::QtxEvalSetString()
1956 addOperations( QString( "+;=;<;>;<=;>=;<>;!=;length;lower;upper" ).split( ";" ) );
1959 aTypes.append( QVariant::Int );
1960 aTypes.append( QVariant::Double );
1961 aTypes.append( QVariant::String );
1968 QtxEvalSetString::~QtxEvalSetString()
1973 \brief Get operations set name.
1974 \return operations set name
1976 QString QtxEvalSetString::Name()
1982 \brief Get operations set name.
1983 \return operations set name
1985 QString QtxEvalSetString::name() const
1991 \brief Create value from its string representation.
1993 Creates string value from Qt string representation.
1995 \param str string representration of the value
1996 \param val returning value
1997 \return \c true if \a str can be evaluated as custom value and \c false
1998 otherwise (parameter)
2000 bool QtxEvalSetString::createValue( const QString& str, QVariant& val ) const
2003 if ( str.length() > 1 && str[0] == '\'' && str[str.length() - 1] == '\'' )
2005 val = str.mid( 1, str.length() - 2 );
2009 ok = QtxEvalSetBase::createValue( str, val );
2014 \brief Get the operation priority.
2016 Operation priority counts from 1.
2017 If the operation is impossible, this function returns value <= 0.
2020 \param isBin \c true if the operation is binary and \c false if it is unary
2021 \return operation priority
2023 int QtxEvalSetString::priority( const QString& op, bool isBin ) const
2029 else if ( op == "=" || op == "<" || op == ">" ||
2030 op == "<=" || op == ">=" || op == "<>" || op == "!=" )
2035 else if ( op == "length" || op == "lower" || op=="upper" )
2042 \brief Calculate the operation.
2044 Process binary operation with values \a v1 and \a v2.
2045 For unary operation the \v2 is invalid.
2046 The result of the operation is returned in the parameter \a v1.
2048 \param op operation name
2049 \param v1 first argument (not valid for unary prefix operations)
2050 \param v2 second argument (not valid for unary postfix operations)
2051 \return error code (QtxEvalExpr::Error)
2053 QtxEvalExpr::Error QtxEvalSetString::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2055 QtxEvalExpr::Error err = QtxEvalExpr::OK;
2056 if ( v1.isValid() && v2.isValid() )
2058 QString _v1 = v1.toString();
2059 QString _v2 = v2.toString();
2062 else if ( op == "=" )
2064 else if ( op == "<" )
2066 else if ( op == ">" )
2068 else if ( op == "<>" || op == "!=" )
2070 else if ( op == "<=" )
2071 v1 = _v1 < _v2 || _v1 == _v2;
2072 else if ( op == ">=" )
2073 v1 = _v1 > _v2 || _v1 == _v2;
2075 else if ( !v1.isValid() && v2.isValid() )
2077 QString val = v2.toString();
2078 if ( op == "length" )
2079 v2 = (int)val.length();
2080 else if ( op == "lower" )
2082 else if ( op == "upper" )
2089 \class QtxEvalSetSets
2090 \brief Provides set of operations with sequences for the parser.
2096 QtxEvalSetSets::QtxEvalSetSets()
2099 addOperations( QString( "{;};=;<>;!=;+;-;*;in;count" ).split( ";" ) );
2102 aTypes.append( QVariant::List );
2109 QtxEvalSetSets::~QtxEvalSetSets()
2114 \brief Get operations set name.
2115 \return operations set name
2117 QString QtxEvalSetSets::Name()
2123 \brief Get operations set name.
2124 \return operations set name
2126 QString QtxEvalSetSets::name() const
2132 \brief Get list of brackets.
2133 \param list returning list of brackets
2134 \param open if \c true, collect opening brackets, or closing brackets otherwise
2136 void QtxEvalSetSets::bracketsList( QStringList& list, bool open ) const
2138 list.append( open ? "{" : "}" );
2139 QtxEvalSetBase::bracketsList( list, open );
2143 \brief Get the operation priority.
2145 Operation priority counts from 1.
2146 If the operation is impossible, this function returns value <= 0.
2149 \param isBin \c true if the operation is binary and \c false if it is unary
2150 \return operation priority
2152 int QtxEvalSetSets::priority( const QString& op, bool isBin ) const
2156 if ( op == "=" || op == "<>" || op == "!=" )
2158 else if ( op == "+" || op == "-" || op == "*" )
2160 else if ( op == "in" )
2165 else if ( op == "{" || op == "}" )
2167 else if ( op == "count" )
2174 \brief Check operation validity.
2176 If the operation is valid, QtxEvalExpr::OK is returned.
2177 If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
2178 or QtxEvalExpr::InvalidOperation.
2181 \param t1 first operand type
2182 \param t2 second operand type
2183 \return error code (QtxEvalExpr::Error)
2185 QtxEvalExpr::Error QtxEvalSetSets::isValid( const QString& op,
2186 const QVariant::Type t1, const QVariant::Type t2 ) const
2189 return QtxEvalExpr::OK;
2192 return QtxEvalSetBase::isValid( op, t1, t2 );
2194 if ( t1 != QVariant::Invalid && t2 == QVariant::List )
2195 return QtxEvalExpr::OK;
2197 return QtxEvalExpr::OperandsNotMatch;
2201 \brief Add new value \a v to the sequence \a set.
2203 \param v value to be added
2205 void QtxEvalSetSets::add( ValueSet& set, const QVariant& v )
2207 if ( v.isValid() && !set.contains( v ) )
2212 \brief Add all values from sequence \a s2 to the sequence \a s1.
2213 \param s1 destination sequence
2214 \param s2 source sequence
2216 void QtxEvalSetSets::add( ValueSet& s1, const ValueSet& s2 )
2218 for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2223 \brief Remove value \a v from sequence \a set.
2225 \param v value to be removed
2227 void QtxEvalSetSets::remove( ValueSet& set, const QVariant& v )
2233 \brief Remove all values listed in the sequence \a s2 from the sequence \a s1.
2234 \param s1 sequence from which items are removed
2235 \param s2 sequence which items are removed
2237 void QtxEvalSetSets::remove( ValueSet& s1, const ValueSet& s2 )
2239 for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2240 s1.removeAll( *anIt );
2244 \brief Calculate the operation.
2246 Process binary operation with values \a v1 and \a v2.
2247 For unary operation the \v2 is invalid.
2248 The result of the operation is returned in the parameter \a v1.
2250 \param op operation name
2251 \param v1 first argument (not valid for unary prefix operations)
2252 \param v2 second argument (not valid for unary postfix operations)
2253 \return error code (QtxEvalExpr::Error)
2255 QtxEvalExpr::Error QtxEvalSetSets::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2257 QtxEvalExpr::Error err = QtxEvalExpr::OK;
2264 add( aNewList, v1.toList() );
2267 else if ( op == "=" || op == "<>" || op == "!=" || op == "+" || op == "-" || op == "*" )
2270 add( aNewList, v1.toList() );
2271 if ( op == "=" || op == "<>" || op == "!=" || op == "-" )
2273 remove( aNewList, v2.toList() );
2275 v1 = aNewList.isEmpty() && v1.toList().count() == v2.toList().count();
2276 else if ( op == "<>" || op == "!=" )
2277 v1 = !aNewList.isEmpty() || v1.toList().count() != v2.toList().count();
2281 else if ( op == "+" )
2283 add( aNewList, v2.toList() );
2286 else if ( op == "*" )
2289 add( toDelete, aNewList );
2290 remove( toDelete, v2.toList() );
2291 remove( aNewList, toDelete );
2295 else if ( op== "count" )
2296 v2 = (int)v2.toList().count();
2297 else if ( op == "in" )
2299 if ( v1.type() == QVariant::List )
2302 ValueSet lst1 = v1.toList();
2303 ValueSet lst2 = v2.toList();
2304 for ( ValueSet::const_iterator anIt = lst1.begin(); anIt != lst1.end() && res; ++anIt )
2305 res = lst2.contains( *anIt );
2310 v1 = QVariant( v2.toList().contains( v1 ) );
2317 \class QtxEvalSetConst
2318 \brief Provides different standard constants.
2320 QtxEvalSetConst::QtxEvalSetConst()
2328 QtxEvalSetConst::~QtxEvalSetConst()
2333 \brief Get operations set name.
2334 \return operations set name
2336 QString QtxEvalSetConst::Name()
2342 \brief Get operations set name.
2343 \return operations set name
2345 QString QtxEvalSetConst::name() const
2351 \brief Create value from its string representation.
2353 Convert constant name to its value.
2355 \param str string representration of the constant
2356 \param val returning value
2357 \return \c true if \a str can be evaluated as custom value and \c false
2358 otherwise (parameter)
2360 bool QtxEvalSetConst::createValue( const QString& str, QVariant& val ) const
2363 if ( str == "pi" ) // PI number
2364 val = QVariant( 3.141593 );
2365 else if ( str == "exp" ) // Exponent value (e)
2366 val = QVariant( 2.718282 );
2367 else if ( str == "g" ) // Free fall acceleration (g)
2368 val = QVariant( 9.80665 );
2376 \brief Get the list of possible operations.
2377 \param list returning list of operations supported by the class (not used)
2379 void QtxEvalSetConst::operationList( QStringList& /*list*/ ) const
2384 \brief Get list of brackets.
2385 \param list returning list of brackets (not used)
2386 \param open if \c true, collect opening brackets, or closing brackets otherwise (not used)
2388 void QtxEvalSetConst::bracketsList( QStringList& /*list*/, bool /*open*/ ) const
2393 \brief Get the operation priority.
2395 Operation priority counts from 1.
2396 If the operation is impossible, this function returns value <= 0.
2398 \param op operation (not used)
2399 \param isBin \c true if the operation is binary and \c false if it is unary (not used)
2400 \return operation priority
2402 int QtxEvalSetConst::priority( const QString& /*op*/, bool /*isBin*/ ) const
2408 \brief Check operation validity.
2410 Always returns QtxEvalExpr::InvalidOperation.
2412 \param op operation (not used)
2413 \param t1 first operand type (not used)
2414 \param t2 second operand type (not used)
2415 \return error code (QtxEvalExpr::Error)
2417 QtxEvalExpr::Error QtxEvalSetConst::isValid( const QString& /*op*/,
2418 const QVariant::Type /*t1*/,
2419 const QVariant::Type /*t2*/ ) const
2421 return QtxEvalExpr::InvalidOperation;
2425 \brief Calculate the operation.
2427 Always returns QtxEvalExpr::InvalidOperation.
2429 \param op operation name (not used)
2430 \param v1 first argument (not valid for unary prefix operations) (not used)
2431 \param v2 second argument (not valid for unary postfix operations) (not used)
2432 \return error code (QtxEvalExpr::Error)
2434 QtxEvalExpr::Error QtxEvalSetConst::calculate( const QString&, QVariant&, QVariant& ) const
2436 return QtxEvalExpr::InvalidOperation;