Library of Assembled Shared Sources
tri_bool.cpp
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#include "lass_common.h"
46#include "tri_bool.h"
47#include "../util/bit_manip.h"
48
49namespace lass
50{
51namespace num
52{
53
54// --- public --------------------------------------------------------------------------------------
55
56/** Construct a TriBool, with as default state the "unknown".
57 */
58TriBool::TriBool(State iState):
59 state_(iState)
60{
61}
62
63
64
65/** Converts a C++ bool to a TriBool.
66 */
67TriBool::TriBool(bool iBool):
68 state_(iBool ? sTrue : sFalse)
69{
70}
71
72
73
74/** return state
75 */
76TriBool::State TriBool::state() const
77{
78 return state_;
79}
80
81
82
83/** access state
84 */
85TriBool::State& TriBool::state()
86{
87 return state_;
88}
89
90
91
92/** Negation: true becomes false, false becomes true, unknown remains unknown.
93 * <table>
94 * <tr><td>!</td> <td>TRUE</td> <td>FALSE</td> <td>UNKNOWN</td></tr>
95 * <tr><td></td> <td>false</td> <td>true</td> <td>unknown</td></tr>
96 * </table>
97 */
98TriBool TriBool::operator!() const
99{
100 if (state_ == sUnknown)
101 {
102 return sUnknown;
103 }
104 return state_ == sTrue ? sFalse : sTrue;
105}
106
107
108
109/** Convert TriBool to a bool in a boolean context.
110 *
111 * Will evaluate true if a boolean context only when the TriBool is definitely true. By this, you
112 * can use TriBools in if-statements:
113 *
114 * @code
115 * TriBool a;
116 * if (a)
117 * {
118 * LASS_ASSERT(a.isTrue());
119 * }
120 * @endcode
121 *
122 * Because @c !a makes @c true @c false, @c false @c true and @c unknown @c unknown, the following
123 * also works:
124 *
125 * @code
126 * TriBool a;
127 * if (!a)
128 * {
129 * LASS_ASSERT(a.isFalse());
130 * }
131 */
132TriBool::operator bool() const
133{
134 return state_ == sTrue;
135}
136
137
138
139/** return true if state is @c true, return false otherwise.
140 */
141bool TriBool::isTrue() const
142{
143 return state_ == sTrue;
144}
145
146
147
148/** return true if state is @c false, return false otherwise.
149 */
150bool TriBool::isFalse() const
151{
152 return state_ == sFalse;
153}
154
155
156
157/** return true if state is @c unknown, return false otherwise.
158 */
159bool TriBool::isUnknown() const
160{
161 return state_ == sUnknown;
162}
163
164
165
166// --- protected -----------------------------------------------------------------------------------
167
168
169
170// --- private -------------------------------------------------------------------------------------
171
172
173
174// --- free ----------------------------------------------------------------------------------------
175
176/** Evaluates if two TriBool's are equal, if at least one is unknown then we don't know the result.
177 * @relates TriBool
178 * <table>
179 * <tr><td>==></td> <td>TRUE</td> <td>FALSE</td> <td>UNKNOWN</td></tr>
180 * <tr><td>TRUE</td> <td>true</td> <td>false</td> <td>unknown</td></tr>
181 * <tr><td>FALSE</td> <td>false</td> <td>true</td> <td>unknown</td></tr>
182 * <tr><td>UNKNOWN</td> <td>unknown</td> <td>unknown</td> <td>unknown</td></tr>
183 * </table>
184 *
185 * @warning don't expect @c unknown @c == @c unknown yields @c true! Use @c unknown.isUnknown()
186 * instead.
187 */
188TriBool operator==(TriBool iA, TriBool iB)
189{
190 if (iA.isUnknown() || iB.isUnknown())
191 {
192 return TriBool::sUnknown;
193 }
194 return iA.state() == iB.state();
195}
196
197
198
199/** Evaluates if two TriBool's differ, if at least one is unknown then we don't know the result.
200 * @relates TriBool
201 * <table>
202 * <tr><td>!=</td> <td>TRUE</td> <td>FALSE</td> <td>UNKNOWN</td></tr>
203 * <tr><td>TRUE</td> <td>false</td> <td>true</td> <td>unknown</td></tr>
204 * <tr><td>FALSE</td> <td>true</td> <td>false</td> <td>unknown</td></tr>
205 * <tr><td>UNKNOWN</td> <td>unknown</td> <td>unknown</td> <td>unknown</td></tr>
206 * </table>
207 */
208TriBool operator!=(TriBool iA, TriBool iB)
209{
210 return !(iA == iB);
211}
212
213
214
215/** Evaluates to true if both are true, unknown if at least one is unknown, false otherwise.
216 * @relates TriBool
217 * <table>
218 * <tr><td>&amp;&amp;</td> <td>TRUE</td> <td>FALSE</td> <td>UNKNOWN</td></tr>
219 * <tr><td>TRUE</td> <td>true</td> <td>false</td> <td>unknown</td></tr>
220 * <tr><td>FALSE</td> <td>false</td> <td>false</td> <td>@b false</td></tr>
221 * <tr><td>UNKNOWN</td> <td>unknown</td> <td>@b false</td> <td>unknown</td></tr>
222 * </table>
223 */
224TriBool operator&&(TriBool iA, TriBool iB)
225{
226 if (iA.isFalse() || iB.isFalse())
227 {
228 return TriBool::sFalse;
229 }
230 if (iA.isTrue() && iB.isTrue())
231 {
232 return TriBool::sTrue;
233 }
234 return TriBool::sUnknown;
235}
236
237
238
239/** Evaluates to true if at least one is true, false if both are false, unknown otherwise.
240 * @relates TriBool
241 * <table>
242 * <tr><td>||</td> <td>TRUE</td> <td>false</td> <td>unknown</td></tr>
243 * <tr><td>TRUE</td> <td>true</td> <td>true</td> <td>@b true</td></tr>
244 * <tr><td>FALSE</td> <td>true</td> <td>false</td> <td>unknown</td></tr>
245 * <tr><td>UNKNOWN</td> <td>@b true</td> <td>unknown</td> <td>unknown</td></tr>
246 * </table>
247 */
248TriBool operator||(TriBool iA, TriBool iB)
249{
250 if (iA.isTrue() || iB.isTrue())
251 {
252 return TriBool::sTrue;
253 }
254 if (iA.isFalse() && iB.isFalse())
255 {
256 return TriBool::sFalse;
257 }
258 return TriBool::sUnknown;
259}
260
261
262
263/** @relates TriBool
264 */
265std::ostream& operator<<(std::ostream& ioS, TriBool iB)
266{
267 switch (iB.state())
268 {
269 case TriBool::sTrue:
270 ioS << true;
271 break;
272
273 case TriBool::sFalse:
274 ioS << false;
275 break;
276
277 default:
278 LASS_ASSERT(iB.state() == TriBool::sUnknown);
279 ioS << (ioS.flags() & std::ios::boolalpha ? "unknown" : "?");
280 break;
281 }
282
283 return ioS;
284}
285
286
287
288}
289
290}
291
292// EOF
numeric types and traits.
Definition basic_ops.h:70
Library for Assembled Shared Sources.
Definition config.h:53