/* This file is part of the KDE project Copyright (C) 2004, 2006 Jaroslaw Staniek 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 /** * \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 TQt 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 TQDialog to get some validation from a user. * While TQDialog::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 TQDialog::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". */ TQString toString() const { if (m_value==False) return TQString::fromLatin1("false"); return m_value==True ? TQString::fromLatin1("true") : TQString::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