diff options
Diffstat (limited to 'kexi/kexiutils/tristate.h')
-rw-r--r-- | kexi/kexiutils/tristate.h | 238 |
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 |