summaryrefslogtreecommitdiff
path: root/subversion/bindings/cxx/include/svnxx/tristate.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/bindings/cxx/include/svnxx/tristate.hpp')
-rw-r--r--subversion/bindings/cxx/include/svnxx/tristate.hpp501
1 files changed, 501 insertions, 0 deletions
diff --git a/subversion/bindings/cxx/include/svnxx/tristate.hpp b/subversion/bindings/cxx/include/svnxx/tristate.hpp
new file mode 100644
index 0000000..0554e29
--- /dev/null
+++ b/subversion/bindings/cxx/include/svnxx/tristate.hpp
@@ -0,0 +1,501 @@
+/**
+ * @file svnxx/tristate.hpp
+ * @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 SVNXX_TRISTATE_HPP
+#define SVNXX_TRISTATE_HPP
+
+#include "svn_types_impl.h"
+
+#include <cstdint>
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+#include <boost/logic/tribool.hpp>
+#endif
+
+namespace apache {
+namespace subversion {
+namespace svnxx {
+
+/**
+ * @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:
+ /**
+ * @brief Factory method for the @e unknown state.
+ */
+ static constexpr tristate unknown() noexcept
+ {
+ return tristate(/*unknown_value*/);
+ }
+
+ /**
+ * @brief Constructor for the @e true and @e false states.
+ */
+ constexpr tristate(bool initial_value) noexcept
+ : value(initial_value ? true_value : false_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;
+ }
+
+ /**
+ * @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></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()));
+ }
+
+private:
+ // NOTE: Keep these values identical to those in svn_tristate_t!
+ enum : std::uint8_t {
+ false_value = svn_tristate_false,
+ true_value = svn_tristate_true,
+ unknown_value = svn_tristate_unknown
+ } value;
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+public:
+ /**
+ * @brief Conversion from <tt>boost::tribool</tt>.
+ * @returns a @c tribool value equivalent to the @a t.
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+ constexpr tristate(boost::tribool t) noexcept
+ : value(boost::indeterminate(t) ? unknown_value
+ : (t ? true_value : false_value))
+ {}
+
+ /**
+ * @brief Conversion to <tt>boost::tribool</tt>.
+ * @returns a <tt>boost::tribool</tt> value equivalent to the @c
+ * tristate value.
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+ constexpr operator boost::tribool() const noexcept
+ {
+ return (value == true_value ? boost::tribool(true)
+ : (value == false_value ? boost::tribool(false)
+ : boost::tribool(boost::indeterminate)));
+ }
+#endif
+};
+
+/**
+ * @related tristate
+ * @brief Test for the @e unknown @c tristate state.
+ * @returns @c true only if @a t is the @e unknown state.
+ */
+constexpr inline bool unknown(tristate t) noexcept
+{
+ return bool(t) == bool(!t);
+}
+
+/**
+ * @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);
+}
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator&&(tristate t, boost::tribool b) noexcept
+{
+ return t && tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator&&(boost::tribool b, tristate t) noexcept
+{
+ return tristate(b) && t;
+}
+#endif
+
+/**
+ * @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;
+}
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator||(tristate t, boost::tribool b) noexcept
+{
+ return t || tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator||(boost::tribool b, tristate t) noexcept
+{
+ return tristate(b) || t;
+}
+#endif
+
+/**
+ * @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 (unknown(t) || 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;
+}
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator==(tristate t, boost::tribool b) noexcept
+{
+ return t == tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator==(boost::tribool b, tristate t) noexcept
+{
+ return tristate(b) == t;
+}
+#endif
+
+/**
+ * @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 (unknown(t) || 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;
+}
+
+#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN)
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator!=(tristate t, boost::tribool b) noexcept
+{
+ return t != tristate(b);
+}
+
+/**
+ * @related tristate
+ * @overload
+ * @note Avalible only if @c SVNXX_USE_BOOST is defined.
+ */
+constexpr inline tristate operator!=(boost::tribool b, tristate t) noexcept
+{
+ return tristate(b) != t;
+}
+#endif
+
+} // namespace svnxx
+} // namespace subversion
+} // namespace apache
+
+#endif // SVNXX_TRISTATE_HPP