From f1afd177173329e33b61564b1a2b8f54689f77b1 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 15 Feb 2008 18:40:36 +0000 Subject: [PATCH] Added support for &&, || [SVN r43269] --- include/boost/bind.hpp | 26 ++++++++++++ test/Jamfile.v2 | 1 + test/bind_and_or_test.cpp | 84 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 test/bind_and_or_test.cpp diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index e1076e0..dd606ad 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -248,6 +248,9 @@ public: } }; +struct logical_and; +struct logical_or; + template< class A1, class A2 > class list2: private storage2< A1, A2 > { private: @@ -294,6 +297,26 @@ public: unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); } + template bool operator()( type, logical_and & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_and const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + template void accept(V & v) const { base_type::accept(v); @@ -1158,6 +1181,9 @@ BOOST_BIND_OPERATOR( <=, less_equal ) BOOST_BIND_OPERATOR( >, greater ) BOOST_BIND_OPERATOR( >=, greater_equal ) +BOOST_BIND_OPERATOR( &&, logical_and ) +BOOST_BIND_OPERATOR( ||, logical_or ) + #undef BOOST_BIND_OPERATOR #if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b88d49e..b7cecea 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -27,6 +27,7 @@ test-suite "bind" [ run bind_visit_test.cpp ] [ run bind_placeholder_test.cpp ] [ run bind_rvalue_test.cpp ] + [ run bind_and_or_test.cpp ] [ run mem_fn_test.cpp ] [ run mem_fn_void_test.cpp ] [ run mem_fn_derived_test.cpp ] diff --git a/test/bind_and_or_test.cpp b/test/bind_and_or_test.cpp new file mode 100644 index 0000000..337a11e --- /dev/null +++ b/test/bind_and_or_test.cpp @@ -0,0 +1,84 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// +// bind_and_or_test.cpp - &&, || operators +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(push, 3) +#endif + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(pop) +#endif + +#include + +bool f( bool x ) +{ + return x; +} + +bool g( bool x ) +{ + return !x; +} + +bool h() +{ + BOOST_ERROR( "Short-circuit evaluation failure" ); + return false; +} + +template< class F, class A1, class A2, class R > void test( F f, A1 a1, A2 a2, R r ) +{ + BOOST_TEST( f( a1, a2 ) == r ); +} + +int main() +{ + // && + + test( boost::bind( f, true ) && boost::bind( g, true ), false, false, f( true ) && g( true ) ); + test( boost::bind( f, true ) && boost::bind( g, false ), false, false, f( true ) && g( false ) ); + + test( boost::bind( f, false ) && boost::bind( h ), false, false, f( false ) && h() ); + + test( boost::bind( f, _1 ) && boost::bind( g, _2 ), true, true, f( true ) && g( true ) ); + test( boost::bind( f, _1 ) && boost::bind( g, _2 ), true, false, f( true ) && g( false ) ); + + test( boost::bind( f, _1 ) && boost::bind( h ), false, false, f( false ) && h() ); + + // || + + test( boost::bind( f, false ) || boost::bind( g, true ), false, false, f( false ) || g( true ) ); + test( boost::bind( f, false ) || boost::bind( g, false ), false, false, f( false ) || g( false ) ); + + test( boost::bind( f, true ) || boost::bind( h ), false, false, f( true ) || h() ); + + test( boost::bind( f, _1 ) || boost::bind( g, _2 ), false, true, f( false ) || g( true ) ); + test( boost::bind( f, _1 ) || boost::bind( g, _2 ), false, false, f( false ) || g( false ) ); + + test( boost::bind( f, _1 ) || boost::bind( h ), true, false, f( true ) || h() ); + + // + + return boost::report_errors(); +}