Author: brane Date: Sat Dec 22 15:34:06 2018 New Revision: 1849555 URL: http://svn.apache.org/viewvc?rev=1849555&view=rev Log: Provide optional interoperability between tristate and boost::tribool in SVNXX.
* subversion/bindings/cxx/include/svnxx/tristate.hpp: (class tristate): Add conversions to and from boost::tribool if SVNXX_USE_BOOST is defined. (operator&&, operator||, operator==, operator!=): Likewise, when SVNXX_USE_BOOST is defined, provide overloads for boost::tribool. Modified: subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp 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=1849555&r1=1849554&r2=1849555&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp (original) +++ subversion/trunk/subversion/bindings/cxx/include/svnxx/tristate.hpp Sat Dec 22 15:34:06 2018 @@ -28,6 +28,10 @@ #ifndef SVNXX_TRISTATE_HPP #define SVNXX_TRISTATE_HPP +#if defined(SVNXX_USE_BOOST) || defined(DOXYGEN) +#include <boost/logic/tribool.hpp> +#endif + namespace apache { namespace subversion { namespace svnxx { @@ -137,12 +141,38 @@ private: true_value, unknown_value } 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. + * @returns @c true only if @a t is the @e unknown state. */ constexpr inline bool unknown(tristate t) noexcept { @@ -206,6 +236,28 @@ constexpr inline tristate operator&&(boo 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. @@ -263,6 +315,28 @@ constexpr inline tristate operator||(boo 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. @@ -319,6 +393,28 @@ constexpr inline tristate operator==(boo 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. @@ -375,6 +471,28 @@ constexpr inline tristate operator!=(boo 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 Modified: 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=1849555&r1=1849554&r2=1849555&view=diff ============================================================================== --- subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp (original) +++ subversion/trunk/subversion/bindings/cxx/tests/test_tristate.cpp Sat Dec 22 15:34:06 2018 @@ -26,14 +26,14 @@ 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_SUITE(tristate); + BOOST_AUTO_TEST_CASE(constants) { BOOST_TEST(!svn::unknown(T)); @@ -260,3 +260,110 @@ BOOST_AUTO_TEST_CASE(bool_neq_tristate) } BOOST_AUTO_TEST_SUITE_END(); + + +#ifdef SVNXX_USE_BOOST +namespace { +constexpr auto boost_T = boost::tribool(true); +constexpr auto boost_F = boost::tribool(false); +constexpr auto boost_X = boost::tribool(boost::indeterminate); +} // anonymous namespace + +BOOST_AUTO_TEST_SUITE(tristate_tribool); + +BOOST_AUTO_TEST_CASE(conversion_to_tribool) +{ + boost::tribool state; + BOOST_TEST((state = T) == boost_T); + BOOST_TEST((state = F) == boost_F); + BOOST_TEST(boost::indeterminate(X)); +} + +BOOST_AUTO_TEST_CASE(conversion_from_tribool) +{ + svn::tristate state(false); // Note: no public default constructor. + BOOST_TEST((state = boost_T) == T); + BOOST_TEST((state = boost_F) == F); + BOOST_TEST(svn::unknown(boost_X)); +} + +BOOST_AUTO_TEST_CASE(tristate_and_tribool) +{ + BOOST_TEST((T && boost_T) == T); + BOOST_TEST((T && boost_F) == F); + BOOST_TEST((F && boost_T) == F); + BOOST_TEST((F && boost_F) == F); + BOOST_TEST(svn::unknown(T && boost_X)); + BOOST_TEST(svn::unknown(X && boost_T)); + BOOST_TEST((F && boost_X) == F); + BOOST_TEST((X && boost_F) == F); + BOOST_TEST(svn::unknown(X && boost_X)); +} + +BOOST_AUTO_TEST_CASE(tribool_and_tristate) +{ + BOOST_TEST((boost_T && T) == T); + BOOST_TEST((boost_T && F) == F); + BOOST_TEST((boost_F && T) == F); + BOOST_TEST((boost_F && F) == F); + BOOST_TEST(svn::unknown(boost_T && X)); + BOOST_TEST(svn::unknown(boost_X && T)); + BOOST_TEST((boost_F && X) == F); + BOOST_TEST((boost_X && F) == F); + BOOST_TEST(svn::unknown(boost_X && X)); +} + +BOOST_AUTO_TEST_CASE(tristate_or_tribool) +{ + BOOST_TEST((T || boost_T) == T); + BOOST_TEST((T || boost_F) == T); + BOOST_TEST((F || boost_T) == T); + BOOST_TEST((F || boost_F) == F); + BOOST_TEST((T || boost_X) == T); + BOOST_TEST((X || boost_T) == T); + BOOST_TEST(svn::unknown(F || boost_X)); + BOOST_TEST(svn::unknown(X || boost_F)); + BOOST_TEST(svn::unknown(X || boost_X)); +} + +BOOST_AUTO_TEST_CASE(tribool_or_tristate) +{ + BOOST_TEST((boost_T || T) == T); + BOOST_TEST((boost_T || F) == T); + BOOST_TEST((boost_F || T) == T); + BOOST_TEST((boost_F || F) == F); + BOOST_TEST((boost_T || X) == T); + BOOST_TEST((boost_X || T) == T); + BOOST_TEST(svn::unknown(boost_F || X)); + BOOST_TEST(svn::unknown(boost_X || F)); + BOOST_TEST(svn::unknown(boost_X || X)); +} + +BOOST_AUTO_TEST_CASE(tristate_eq_tribool) +{ + BOOST_TEST((T == boost_T) == T); + BOOST_TEST((T == boost_F) == F); + BOOST_TEST(svn::unknown(T == boost_X)); + BOOST_TEST((F == boost_T) == F); + BOOST_TEST((F == boost_F) == T); + BOOST_TEST(svn::unknown(F == boost_X)); + BOOST_TEST(svn::unknown(X == boost_T)); + BOOST_TEST(svn::unknown(X == boost_F)); + BOOST_TEST(svn::unknown(X == boost_X)); +} + +BOOST_AUTO_TEST_CASE(tribool_eq_tristate) +{ + BOOST_TEST((boost_T == T) == T); + BOOST_TEST((boost_T == F) == F); + BOOST_TEST(svn::unknown(boost_T == X)); + BOOST_TEST((boost_F == T) == F); + BOOST_TEST((boost_F == F) == T); + BOOST_TEST(svn::unknown(boost_F == X)); + BOOST_TEST(svn::unknown(boost_X == T)); + BOOST_TEST(svn::unknown(boost_X == F)); + BOOST_TEST(svn::unknown(boost_X == X)); +} + +BOOST_AUTO_TEST_SUITE_END(); +#endif // SVNXX_USE_BOOST