You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2018/12/20 23:34:15 UTC

svn commit: r1849444 - in /subversion/trunk/subversion/bindings/cxx: include/svnxx/tristate.hpp src/private.hpp src/private/tristate-private.hpp src/tristate.cpp tests/test_tristate.cpp

Author: brane
Date: Thu Dec 20 23:34:15 2018
New Revision: 1849444

URL: http://svn.apache.org/viewvc?rev=1849444&view=rev
Log:
Implement a fesh new tristate type in SVN++.

* subversion/bindings/cxx/include/svnxx/tristate.hpp
  (class Tristate): Removed.
  (class tristate): New.
  (operator&&, operator||, operator==, operator!=): Logical and comparison
   operators for the tristate class.

* subversion/bindings/cxx/src/private/tristate-private.hpp: New file.
  (convert): New; conversions between the tristate class and svn_tristate_t.

* subversion/bindings/cxx/src/private.hpp:
   - Rename include guard.
   - Include private/tristate-private.hpp.
* subversion/bindings/cxx/src/tristate.cpp: Removed.

* subversion/bindings/cxx/tests/test_tristate.cpp: New.

Added:
    subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp   (with props)
    subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp   (with props)
Removed:
    subversion/trunk/subversion/bindings/cxx/src/tristate.cpp
Modified:
    subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp
    subversion/trunk/subversion/bindings/cxx/src/private.hpp

Modified: subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp?rev=1849444&r1=1849443&r2=1849444&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp Thu Dec 20 23:34:15 2018
@@ -32,31 +32,344 @@ namespace apache {
 namespace subversion {
 namespace svnxx {
 
-class Tristate
+/**
+ * @brief A three-state Boolean-like type.
+ *
+ * @c tristate values represent one of three states:
+ * @li the @e true state (equivalent to Boolean @c true);
+ * @li the @e false state (equivalent to Boolean @c false);
+ * @li the @e unknown state.
+ *
+ * @c tristate constructors, methods and operators are all
+ * compile-time constant expressions and can be used to initialize
+ * other @c constexpr values. And unlike most other types,
+ * comparisons and logical operations between @c tristate values
+ * return a @c tristate, not a @c bool.
+ *
+ * Given a @c tristate value @a t, the state it represents can be
+ * uniquely determined by the following coding pattern:
+ * @code{.cpp}
+ *   if (t) {
+ *       // t is true
+ *   }
+ *   else if (!t) {
+ *       // t is false
+ *   else {
+ *       // t is unknown
+ *   }
+ * @endcode
+ *
+ * @note Inspired by <tt>boost::tribool</tt>
+ */
+class tristate
 {
+  struct impl
+  {
+    void trueval() {};
+  };
+  using safe_bool = void (impl::*)();
+
+  // The default constructor creates the unkonwn state.
+  constexpr tristate() noexcept
+    : value(unknown_value)
+    {}
+
 public:
-  static const Tristate TRUE;
-  static const Tristate FALSE;
-  static const Tristate UNKNOWN;
+  /**
+   * @brief Factory method for the @e unknown state.
+   */
+  static constexpr tristate unknown() noexcept
+    { return tristate(/*unknown_value*/); }
 
-  Tristate(const Tristate& that) throw()
-    : m_value(that.m_value)
+  /**
+   * @brief Constructor for the @e true and @e false states.
+   */
+  constexpr tristate(bool initial_value) noexcept
+    : value(initial_value ? true_value : false_value)
     {}
 
-  bool operator==(const Tristate& that) const throw()
-    { return m_value == that.m_value; }
+  /**
+   * @brief Safe conversion to @c bool.
+   * @returns a @e true-like value only when this @c tristate is the
+   * @e true state.
+   */
+  constexpr operator safe_bool() const noexcept
+    { return value == true_value ? &impl::trueval : 0; }
 
-  bool operator!=(const Tristate& that) const throw()
-    { return !(*this == that); }
+  /**
+   * @brief Logical negation.
+   * @returns the logical negation of a @c tristate, according to
+   * the following table:
+   *   <table border=1>
+   *     <tr>
+   *       <th><center><code>!</code></center></th>
+   *       <th/>
+   *     </tr>
+   *     <tr>
+   *       <th><center><em>false</em></center></th>
+   *       <td><center><em>true</em></center></td>
+   *     </tr>
+   *     <tr>
+   *       <th><center><em>true</em></center></th>
+   *       <td><center><em>false</em></center></td>
+   *     </tr>
+   *     <tr>
+   *       <th><center><em>unknown</em></center></th>
+   *       <td><center><em>unknown</em></center></td>
+   *     </tr>
+   *   </table>
+   */
+  constexpr tristate operator!() const noexcept
+    {
+      return (value == false_value ? tristate(true)
+              : (value == true_value ? tristate(false)
+                 : tristate::unknown()));
+    }
 
-  bool known() const throw()
-    { return *this != UNKNOWN; }
+  /**
+   * @brief Test for the @e unknown state.
+   * @returns @c true only if @a t is the @e unknown state.
+   */
+  static constexpr bool unknown(tristate t) noexcept
+    { return t.value == unknown_value; }
 
 private:
-  explicit Tristate(short int value) throw();
-  short int m_value;
+  // See svn_tristate_t in svn_types.h.
+  enum: unsigned char {
+    false_value = 2,
+    true_value,
+    unknown_value
+  } value;
 };
 
+/**
+ * @related tristate
+ * @brief Logical conjunction.
+ * @returns the result of a logical @c AND of two @c tristate
+ * values, according to the following table:
+ *   <table border=1>
+ *     <tr>
+ *       <th><center><code>&amp;&amp;</code></center></th>
+ *       <th><center><em>false</em></center></th>
+ *       <th><center><em>true</em></center></th>
+ *       <th><center><em>unknown</em></center></th>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>false</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>false</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>true</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>unknown</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *   </table>
+ */
+constexpr inline tristate operator&&(tristate t, tristate u) noexcept
+{
+  return (bool(!t) || bool(!u) ? tristate(false)
+          : (bool(t) && bool(u) ? tristate(true)
+             : tristate::unknown()));
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator&&(tristate t, bool b) noexcept
+{
+  return b ? t : tristate(false);
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator&&(bool b, tristate t) noexcept
+{
+  return b ? t : tristate(false);
+}
+
+/**
+ * @related tristate
+ * @brief Logical disjunction.
+ * @returns the result of a logical @c OR of two @c tristate
+ * values, according to the following table:
+ *   <table border=1>
+ *     <tr>
+ *       <th><center><code>||</code></center></th>
+ *       <th><center><em>false</em></center></th>
+ *       <th><center><em>true</em></center></th>
+ *       <th><center><em>unknown</em></center></th>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>false</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>true</em></center></th>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>unknown</em></center></th>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *   </table>
+ */
+constexpr inline tristate operator||(tristate t, tristate u) noexcept
+{
+  return (bool(!t) && bool(!u) ? tristate(false)
+          : (bool(t) || bool(u) ? tristate(true)
+             : tristate::unknown()));
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator||(tristate t, bool b) noexcept
+{
+  return b ? tristate(true) : t;
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator||(bool b, tristate t) noexcept
+{
+  return b ? tristate(true) : t;
+}
+
+/**
+ * @related tristate
+ * @brief Equality comparison.
+ * @returns the result of comparing two @c tristate values for
+ * equality, according to the following table:
+ *   <table border=1>
+ *     <tr>
+ *       <th><center><code>==</code></center></th>
+ *       <th><center><em>false</em></center></th>
+ *       <th><center><em>true</em></center></th>
+ *       <th><center><em>unknown</em></center></th>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>false</em></center></th>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>true</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>unknown</em></center></th>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *   </table>
+ */
+constexpr inline tristate operator==(tristate t, tristate u) noexcept
+{
+  return (tristate::unknown(t) || tristate::unknown(u)
+          ? tristate::unknown()
+          : ((t && u) || (!t && !u)));
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator==(tristate t, bool b) noexcept
+{
+  return t == tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator==(bool b, tristate t) noexcept
+{
+  return tristate(b) == t;
+}
+
+/**
+ * @related tristate
+ * @brief Inquality comparison.
+ * @returns the result of comparing two @c tristate values for
+ * inequality, according to the following table:
+ *   <table border=1>
+ *     <tr>
+ *       <th><center><code>!=</code></center></th>
+ *       <th><center><em>false</em></center></th>
+ *       <th><center><em>true</em></center></th>
+ *       <th><center><em>unknown</em></center></th>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>false</em></center></th>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>true</em></center></th>
+ *       <td><center><em>true</em></center></td>
+ *       <td><center><em>false</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *     <tr>
+ *       <th><center><em>unknown</em></center></th>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *       <td><center><em>unknown</em></center></td>
+ *     </tr>
+ *   </table>
+ */
+constexpr inline tristate operator!=(tristate t, tristate u) noexcept
+{
+  return (tristate::unknown(t) || tristate::unknown(u)
+          ? tristate::unknown()
+          : !((t && u) || (!t && !u)));
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator!=(tristate t, bool b) noexcept
+{
+  return t != tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ */
+constexpr inline tristate operator!=(bool b, tristate t) noexcept
+{
+  return tristate(b) != t;
+}
+
 } // namespace svnxx
 } // namespace subversion
 } // namespace apache

Modified: subversion/trunk/subversion/bindings/cxx/src/private.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private.hpp?rev=1849444&r1=1849443&r2=1849444&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/src/private.hpp Thu Dec 20 23:34:15 2018
@@ -21,9 +21,10 @@
  * @endcopyright
  */
 
-#ifndef SVNXX_PRIVATE_PRIVATE_H
-#define SVNXX_PRIVATE_PRIVATE_H
+#ifndef SVNXX_PRIVATE_PRIVATE_HPP
+#define SVNXX_PRIVATE_PRIVATE_HPP
 
 #include "private/exception-private.hpp"
+#include "private/tristate-private.hpp"
 
-#endif // SVNXX_PRIVATE_PRIVATE_H
+#endif // SVNXX_PRIVATE_PRIVATE_HPP

Added: subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp?rev=1849444&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp (added)
+++ subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp Thu Dec 20 23:34:15 2018
@@ -0,0 +1,63 @@
+/**
+ * @copyright
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+#ifndef __cplusplus
+#error "This is a C++ header file."
+#endif
+
+#ifndef SVNXX_PRIVATE_TRISTATE_HPP
+#define SVNXX_PRIVATE_TRISTATE_HPP
+
+#include "svnxx/tristate.hpp"
+#include "svn_types.h"
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+namespace detail {
+
+/**
+ * Converts an @c svn_tristate_t value to a @c tristate value.
+ */
+inline constexpr tristate convert(svn_tristate_t x)
+{
+  return (x == svn_tristate_true ? tristate(true)
+          : (x == svn_tristate_false ? tristate(false)
+             : tristate::unknown()));
+}
+
+/**
+ * Converts a @c tristate value to an @c svn_tristate_t value.
+ */
+inline constexpr svn_tristate_t convert(tristate t)
+{
+  return (t ? svn_tristate_true
+          : (!t ? svn_tristate_false : svn_tristate_unknown));
+}
+
+} // namespace detail
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_PRIVATE_TRISTATE_HPP

Propchange: subversion/trunk/subversion/bindings/cxx/src/private/tristate-private.hpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp?rev=1849444&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp (added)
+++ subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp Thu Dec 20 23:34:15 2018
@@ -0,0 +1,262 @@
+/*
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+#include <boost/test/unit_test.hpp>
+
+#include "svnxx/tristate.hpp"
+#include "../src/private/tristate-private.hpp"
+
+namespace svn = ::apache::subversion::svnxx;
+namespace detail = ::apache::subversion::svnxx::detail;
+
+BOOST_AUTO_TEST_SUITE(tristate);
+
+namespace {
+constexpr auto T = svn::tristate(true);
+constexpr auto F = svn::tristate(false);
+constexpr auto X = svn::tristate::unknown();
+} // anonymous namespace
+
+BOOST_AUTO_TEST_CASE(constants)
+{
+  BOOST_TEST(!svn::tristate::unknown(T));
+  BOOST_TEST(!svn::tristate::unknown(F));
+  BOOST_TEST(svn::tristate::unknown(X));
+
+  BOOST_TEST(bool(T));
+  BOOST_TEST(!bool(!T));
+
+  BOOST_TEST(!bool(F));
+  BOOST_TEST(bool(!F));
+
+  BOOST_TEST(!bool(X));
+  BOOST_TEST(!bool(!X));
+}
+
+BOOST_AUTO_TEST_CASE(conversions)
+{
+  BOOST_TEST(detail::convert(T) == svn_tristate_true);
+  BOOST_TEST(detail::convert(F) == svn_tristate_false);
+  BOOST_TEST(detail::convert(X) == svn_tristate_unknown);
+
+  BOOST_TEST(detail::convert(svn_tristate_true) == T);
+  BOOST_TEST(detail::convert(svn_tristate_false) == F);
+  BOOST_TEST(svn::tristate::unknown(detail::convert(svn_tristate_unknown)));
+}
+
+BOOST_AUTO_TEST_CASE(construct_true)
+{
+  constexpr auto state = svn::tristate(true);
+  BOOST_TEST(!svn::tristate::unknown(state));
+  BOOST_TEST(bool(state));
+  BOOST_TEST(!bool(!state));
+}
+
+BOOST_AUTO_TEST_CASE(construct_false)
+{
+  constexpr auto state = svn::tristate(false);
+  BOOST_TEST(!svn::tristate::unknown(state));
+  BOOST_TEST(!bool(state));
+  BOOST_TEST(bool(!state));
+}
+
+BOOST_AUTO_TEST_CASE(construct_unknown)
+{
+  constexpr auto state = svn::tristate::unknown();
+  BOOST_TEST(svn::tristate::unknown(state));
+  BOOST_TEST(!bool(state));
+  BOOST_TEST(!bool(!state));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_and_tristate)
+{
+  BOOST_TEST((T && T) == T);
+  BOOST_TEST((T && F) == F);
+  BOOST_TEST((F && T) == F);
+  BOOST_TEST((F && F) == F);
+  BOOST_TEST(svn::tristate::unknown(T && X));
+  BOOST_TEST(svn::tristate::unknown(X && T));
+  BOOST_TEST((F && X) == F);
+  BOOST_TEST((X && F) == F);
+  BOOST_TEST(svn::tristate::unknown(X && X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_and_bool)
+{
+  BOOST_TEST((T &&  true) == T);
+  BOOST_TEST((T && false) == F);
+  BOOST_TEST((F &&  true) == F);
+  BOOST_TEST((F && false) == F);
+  BOOST_TEST(svn::tristate::unknown(X && true));
+  BOOST_TEST((X && false) == F);
+}
+
+BOOST_AUTO_TEST_CASE(bool_and_tristate)
+{
+  BOOST_TEST((true  && T) == T);
+  BOOST_TEST((false && T) == F);
+  BOOST_TEST((true  && F) == F);
+  BOOST_TEST((false && F) == F);
+  BOOST_TEST(svn::tristate::unknown(true && X));
+  BOOST_TEST((false && X) == F);
+}
+
+BOOST_AUTO_TEST_CASE(tristate_and_number)
+{
+  BOOST_TEST((T &&  1) == T);
+  BOOST_TEST((T &&  0) == F);
+  BOOST_TEST((F && -1) == F);
+  BOOST_TEST((F &&  0) == F);
+  BOOST_TEST(svn::tristate::unknown(X &&  5));
+  BOOST_TEST((X &&  0) == F);
+}
+
+BOOST_AUTO_TEST_CASE(number_and_tristate)
+{
+
+  BOOST_TEST((77 && T) == T);
+  BOOST_TEST(( 0 && T) == F);
+  BOOST_TEST((~0 && F) == F);
+  BOOST_TEST(( 0 && F) == F);
+  BOOST_TEST(svn::tristate::unknown(07 && X));
+  BOOST_TEST(( 0 && X) == F);
+}
+
+BOOST_AUTO_TEST_CASE(tristate_or_tristate)
+{
+  BOOST_TEST((T || T) == T);
+  BOOST_TEST((T || F) == T);
+  BOOST_TEST((F || T) == T);
+  BOOST_TEST((F || F) == F);
+  BOOST_TEST((T || X) == T);
+  BOOST_TEST((X || T) == T);
+  BOOST_TEST(svn::tristate::unknown(F || X));
+  BOOST_TEST(svn::tristate::unknown(X || F));
+  BOOST_TEST(svn::tristate::unknown(X || X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_or_bool)
+{
+  BOOST_TEST((T ||  true) == T);
+  BOOST_TEST((T || false) == T);
+  BOOST_TEST((F ||  true) == T);
+  BOOST_TEST((F || false) == F);
+  BOOST_TEST((X ||  true) == T);
+  BOOST_TEST(svn::tristate::unknown(X || false));
+}
+
+BOOST_AUTO_TEST_CASE(bool_or_tristate)
+{
+  BOOST_TEST((true  || T) == T);
+  BOOST_TEST((false || T) == T);
+  BOOST_TEST((true  || F) == T);
+  BOOST_TEST((false || F) == F);
+  BOOST_TEST((true  || X) == T);
+  BOOST_TEST(svn::tristate::unknown(false || X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_or_number)
+{
+  BOOST_TEST((T ||  1) == T);
+  BOOST_TEST((T ||  0) == T);
+  BOOST_TEST((F || -1) == T);
+  BOOST_TEST((F ||  0) == F);
+  BOOST_TEST((X ||  5) == T);
+  BOOST_TEST(svn::tristate::unknown(X || 0));
+}
+
+BOOST_AUTO_TEST_CASE(number_or_tristate)
+{
+
+  BOOST_TEST((77 || T) == T);
+  BOOST_TEST(( 0 || T) == T);
+  BOOST_TEST((~0 || F) == T);
+  BOOST_TEST(( 0 || F) == F);
+  BOOST_TEST((07 || X) == T);
+  BOOST_TEST(svn::tristate::unknown(0 || X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_eq_tristate)
+{
+  BOOST_TEST((T == T) == T);
+  BOOST_TEST((T == F) == F);
+  BOOST_TEST(svn::tristate::unknown(T == X));
+  BOOST_TEST((F == T) == F);
+  BOOST_TEST((F == F) == T);
+  BOOST_TEST(svn::tristate::unknown(F == X));
+  BOOST_TEST(svn::tristate::unknown(X == T));
+  BOOST_TEST(svn::tristate::unknown(X == F));
+  BOOST_TEST(svn::tristate::unknown(X == X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_eq_bool)
+{
+  BOOST_TEST((T ==  true) == T);
+  BOOST_TEST((T == false) == F);
+  BOOST_TEST((F ==  true) == F);
+  BOOST_TEST((F == false) == T);
+  BOOST_TEST(svn::tristate::unknown(X == true));
+  BOOST_TEST(svn::tristate::unknown(X == false));
+}
+
+BOOST_AUTO_TEST_CASE(bool_eq_tristate)
+{
+  BOOST_TEST((true  == T) == T);
+  BOOST_TEST((false == T) == F);
+  BOOST_TEST((true  == F) == F);
+  BOOST_TEST((false == F) == T);
+  BOOST_TEST(svn::tristate::unknown(true  == X));
+  BOOST_TEST(svn::tristate::unknown(false == X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_neq_tristate)
+{
+  BOOST_TEST((T != T) == F);
+  BOOST_TEST((T != F) == T);
+  BOOST_TEST(svn::tristate::unknown(T != X));
+  BOOST_TEST((F != T) == T);
+  BOOST_TEST((F != F) == F);
+  BOOST_TEST(svn::tristate::unknown(F != X));
+  BOOST_TEST(svn::tristate::unknown(X != T));
+  BOOST_TEST(svn::tristate::unknown(X != F));
+  BOOST_TEST(svn::tristate::unknown(X != X));
+}
+
+BOOST_AUTO_TEST_CASE(tristate_neq_bool)
+{
+  BOOST_TEST((T !=  true) == F);
+  BOOST_TEST((T != false) == T);
+  BOOST_TEST((F !=  true) == T);
+  BOOST_TEST((F != false) == F);
+  BOOST_TEST(svn::tristate::unknown(X != true));
+  BOOST_TEST(svn::tristate::unknown(X != false));
+}
+
+BOOST_AUTO_TEST_CASE(bool_neq_tristate)
+{
+  BOOST_TEST((true  != T) == F);
+  BOOST_TEST((false != T) == T);
+  BOOST_TEST((true  != F) == T);
+  BOOST_TEST((false != F) == F);
+  BOOST_TEST(svn::tristate::unknown(true  != X));
+  BOOST_TEST(svn::tristate::unknown(false != X));
+}
+
+BOOST_AUTO_TEST_SUITE_END();

Propchange: subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp
------------------------------------------------------------------------------
    svn:eol-style = native