summaryrefslogtreecommitdiffstats
path: root/kexi/kexiutils/tristate.h
diff options
context:
space:
mode:
Diffstat (limited to 'kexi/kexiutils/tristate.h')
-rw-r--r--kexi/kexiutils/tristate.h238
1 files changed, 238 insertions, 0 deletions
diff --git a/kexi/kexiutils/tristate.h b/kexi/kexiutils/tristate.h
new file mode 100644
index 00000000..a3de22bb
--- /dev/null
+++ b/kexi/kexiutils/tristate.h
@@ -0,0 +1,238 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004, 2006 Jaroslaw Staniek <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _TRISTATE_TYPE_H_
+#define _TRISTATE_TYPE_H_
+
+#include <qstring.h>
+
+/**
+ * \e cancelled value, in most cases usable if there is a need for returning
+ * \e cancelled value explicitly. Example use:
+ * \code
+ * tristate myFunctionThatCanBeCancelled() {
+ * doSomething();
+ * if (userCancelledOperation())
+ * return cancelled; //neither success or failure is returned here
+ * return operationSucceeded(); //return success or failure
+ * }
+ * \endcode
+ * Even though ~ operator of tristate class can be used, it is also possible to test:
+ * \code
+ * if (cancelled == myFunctionThatCanBeCancelled()) { .... }
+ * \endcode
+ */
+static const char cancelled = 2;
+
+/**
+ * Convenience name, the same as cancelled value.
+ */
+static const char dontKnow = cancelled;
+
+/**
+ * 3-state logical type with three values: \e true, \e false and \e cancelled and convenient operators.
+ *
+ * \e cancelled state can be also called \e dontKnow, it behaves as \e null in SQL.
+ * A main goal of this class is to improve readibility when there's a need
+ * for storing third, \e cancelled, state, especially in case C++ exceptions are not in use.
+ * With it, developer can forget about declaring a specific enum type
+ * having just three values: \e true, \e false, \e cancelled.
+ *
+ * Objects of this class can be used with similar convenience as standard bool type:
+ * - use as return value when 'cancelled'
+ * \code
+ * tristate doSomething();
+ * \endcode
+ * - convert from bool (1) or to bool (2)
+ * \code
+ * tristate t = true; //(1)
+ * setVisible(t); //(2)
+ * \endcode
+ * - clear comparisons
+ * \code
+ * tristate t = doSomething();
+ * if (t) doSomethingIfTrue();
+ * if (!t) doSomethingIfFalse();
+ * if (~t) doSomethingIfCancelled();
+ * \endcode
+ *
+ * "! ~" can be used as "not cancelled".
+ *
+ * With tristate class, developer can also forget about
+ * it's additional meaning and treat it just as a bool, if the third state
+ * is irrelevant to the current situation.
+ *
+ * Other use for tristate class could be to allow cancellation within
+ * a callback function or a Qt slot. Example:
+ * \code
+ * public slots:
+ * void validateData(tristate& result);
+ * \endcode
+ * Having the single parameter, signals and slots have still simple look.
+ * Developers can alter their code (by replacing 'bool& result' with 'tristate& result')
+ * in case when a possibility of canceling of, say, data provessing needs to be implemented.
+ * Let's say \e validateData() function uses a QDialog to get some validation from a user.
+ * While QDialog::Rejected is returned after cancellation of the validation process,
+ * the information about cancellation needs to be transferred up to a higher level of the program.
+ * Storing values of type QDialog::DialogCode there could be found as unreadable, and
+ * casting these to int is not typesafe. With tristate class it's easier to make it obvious that
+ * cancellation should be taken into account.
+ *
+ * @author Jaroslaw Staniek
+ */
+class tristate
+{
+public:
+ /**
+ * Default constructor, object has \e cancelled value set.
+ */
+ tristate()
+ : m_value(Cancelled)
+ {
+ }
+
+ /**
+ * Constructor accepting a boolean value.
+ */
+ tristate(bool boolValue)
+ : m_value(boolValue ? True : False)
+ {
+ }
+
+ /**
+ * Constructor accepting a char value.
+ * It is converted in the following way:
+ * - 2 -> cancelled
+ * - 1 -> true
+ * - other -> false
+ */
+ tristate(char c)
+ : m_value(c==cancelled ? tristate::Cancelled : (c==1 ? True : False))
+ {
+ }
+
+ /** Constructor accepting an integer value.
+ * It is converted in the following way:
+ * - 2 -> cancelled
+ * - 1 -> true
+ * - other -> false
+ */
+ tristate(int intValue)
+ : m_value(intValue==(int)cancelled ? tristate::Cancelled : (intValue==1 ? True : False))
+ {
+ }
+
+ /**
+ * Casting to bool type with negation: true is only returned
+ * if the original tristate value is equal to false.
+ */
+ bool operator!() const { return m_value==False; }
+
+ /**
+ * Special casting to bool type: true is only returned
+ * if the original tristate value is equal to \e cancelled.
+ */
+ bool operator~() const { return m_value==Cancelled; }
+
+ tristate& operator=(const tristate& tsValue) { m_value = tsValue.m_value; return *this; }
+
+ friend inline bool operator==(bool boolValue, tristate tsValue);
+
+ friend inline bool operator==(tristate tsValue, bool boolValue);
+
+ friend inline bool operator!=(bool boolValue, tristate tsValue);
+
+ friend inline bool operator!=(tristate tsValue, bool boolValue);
+
+ /**
+ * \return text representation of the value: "true", "false" or "cancelled".
+ */
+ QString toString() const {
+ if (m_value==False)
+ return QString::fromLatin1("false");
+ return m_value==True ? QString::fromLatin1("true") : QString::fromLatin1("cancelled");
+ }
+
+private:
+ /**
+ * @internal
+ * States used internally.
+ */
+ enum Value {
+ False = 0,
+ True = 1,
+ Cancelled = 2
+ };
+
+ /**
+ * @internal
+ */
+ Value m_value;
+};
+
+/**
+ * Inequality operator comparing a bool value @p boolValue and a tristate value @p tsValue.
+ *
+ * @return false if both @p boolValue and @p tsValue are true
+ * or if both @p boolValue and @p tsValue are false.
+ * Else, returns true.
+*/
+inline bool operator!=(bool boolValue, tristate tsValue)
+{
+ return !( (tsValue.m_value==tristate::True && boolValue)
+ || (tsValue.m_value==tristate::False && !boolValue) );
+}
+
+/**
+ * Inequality operator comparing a tristate value @p tsValue and a bool value @p boolValue.
+ * @see bool operator!=(bool boolValue, tristate tsValue)
+*/
+inline bool operator!=(tristate tsValue, bool boolValue)
+{
+ return !( (tsValue.m_value==tristate::True && boolValue)
+ || (tsValue.m_value==tristate::False && !boolValue) );
+}
+
+/**
+ * Equality operator comparing a tristate value @p tsValue and a bool value @p boolValue.
+ * \return true if both
+ * - both @p tsValue value and @p boolValue are true, or
+ * - both @p tsValue value and @p boolValue are false
+ * If the tristate value has value of cancelled, false is returned.
+ */
+inline bool operator==(tristate tsValue, bool boolValue)
+{
+ return (tsValue.m_value==tristate::True && boolValue)
+ || (tsValue.m_value==tristate::False && !boolValue);
+}
+
+/**
+ * Equality operator comparing a bool value @p boolValue and a tristate value @p tsValue.
+ * \return true if both
+ * - both @p tsValue value and @p boolValue are true, or
+ * - both @p tsValue value and @p boolValue are false
+ * If the tristate value has value of cancelled, false is returned.
+ */
+inline bool operator==(bool boolValue, tristate tsValue)
+{
+ return (tsValue.m_value==tristate::True && boolValue)
+ || (tsValue.m_value==tristate::False && !boolValue);
+}
+
+#endif