kspread

kspread_functions_logic.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998-2002 The KSpread Team
3 www.koffice.org/kspread
4 Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License.
10
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 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22// built-in logical functions
23
24#include "functions.h"
25#include "valuecalc.h"
26#include "valueconverter.h"
27
28using namespace KSpread;
29
30// prototypes (sorted alphabetically)
31Value func_and (valVector args, ValueCalc *calc, FuncExtra *);
32Value func_false (valVector args, ValueCalc *calc, FuncExtra *);
33Value func_if (valVector args, ValueCalc *calc, FuncExtra *);
34Value func_nand (valVector args, ValueCalc *calc, FuncExtra *);
35Value func_nor (valVector args, ValueCalc *calc, FuncExtra *);
36Value func_not (valVector args, ValueCalc *calc, FuncExtra *);
37Value func_or (valVector args, ValueCalc *calc, FuncExtra *);
38Value func_true (valVector args, ValueCalc *calc, FuncExtra *);
39Value func_xor (valVector args, ValueCalc *calc, FuncExtra *);
40
41// registers all logic functions
42void RegisterLogicFunctions()
43{
44 FunctionRepository* repo = FunctionRepository::self();
45 Function *f;
46
47 f = new Function ("FALSE", func_false);
48 f->setParamCount (0);
49 repo->add (f);
50 f = new Function ("TRUE", func_true);
51 f->setParamCount (0);
52 repo->add (f);
53 f = new Function ("NOT", func_not);
54 f->setParamCount (1);
55 repo->add (f);
56 f = new Function ("AND", func_and);
57 f->setParamCount (1, -1);
58 f->setAcceptArray ();
59 repo->add (f);
60 f = new Function ("NAND", func_nand);
61 f->setParamCount (1, -1);
62 f->setAcceptArray ();
63 repo->add (f);
64 f = new Function ("NOR", func_nor);
65 f->setParamCount (1, -1);
66 f->setAcceptArray ();
67 repo->add (f);
68 f = new Function ("OR", func_or);
69 f->setParamCount (1, -1);
70 f->setAcceptArray ();
71 repo->add (f);
72 f = new Function ("XOR", func_xor);
73 f->setParamCount (1, -1);
74 f->setAcceptArray ();
75 repo->add (f);
76 f = new Function ("IF", func_if);
77 f->setParamCount (3);
78 repo->add (f);
79}
80
81// Function: FALSE
82Value func_false (valVector, ValueCalc *, FuncExtra *)
83{
84 return Value (false);
85}
86
87// Function: TRUE
88Value func_true (valVector, ValueCalc *, FuncExtra *)
89{
90 return Value (true);
91}
92
93// helper for most logical functions
94bool asBool (Value val, ValueCalc *calc)
95{
96 return calc->conv()->asBoolean (val).asBoolean ();
97}
98
99// Function: NOT
100Value func_not (valVector args, ValueCalc *calc, FuncExtra *)
101{
102 bool val = asBool (args[0], calc) ? false : true;
103 return Value (val);
104}
105
106// Function: OR
107void awOr (ValueCalc *calc, Value &res, Value value, Value)
108{
109 if (! res.asBoolean())
110 res = Value ( asBool (value, calc) );
111}
112Value func_or (valVector args, ValueCalc *calc, FuncExtra *)
113{
114 Value result(false);
115 int cnt = args.count();
116 for (int i = 0; i < cnt; ++i) {
117 calc->arrayWalk (args[i], result, awOr, 0);
118 if (result.asBoolean())
119 // if any value is true, return true
120 return result;
121 }
122 // nothing is true -> return false
123 return result;
124}
125
126// Function: NOR
127Value func_nor (valVector args, ValueCalc *calc, FuncExtra *extra)
128{
129 // OR in reverse
130 return Value(! func_or(args, calc, extra).asBoolean());
131}
132
133// Function: AND
134void awAnd (ValueCalc *calc, Value &res, Value value, Value)
135{
136 if (res.asBoolean())
137 res = Value ( asBool (value, calc) );
138}
139Value func_and (valVector args, ValueCalc *calc, FuncExtra *)
140{
141 Value result(true);
142 int cnt = args.count();
143 for (int i = 0; i < cnt; ++i) {
144 calc->arrayWalk (args[i], result, awAnd, 0);
145 if (! result.asBoolean())
146 // if any value is false, return false
147 return result;
148 }
149 // nothing is false -> return true
150 return result;
151}
152
153// Function: NAND
154Value func_nand (valVector args, ValueCalc *calc, FuncExtra *extra)
155{
156 // AND in reverse
157 return Value(! func_and(args, calc, extra).asBoolean());
158}
159
160// Function: XOR
161void awXor (ValueCalc *calc, Value &count, Value value, Value)
162{
163 if (asBool (value, calc))
164 count = Value( count.asInteger() + 1 );
165}
166Value func_xor (valVector args, ValueCalc *calc, FuncExtra *)
167{
168 // exclusive OR - exactly one value must be true
169 int cnt = args.count();
170 Value count(0);
171 for (int i = 0; i < cnt; ++i)
172 calc->arrayWalk (args[i], count, awXor, 0);
173 return Value (count.asInteger() == 1);
174}
175
176// Function: IF
177Value func_if (valVector args, ValueCalc *calc, FuncExtra *)
178{
179 if (asBool (args[0], calc))
180 return args[1];
181 else
182 return args[2];
183}
The ValueCalc class is used to perform all sorts of calculations.
Definition valuecalc.h:69
void arrayWalk(const Value &range, Value &res, arrayWalkFunc func, Value param)
array/range walking
Provides a wrapper for cell value.
long asInteger() const
Returns the integer value of this value.
bool asBoolean() const
Returns the boolean value of this value.
The KSpread namespace.
Definition commands.h:39