os/ossrv/ossrv_pub/boost_apis/boost/logic/tribool.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Three-state boolean logic library
sl@0
     2
sl@0
     3
// Copyright Douglas Gregor 2002-2004. Use, modification and
sl@0
     4
// distribution is subject to the Boost Software License, Version
sl@0
     5
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     6
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     7
sl@0
     8
sl@0
     9
// For more information, see http://www.boost.org
sl@0
    10
#ifndef BOOST_LOGIC_TRIBOOL_HPP
sl@0
    11
#define BOOST_LOGIC_TRIBOOL_HPP
sl@0
    12
sl@0
    13
#include <boost/logic/tribool_fwd.hpp>
sl@0
    14
#include <boost/config.hpp>
sl@0
    15
#include <boost/detail/workaround.hpp>
sl@0
    16
sl@0
    17
#if BOOST_WORKAROUND(_MSC_VER, >= 1200)
sl@0
    18
#  pragma once
sl@0
    19
#endif
sl@0
    20
sl@0
    21
namespace boost { namespace logic {
sl@0
    22
sl@0
    23
/// INTERNAL ONLY
sl@0
    24
namespace detail {
sl@0
    25
/**
sl@0
    26
 * INTERNAL ONLY
sl@0
    27
 *
sl@0
    28
 * \brief A type used only to uniquely identify the 'indeterminate'
sl@0
    29
 * function/keyword.
sl@0
    30
 */
sl@0
    31
struct indeterminate_t
sl@0
    32
{
sl@0
    33
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0600)
sl@0
    34
  char dummy_; // BCB would use 8 bytes by default
sl@0
    35
#endif
sl@0
    36
};
sl@0
    37
sl@0
    38
} // end namespace detail
sl@0
    39
sl@0
    40
/**
sl@0
    41
 * INTERNAL ONLY
sl@0
    42
 * The type of the 'indeterminate' keyword. This has the same type as the
sl@0
    43
 * function 'indeterminate' so that we can recognize when the keyword is
sl@0
    44
 * used.
sl@0
    45
 */
sl@0
    46
typedef bool (*indeterminate_keyword_t)(tribool, detail::indeterminate_t);
sl@0
    47
sl@0
    48
/**
sl@0
    49
 * \brief Keyword and test function for the indeterminate tribool value
sl@0
    50
 *
sl@0
    51
 * The \c indeterminate function has a dual role. It's first role is
sl@0
    52
 * as a unary function that tells whether the tribool value is in the
sl@0
    53
 * "indeterminate" state. It's second role is as a keyword
sl@0
    54
 * representing the indeterminate (just like "true" and "false"
sl@0
    55
 * represent the true and false states). If you do not like the name
sl@0
    56
 * "indeterminate", and would prefer to use a different name, see the
sl@0
    57
 * macro \c BOOST_TRIBOOL_THIRD_STATE.
sl@0
    58
 *
sl@0
    59
 * \returns <tt>x.value == tribool::indeterminate_value</tt>
sl@0
    60
 * \throws nothrow
sl@0
    61
 */
sl@0
    62
inline bool
sl@0
    63
indeterminate(tribool x,
sl@0
    64
              detail::indeterminate_t dummy = detail::indeterminate_t());
sl@0
    65
sl@0
    66
/**
sl@0
    67
 * \brief A 3-state boolean type.
sl@0
    68
 *
sl@0
    69
 * 3-state boolean values are either true, false, or
sl@0
    70
 * indeterminate.
sl@0
    71
 */
sl@0
    72
class tribool
sl@0
    73
{
sl@0
    74
private:
sl@0
    75
  /// INTERNAL ONLY
sl@0
    76
  struct dummy {
sl@0
    77
    void nonnull() {};
sl@0
    78
  };
sl@0
    79
sl@0
    80
  typedef void (dummy::*safe_bool)();
sl@0
    81
sl@0
    82
public:
sl@0
    83
  /**
sl@0
    84
   * Construct a new 3-state boolean value with the value 'false'.
sl@0
    85
   *
sl@0
    86
   * \throws nothrow
sl@0
    87
   */
sl@0
    88
  tribool() : value(false_value) {}
sl@0
    89
sl@0
    90
  /**
sl@0
    91
   * Construct a new 3-state boolean value with the given boolean
sl@0
    92
   * value, which may be \c true or \c false.
sl@0
    93
   *
sl@0
    94
   * \throws nothrow
sl@0
    95
   */
sl@0
    96
  tribool(bool value) : value(value? true_value : false_value) {}
sl@0
    97
sl@0
    98
  /**
sl@0
    99
   * Construct a new 3-state boolean value with an indeterminate value.
sl@0
   100
   *
sl@0
   101
   * \throws nothrow
sl@0
   102
   */
sl@0
   103
  tribool(indeterminate_keyword_t) : value(indeterminate_value) {}
sl@0
   104
sl@0
   105
  /**
sl@0
   106
   * Use a 3-state boolean in a boolean context. Will evaluate true in a
sl@0
   107
   * boolean context only when the 3-state boolean is definitely true.
sl@0
   108
   *
sl@0
   109
   * \returns true if the 3-state boolean is true, false otherwise
sl@0
   110
   * \throws nothrow
sl@0
   111
   */
sl@0
   112
  operator safe_bool() const
sl@0
   113
  {
sl@0
   114
    return value == true_value? &dummy::nonnull : 0;
sl@0
   115
  }
sl@0
   116
sl@0
   117
  /**
sl@0
   118
   * The actual stored value in this 3-state boolean, which may be false, true,
sl@0
   119
   * or indeterminate.
sl@0
   120
   */
sl@0
   121
  enum value_t { false_value, true_value, indeterminate_value } value;
sl@0
   122
};
sl@0
   123
sl@0
   124
// Check if the given tribool has an indeterminate value. Also doubles as a
sl@0
   125
// keyword for the 'indeterminate' value
sl@0
   126
inline bool indeterminate(tribool x, detail::indeterminate_t)
sl@0
   127
{
sl@0
   128
  return x.value == tribool::indeterminate_value;
sl@0
   129
}
sl@0
   130
sl@0
   131
/** @defgroup logical Logical operations
sl@0
   132
 */
sl@0
   133
//@{
sl@0
   134
/**
sl@0
   135
 * \brief Computes the logical negation of a tribool
sl@0
   136
 *
sl@0
   137
 * \returns the logical negation of the tribool, according to the
sl@0
   138
 * table:
sl@0
   139
 *  <table border=1>
sl@0
   140
 *    <tr>
sl@0
   141
 *      <th><center><code>!</code></center></th>
sl@0
   142
 *      <th/>
sl@0
   143
 *    </tr>
sl@0
   144
 *    <tr>
sl@0
   145
 *      <th><center>false</center></th>
sl@0
   146
 *      <td><center>true</center></td>
sl@0
   147
 *    </tr>
sl@0
   148
 *    <tr>
sl@0
   149
 *      <th><center>true</center></th>
sl@0
   150
 *      <td><center>false</center></td>
sl@0
   151
 *    </tr>
sl@0
   152
 *    <tr>
sl@0
   153
 *      <th><center>indeterminate</center></th>
sl@0
   154
 *      <td><center>indeterminate</center></td>
sl@0
   155
 *    </tr>
sl@0
   156
 *  </table>
sl@0
   157
 * \throws nothrow
sl@0
   158
 */
sl@0
   159
inline tribool operator!(tribool x)
sl@0
   160
{
sl@0
   161
  return x.value == tribool::false_value? tribool(true)
sl@0
   162
        :x.value == tribool::true_value? tribool(false)
sl@0
   163
        :tribool(indeterminate);
sl@0
   164
}
sl@0
   165
sl@0
   166
/**
sl@0
   167
 * \brief Computes the logical conjuction of two tribools
sl@0
   168
 *
sl@0
   169
 * \returns the result of logically ANDing the two tribool values,
sl@0
   170
 * according to the following table:
sl@0
   171
 *       <table border=1>
sl@0
   172
 *           <tr>
sl@0
   173
 *             <th><center><code>&amp;&amp;</code></center></th>
sl@0
   174
 *             <th><center>false</center></th>
sl@0
   175
 *             <th><center>true</center></th>
sl@0
   176
 *             <th><center>indeterminate</center></th>
sl@0
   177
 *           </tr>
sl@0
   178
 *           <tr>
sl@0
   179
 *             <th><center>false</center></th>
sl@0
   180
 *             <td><center>false</center></td>
sl@0
   181
 *             <td><center>false</center></td>
sl@0
   182
 *             <td><center>false</center></td>
sl@0
   183
 *           </tr>
sl@0
   184
 *           <tr>
sl@0
   185
 *             <th><center>true</center></th>
sl@0
   186
 *             <td><center>false</center></td>
sl@0
   187
 *             <td><center>true</center></td>
sl@0
   188
 *             <td><center>indeterminate</center></td>
sl@0
   189
 *           </tr>
sl@0
   190
 *           <tr>
sl@0
   191
 *             <th><center>indeterminate</center></th>
sl@0
   192
 *             <td><center>false</center></td>
sl@0
   193
 *             <td><center>indeterminate</center></td>
sl@0
   194
 *             <td><center>indeterminate</center></td>
sl@0
   195
 *           </tr>
sl@0
   196
 *       </table>
sl@0
   197
 * \throws nothrow
sl@0
   198
 */
sl@0
   199
inline tribool operator&&(tribool x, tribool y)
sl@0
   200
{
sl@0
   201
  if (static_cast<bool>(!x) || static_cast<bool>(!y))
sl@0
   202
    return false;
sl@0
   203
  else if (static_cast<bool>(x) && static_cast<bool>(y))
sl@0
   204
    return true;
sl@0
   205
  else
sl@0
   206
    return indeterminate;
sl@0
   207
}
sl@0
   208
sl@0
   209
/**
sl@0
   210
 * \overload
sl@0
   211
 */
sl@0
   212
inline tribool operator&&(tribool x, bool y)
sl@0
   213
{ return y? x : tribool(false); }
sl@0
   214
sl@0
   215
/**
sl@0
   216
 * \overload
sl@0
   217
 */
sl@0
   218
inline tribool operator&&(bool x, tribool y)
sl@0
   219
{ return x? y : tribool(false); }
sl@0
   220
sl@0
   221
/**
sl@0
   222
 * \overload
sl@0
   223
 */
sl@0
   224
inline tribool operator&&(indeterminate_keyword_t, tribool x)
sl@0
   225
{ return !x? tribool(false) : tribool(indeterminate); }
sl@0
   226
sl@0
   227
/**
sl@0
   228
 * \overload
sl@0
   229
 */
sl@0
   230
inline tribool operator&&(tribool x, indeterminate_keyword_t)
sl@0
   231
{ return !x? tribool(false) : tribool(indeterminate); }
sl@0
   232
sl@0
   233
/**
sl@0
   234
 * \brief Computes the logical disjunction of two tribools
sl@0
   235
 *
sl@0
   236
 * \returns the result of logically ORing the two tribool values,
sl@0
   237
 * according to the following table:
sl@0
   238
 *       <table border=1>
sl@0
   239
 *           <tr>
sl@0
   240
 *             <th><center><code>||</code></center></th>
sl@0
   241
 *             <th><center>false</center></th>
sl@0
   242
 *             <th><center>true</center></th>
sl@0
   243
 *             <th><center>indeterminate</center></th>
sl@0
   244
 *           </tr>
sl@0
   245
 *           <tr>
sl@0
   246
 *             <th><center>false</center></th>
sl@0
   247
 *             <td><center>false</center></td>
sl@0
   248
 *             <td><center>true</center></td>
sl@0
   249
 *             <td><center>indeterminate</center></td>
sl@0
   250
 *           </tr>
sl@0
   251
 *           <tr>
sl@0
   252
 *             <th><center>true</center></th>
sl@0
   253
 *             <td><center>true</center></td>
sl@0
   254
 *             <td><center>true</center></td>
sl@0
   255
 *             <td><center>true</center></td>
sl@0
   256
 *           </tr>
sl@0
   257
 *           <tr>
sl@0
   258
 *             <th><center>indeterminate</center></th>
sl@0
   259
 *             <td><center>indeterminate</center></td>
sl@0
   260
 *             <td><center>true</center></td>
sl@0
   261
 *             <td><center>indeterminate</center></td>
sl@0
   262
 *           </tr>
sl@0
   263
 *       </table>
sl@0
   264
 *  \throws nothrow
sl@0
   265
 */
sl@0
   266
inline tribool operator||(tribool x, tribool y)
sl@0
   267
{
sl@0
   268
  if (static_cast<bool>(!x) && static_cast<bool>(!y))
sl@0
   269
    return false;
sl@0
   270
  else if (static_cast<bool>(x) || static_cast<bool>(y))
sl@0
   271
    return true;
sl@0
   272
  else
sl@0
   273
    return indeterminate;
sl@0
   274
}
sl@0
   275
sl@0
   276
/**
sl@0
   277
 * \overload
sl@0
   278
 */
sl@0
   279
inline tribool operator||(tribool x, bool y)
sl@0
   280
{ return y? tribool(true) : x; }
sl@0
   281
sl@0
   282
/**
sl@0
   283
 * \overload
sl@0
   284
 */
sl@0
   285
inline tribool operator||(bool x, tribool y)
sl@0
   286
{ return x? tribool(true) : y; }
sl@0
   287
sl@0
   288
/**
sl@0
   289
 * \overload
sl@0
   290
 */
sl@0
   291
inline tribool operator||(indeterminate_keyword_t, tribool x)
sl@0
   292
{ return x? tribool(true) : tribool(indeterminate); }
sl@0
   293
sl@0
   294
/**
sl@0
   295
 * \overload
sl@0
   296
 */
sl@0
   297
inline tribool operator||(tribool x, indeterminate_keyword_t)
sl@0
   298
{ return x? tribool(true) : tribool(indeterminate); }
sl@0
   299
//@}
sl@0
   300
sl@0
   301
/**
sl@0
   302
 * \brief Compare tribools for equality
sl@0
   303
 *
sl@0
   304
 * \returns the result of comparing two tribool values, according to
sl@0
   305
 * the following table:
sl@0
   306
 *       <table border=1>
sl@0
   307
 *          <tr>
sl@0
   308
 *            <th><center><code>==</code></center></th>
sl@0
   309
 *            <th><center>false</center></th>
sl@0
   310
 *            <th><center>true</center></th>
sl@0
   311
 *            <th><center>indeterminate</center></th>
sl@0
   312
 *          </tr>
sl@0
   313
 *          <tr>
sl@0
   314
 *            <th><center>false</center></th>
sl@0
   315
 *            <td><center>true</center></td>
sl@0
   316
 *            <td><center>false</center></td>
sl@0
   317
 *            <td><center>indeterminate</center></td>
sl@0
   318
 *          </tr>
sl@0
   319
 *          <tr>
sl@0
   320
 *            <th><center>true</center></th>
sl@0
   321
 *            <td><center>false</center></td>
sl@0
   322
 *            <td><center>true</center></td>
sl@0
   323
 *            <td><center>indeterminate</center></td>
sl@0
   324
 *          </tr>
sl@0
   325
 *          <tr>
sl@0
   326
 *            <th><center>indeterminate</center></th>
sl@0
   327
 *            <td><center>indeterminate</center></td>
sl@0
   328
 *            <td><center>indeterminate</center></td>
sl@0
   329
 *            <td><center>indeterminate</center></td>
sl@0
   330
 *          </tr>
sl@0
   331
 *      </table>
sl@0
   332
 * \throws nothrow
sl@0
   333
 */
sl@0
   334
inline tribool operator==(tribool x, tribool y)
sl@0
   335
{
sl@0
   336
  if (indeterminate(x) || indeterminate(y))
sl@0
   337
    return indeterminate;
sl@0
   338
  else
sl@0
   339
    return x && y || !x && !y;
sl@0
   340
}
sl@0
   341
sl@0
   342
/**
sl@0
   343
 * \overload
sl@0
   344
 */
sl@0
   345
inline tribool operator==(tribool x, bool y) { return x == tribool(y); }
sl@0
   346
sl@0
   347
/**
sl@0
   348
 * \overload
sl@0
   349
 */
sl@0
   350
inline tribool operator==(bool x, tribool y) { return tribool(x) == y; }
sl@0
   351
sl@0
   352
/**
sl@0
   353
 * \overload
sl@0
   354
 */
sl@0
   355
inline tribool operator==(indeterminate_keyword_t, tribool x)
sl@0
   356
{ return tribool(indeterminate) == x; }
sl@0
   357
sl@0
   358
/**
sl@0
   359
 * \overload
sl@0
   360
 */
sl@0
   361
inline tribool operator==(tribool x, indeterminate_keyword_t)
sl@0
   362
{ return tribool(indeterminate) == x; }
sl@0
   363
sl@0
   364
/**
sl@0
   365
 * \brief Compare tribools for inequality
sl@0
   366
 *
sl@0
   367
 * \returns the result of comparing two tribool values for inequality,
sl@0
   368
 * according to the following table:
sl@0
   369
 *       <table border=1>
sl@0
   370
 *           <tr>
sl@0
   371
 *             <th><center><code>!=</code></center></th>
sl@0
   372
 *             <th><center>false</center></th>
sl@0
   373
 *             <th><center>true</center></th>
sl@0
   374
 *             <th><center>indeterminate</center></th>
sl@0
   375
 *           </tr>
sl@0
   376
 *           <tr>
sl@0
   377
 *             <th><center>false</center></th>
sl@0
   378
 *             <td><center>false</center></td>
sl@0
   379
 *             <td><center>true</center></td>
sl@0
   380
 *             <td><center>indeterminate</center></td>
sl@0
   381
 *           </tr>
sl@0
   382
 *           <tr>
sl@0
   383
 *             <th><center>true</center></th>
sl@0
   384
 *             <td><center>true</center></td>
sl@0
   385
 *             <td><center>false</center></td>
sl@0
   386
 *             <td><center>indeterminate</center></td>
sl@0
   387
 *           </tr>
sl@0
   388
 *           <tr>
sl@0
   389
 *             <th><center>indeterminate</center></th>
sl@0
   390
 *             <td><center>indeterminate</center></td>
sl@0
   391
 *             <td><center>indeterminate</center></td>
sl@0
   392
 *             <td><center>indeterminate</center></td>
sl@0
   393
 *           </tr>
sl@0
   394
 *       </table>
sl@0
   395
 * \throws nothrow
sl@0
   396
 */
sl@0
   397
inline tribool operator!=(tribool x, tribool y)
sl@0
   398
{
sl@0
   399
  if (indeterminate(x) || indeterminate(y))
sl@0
   400
    return indeterminate;
sl@0
   401
  else
sl@0
   402
    return !(x && y || !x && !y);
sl@0
   403
}
sl@0
   404
sl@0
   405
/**
sl@0
   406
 * \overload
sl@0
   407
 */
sl@0
   408
inline tribool operator!=(tribool x, bool y) { return x != tribool(y); }
sl@0
   409
sl@0
   410
/**
sl@0
   411
 * \overload
sl@0
   412
 */
sl@0
   413
inline tribool operator!=(bool x, tribool y) { return tribool(x) != y; }
sl@0
   414
sl@0
   415
/**
sl@0
   416
 * \overload
sl@0
   417
 */
sl@0
   418
inline tribool operator!=(indeterminate_keyword_t, tribool x)
sl@0
   419
{ return tribool(indeterminate) != x; }
sl@0
   420
sl@0
   421
/**
sl@0
   422
 * \overload
sl@0
   423
 */
sl@0
   424
inline tribool operator!=(tribool x, indeterminate_keyword_t)
sl@0
   425
{ return x != tribool(indeterminate); }
sl@0
   426
sl@0
   427
} } // end namespace boost::logic
sl@0
   428
sl@0
   429
// Pull tribool and indeterminate into namespace "boost"
sl@0
   430
namespace boost {
sl@0
   431
  using logic::tribool;
sl@0
   432
  using logic::indeterminate;
sl@0
   433
}
sl@0
   434
sl@0
   435
/**
sl@0
   436
 * \brief Declare a new name for the third state of a tribool
sl@0
   437
 *
sl@0
   438
 * Use this macro to declare a new name for the third state of a
sl@0
   439
 * tribool. This state can have any number of new names (in addition
sl@0
   440
 * to \c indeterminate), all of which will be equivalent. The new name will be
sl@0
   441
 * placed in the namespace in which the macro is expanded.
sl@0
   442
 *
sl@0
   443
 * Example:
sl@0
   444
 *   BOOST_TRIBOOL_THIRD_STATE(true_or_false)
sl@0
   445
 *
sl@0
   446
 *   tribool x(true_or_false);
sl@0
   447
 *   // potentially set x
sl@0
   448
 *   if (true_or_false(x)) {
sl@0
   449
 *     // don't know what x is
sl@0
   450
 *   }
sl@0
   451
 */
sl@0
   452
#define BOOST_TRIBOOL_THIRD_STATE(Name)                                 \
sl@0
   453
inline bool                                                             \
sl@0
   454
Name(boost::logic::tribool x,                                           \
sl@0
   455
     boost::logic::detail::indeterminate_t dummy =                      \
sl@0
   456
       boost::logic::detail::indeterminate_t())                         \
sl@0
   457
{ return x.value == boost::logic::tribool::indeterminate_value; }
sl@0
   458
sl@0
   459
#endif // BOOST_LOGIC_TRIBOOL_HPP
sl@0
   460