kspread

kspread_functions_logic.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004    Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 // built-in logical functions
00023 
00024 #include "functions.h"
00025 #include "valuecalc.h"
00026 #include "valueconverter.h"
00027 
00028 using namespace KSpread;
00029 
00030 // prototypes (sorted alphabetically)
00031 Value func_and (valVector args, ValueCalc *calc, FuncExtra *);
00032 Value func_false (valVector args, ValueCalc *calc, FuncExtra *);
00033 Value func_if (valVector args, ValueCalc *calc, FuncExtra *);
00034 Value func_nand (valVector args, ValueCalc *calc, FuncExtra *);
00035 Value func_nor (valVector args, ValueCalc *calc, FuncExtra *);
00036 Value func_not (valVector args, ValueCalc *calc, FuncExtra *);
00037 Value func_or (valVector args, ValueCalc *calc, FuncExtra *);
00038 Value func_true (valVector args, ValueCalc *calc, FuncExtra *);
00039 Value func_xor (valVector args, ValueCalc *calc, FuncExtra *);
00040 
00041 // registers all logic functions
00042 void RegisterLogicFunctions()
00043 {
00044   FunctionRepository* repo = FunctionRepository::self();
00045   Function *f;
00046 
00047   f = new Function ("FALSE", func_false);
00048   f->setParamCount (0);
00049   repo->add (f);
00050   f = new Function ("TRUE", func_true);
00051   f->setParamCount (0);
00052   repo->add (f);
00053   f = new Function ("NOT", func_not);
00054   f->setParamCount (1);
00055   repo->add (f);
00056   f = new Function ("AND", func_and);
00057   f->setParamCount (1, -1);
00058   f->setAcceptArray ();
00059   repo->add (f);
00060   f = new Function ("NAND", func_nand);
00061   f->setParamCount (1, -1);
00062   f->setAcceptArray ();
00063   repo->add (f);
00064   f = new Function ("NOR", func_nor);
00065   f->setParamCount (1, -1);
00066   f->setAcceptArray ();
00067   repo->add (f);
00068   f = new Function ("OR", func_or);
00069   f->setParamCount (1, -1);
00070   f->setAcceptArray ();
00071   repo->add (f);
00072   f = new Function ("XOR", func_xor);
00073   f->setParamCount (1, -1);
00074   f->setAcceptArray ();
00075   repo->add (f);
00076   f = new Function ("IF", func_if);
00077   f->setParamCount (3);
00078   repo->add (f);
00079 }
00080 
00081 // Function: FALSE
00082 Value func_false (valVector, ValueCalc *, FuncExtra *)
00083 {
00084   return Value (false);
00085 }
00086 
00087 // Function: TRUE
00088 Value func_true (valVector, ValueCalc *, FuncExtra *)
00089 {
00090   return Value (true);
00091 }
00092 
00093 // helper for most logical functions
00094 bool asBool (Value val, ValueCalc *calc)
00095 {
00096   return calc->conv()->asBoolean (val).asBoolean ();
00097 }
00098 
00099 // Function: NOT
00100 Value func_not (valVector args, ValueCalc *calc, FuncExtra *)
00101 {
00102   bool val = asBool (args[0], calc) ? false : true;
00103   return Value (val);
00104 }
00105 
00106 // Function: OR
00107 void awOr (ValueCalc *calc, Value &res, Value value, Value)
00108 {
00109   if (! res.asBoolean())
00110     res = Value ( asBool (value, calc) );
00111 }
00112 Value func_or (valVector args, ValueCalc *calc, FuncExtra *)
00113 {
00114   Value result(false);
00115   int cnt = args.count();
00116   for (int i = 0; i < cnt; ++i) {
00117     calc->arrayWalk (args[i], result, awOr, 0);
00118     if (result.asBoolean())
00119       // if any value is true, return true
00120       return result;
00121   }
00122   // nothing is true -> return false
00123   return result;
00124 }
00125 
00126 // Function: NOR
00127 Value func_nor (valVector args, ValueCalc *calc, FuncExtra *extra)
00128 {
00129   // OR in reverse
00130   return Value(! func_or(args, calc, extra).asBoolean());
00131 }
00132 
00133 // Function: AND
00134 void awAnd (ValueCalc *calc, Value &res, Value value, Value)
00135 {
00136   if (res.asBoolean())
00137     res = Value ( asBool (value, calc) );
00138 }
00139 Value func_and (valVector args, ValueCalc *calc, FuncExtra *)
00140 {
00141   Value result(true);
00142   int cnt = args.count();
00143   for (int i = 0; i < cnt; ++i) {
00144     calc->arrayWalk (args[i], result, awAnd, 0);
00145     if (! result.asBoolean())
00146       // if any value is false, return false
00147       return result;
00148   }
00149   // nothing is false -> return true
00150   return result;
00151 }
00152 
00153 // Function: NAND
00154 Value func_nand (valVector args, ValueCalc *calc, FuncExtra *extra)
00155 {
00156   // AND in reverse
00157   return Value(! func_and(args, calc, extra).asBoolean());
00158 }
00159 
00160 // Function: XOR
00161 void awXor (ValueCalc *calc, Value &count, Value value, Value)
00162 {
00163   if (asBool (value, calc))
00164     count = Value( count.asInteger() + 1 );
00165 }
00166 Value func_xor (valVector args, ValueCalc *calc, FuncExtra *)
00167 {
00168   // exclusive OR - exactly one value must be true
00169   int cnt = args.count();
00170   Value count(0);
00171   for (int i = 0; i < cnt; ++i)
00172     calc->arrayWalk (args[i], count, awXor, 0);
00173   return Value (count.asInteger() == 1);
00174 }
00175 
00176 // Function: IF
00177 Value func_if (valVector args, ValueCalc *calc, FuncExtra *)
00178 {
00179   if (asBool (args[0], calc))
00180     return args[1];
00181   else
00182     return args[2];
00183 }
KDE Home | KDE Accessibility Home | Description of Access Keys