Loading...
Searching...
No Matches
tristate.hpp
Go to the documentation of this file.
/**
* @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
apache::subversion::svnxx::tristate::unknown
constexpr bool unknown(tristate t) noexcept
Test for the unknown tristate state.
Definition tristate.hpp:178
apache::subversion::svnxx::tristate::unknown
static constexpr tristate unknown() noexcept
Factory method for the unknown state.
Definition tristate.hpp:86
apache::subversion::svnxx::tristate::operator==
constexpr tristate operator==(tristate t, bool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:383
apache::subversion::svnxx::tristate::operator!=
constexpr tristate operator!=(tristate t, boost::tribool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:481
apache::subversion::svnxx::tristate::operator||
constexpr tristate operator||(boost::tribool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:335
apache::subversion::svnxx::tristate::operator&&
constexpr tristate operator&&(boost::tribool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:256
apache::subversion::svnxx::tristate::operator&&
constexpr tristate operator&&(tristate t, bool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:226
apache::subversion::svnxx::tristate::operator==
constexpr tristate operator==(boost::tribool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:413
apache::subversion::svnxx::tristate::tristate
constexpr tristate(bool initial_value) noexcept
Constructor for the true and false states.
Definition tristate.hpp:94
apache::subversion::svnxx::tristate::operator&&
constexpr tristate operator&&(bool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:235
apache::subversion::svnxx::tristate::operator!=
constexpr tristate operator!=(tristate t, bool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:461
apache::subversion::svnxx::tristate::operator!=
constexpr tristate operator!=(tristate t, tristate u) noexcept
Inquality comparison.
Definition tristate.hpp:451
apache::subversion::svnxx::tristate::operator||
constexpr tristate operator||(bool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:314
apache::subversion::svnxx::tristate::operator||
constexpr tristate operator||(tristate t, tristate u) noexcept
Logical disjunction.
Definition tristate.hpp:294
apache::subversion::svnxx::tristate::operator||
constexpr tristate operator||(tristate t, bool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:305
apache::subversion::svnxx::tristate::tristate
constexpr tristate(boost::tribool t) noexcept
Conversion from boost::tribool.
Definition tristate.hpp:153
apache::subversion::svnxx::tristate::operator&&
constexpr tristate operator&&(tristate t, boost::tribool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:246
apache::subversion::svnxx::tristate::operator==
constexpr tristate operator==(tristate t, tristate u) noexcept
Equality comparison.
Definition tristate.hpp:373
apache::subversion::svnxx::tristate::operator&&
constexpr tristate operator&&(tristate t, tristate u) noexcept
Logical conjunction.
Definition tristate.hpp:215
apache::subversion::svnxx::tristate::operator!=
constexpr tristate operator!=(boost::tribool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:491
apache::subversion::svnxx::tristate::operator!
constexpr tristate operator!() const noexcept
Logical negation.
Definition tristate.hpp:131
apache::subversion::svnxx::tristate::operator==
constexpr tristate operator==(bool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:392
apache::subversion::svnxx::tristate::operator==
constexpr tristate operator==(tristate t, boost::tribool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:403
apache::subversion::svnxx::tristate::operator!=
constexpr tristate operator!=(bool b, tristate t) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:470
apache::subversion::svnxx::tristate::operator||
constexpr tristate operator||(tristate t, boost::tribool b) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition tristate.hpp:325
svn_types_impl.h
Subversion's data types (common implementation).
svn_tristate_unknown
@ svn_tristate_unknown
state could be true or false
Definition svn_types_impl.h:89
svn_tristate_true
@ svn_tristate_true
state known to be true
Definition svn_types_impl.h:87
svn_tristate_false
@ svn_tristate_false
state known to be false (the constant does not evaulate to false)
Definition svn_types_impl.h:85