From 21a62d0de7e1b281f9c8060e3b7542f0c4a3c593 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 16 Nov 2018 15:23:18 +0100 Subject: [PATCH] Fix C++98 compatibility Arguments are now passed by (const) reference and not unconditionally as rvalue references --- include/turtle/constraint.hpp | 18 ++++++--- include/turtle/constraints.hpp | 40 ++++++++++++------- include/turtle/detail/action.hpp | 4 +- .../turtle/detail/expectation_template.hpp | 21 +++++----- include/turtle/detail/function.hpp | 7 ++++ .../turtle/detail/function_impl_template.hpp | 6 +-- include/turtle/detail/function_template.hpp | 2 +- .../turtle/detail/matcher_base_template.hpp | 9 +++-- include/turtle/matcher.hpp | 8 ++++ include/turtle/mock.hpp | 2 +- test/test_constraints.cpp | 3 +- 11 files changed, 77 insertions(+), 43 deletions(-) diff --git a/include/turtle/constraint.hpp b/include/turtle/constraint.hpp index 081c04d..c08bdb9 100644 --- a/include/turtle/constraint.hpp +++ b/include/turtle/constraint.hpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include namespace mock { @@ -145,8 +147,8 @@ namespace detail } \ const mock::constraint< detail::Name > Name; -#define MOCK_CONSTRAINT_ASSIGN(z, n, d) \ - expected##n( e##n ) +#define MOCK_CONSTRAINT_ASSIGN(z, n, Args) \ + expected##n( boost::forward< T##n >( BOOST_PP_ARRAY_ELEM(n, Args) ) ) #define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) \ boost::unwrap_ref( expected##n ) @@ -154,11 +156,14 @@ namespace detail #define MOCK_CONSTRAINT_FORMAT(z, n, d) \ BOOST_PP_IF(n, << ", " <<,) mock::format( c.expected##n ) +#define MOCK_CONSTRAINT_MEMBER_TYPE(n) \ + typename boost::decay< typename boost::add_const< Expected_##n >::type >::type + #define MOCK_CONSTRAINT_MEMBER(z, n, d) \ - Expected_##n expected##n; + MOCK_CONSTRAINT_MEMBER_TYPE(n) expected##n; #define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \ - const typename boost::unwrap_reference< Expected_##n >::type& \ + const typename boost::unwrap_reference< MOCK_CONSTRAINT_MEMBER_TYPE(n) >::type& \ BOOST_PP_ARRAY_ELEM(n, Args) #define MOCK_CONSTRAINT_ARG(z, n, Args) \ @@ -173,9 +178,10 @@ namespace detail template< BOOST_PP_ENUM_PARAMS(n, typename Expected_) > \ struct Name \ { \ + template< BOOST_PP_ENUM_PARAMS(n, typename T) > \ explicit Name( \ - BOOST_PP_ENUM_BINARY_PARAMS(n, Expected_, e) ) \ - : BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \ + BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARG, (n, Args)) ) \ + : BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, (n, Args)) \ {} \ template< typename Actual > \ bool operator()( const Actual& actual ) const \ diff --git a/include/turtle/constraints.hpp b/include/turtle/constraints.hpp index 5433874..409c89f 100644 --- a/include/turtle/constraints.hpp +++ b/include/turtle/constraints.hpp @@ -170,10 +170,33 @@ namespace detail : expected_( detail::addressof( boost::unwrap_ref( expected ) ) ) {} template< typename Actual > + bool operator()( BOOST_RV_REF(Actual) actual, + typename boost::disable_if< + boost::is_convertible< Actual*, + typename + boost::unwrap_reference< Expected >::type + > + >::type* = 0 ) const + { + *expected_ = boost::move(actual); + return true; + } + template< typename Actual > + bool operator()( Actual& actual, + typename boost::disable_if< + boost::is_convertible< Actual*, + typename + boost::unwrap_reference< Expected >::type + > + >::type* = 0 ) const + { + *expected_ = static_cast< BOOST_RV_REF(Actual) >(actual); + return true; + } + template< typename Actual > bool operator()( const Actual& actual, typename boost::disable_if< - boost::is_convertible< - const Actual*, + boost::is_convertible< Actual*, typename boost::unwrap_reference< Expected >::type > @@ -183,19 +206,6 @@ namespace detail return true; } template< typename Actual > - bool operator()( BOOST_RV_REF(Actual) actual, - typename boost::disable_if< - boost::is_convertible< - const Actual*, - typename - boost::unwrap_reference< Expected >::type - > - >::type* = 0 ) const - { - *expected_ = boost::move( actual ); - return true; - } - template< typename Actual > bool operator()( Actual& actual, typename boost::enable_if< boost::is_convertible< Actual*, diff --git a/include/turtle/detail/action.hpp b/include/turtle/detail/action.hpp index b201cd9..117c475 100644 --- a/include/turtle/detail/action.hpp +++ b/include/turtle/detail/action.hpp @@ -105,7 +105,7 @@ namespace detail } template< typename Value > - void moves( BOOST_RV_REF(Value) v ) + void moves( BOOST_FWD_REF(Value) v ) { this->set( boost::bind( @@ -137,7 +137,7 @@ namespace detail value_imp( BOOST_RV_REF(value_type) t ) : t_( boost::move( t ) ) {} - value_imp( const T& t ) + value_imp( const value_type& t ) : t_( t ) {} template< typename Y > diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index 33d6487..731a108 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -12,10 +12,10 @@ BOOST_PP_COMMA_IF(n) c##n##_( c##n ) #define MOCK_EXPECTATION_MEMBER(z, n, d) \ - matcher< T##n, Constraint_##n > c##n##_; + matcher< typename boost::remove_reference< T##n >::type, Constraint_##n > c##n##_; #define MOCK_EXPECTATION_IS_VALID(z, n, d) \ - BOOST_PP_IF(n, &&,) c##n##_( boost::forward< T##n >( a##n ) ) + BOOST_PP_IF(n, &&,) c##n##_( a##n ) #define MOCK_EXPECTATION_SERIALIZE(z, n, d) \ BOOST_PP_IF(n, << ", " <<,) c##n##_ @@ -24,10 +24,10 @@ BOOST_PP_IF(n, << ", " <<,) "any" #define MOCK_EXPECTATION_PARAM(z, n, Args) \ - boost::forward< T##n >( a##n ) + a##n -#define MOCK_RV_REF_ARG(z, n, d) \ - BOOST_RV_REF(T##n) a##n +#define MOCK_ARG_TYPE(z, n, d) \ + typename ::mock::detail::ref_arg< T##n >::type a##n namespace mock { @@ -42,7 +42,7 @@ namespace detail { private: virtual bool operator()( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF, _) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_ARG_TYPE, _) ) { return true; } @@ -76,7 +76,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_ARG_TYPE, _) ) { return BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_IS_VALID, _); @@ -106,7 +106,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_ARG_TYPE, _) ) { return f_( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) ); } @@ -204,7 +204,7 @@ namespace detail } bool is_valid( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) const + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_ARG_TYPE, _) ) const { return !invocation_->exhausted() && (*matcher_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) ); @@ -268,5 +268,4 @@ namespace detail #undef MOCK_EXPECTATION_SERIALIZE #undef MOCK_EXPECTATION_SERIALIZE_ANY #undef MOCK_EXPECTATION_PARAM -#undef MOCK_RV_REF_ARG -#undef MOCK_RV_REF +#undef MOCK_ARG_TYPE diff --git a/include/turtle/detail/function.hpp b/include/turtle/detail/function.hpp index 7432384..803672a 100644 --- a/include/turtle/detail/function.hpp +++ b/include/turtle/detail/function.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,12 @@ namespace mock { namespace detail { + template< typename T > + struct ref_arg + { + typedef typename boost::add_reference::type type; + }; + template< typename R, typename E > struct wrapper_base { diff --git a/include/turtle/detail/function_impl_template.hpp b/include/turtle/detail/function_impl_template.hpp index 4d47a82..1d305a3 100644 --- a/include/turtle/detail/function_impl_template.hpp +++ b/include/turtle/detail/function_impl_template.hpp @@ -183,9 +183,9 @@ namespace detail this->e_->throws( t ); } template< typename TT > - void moves( BOOST_RV_REF(TT) t ) + void moves( BOOST_FWD_REF(TT) t ) { - this->e_->moves( boost::move( t ) ); + this->e_->moves( boost::forward( t ) ); } lock lock_; @@ -217,7 +217,7 @@ namespace detail for( expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it ) if( it->is_valid( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) ) + BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ) ) { if( ! it->invoke() ) { diff --git a/include/turtle/detail/function_template.hpp b/include/turtle/detail/function_template.hpp index 04a0ad2..c597869 100644 --- a/include/turtle/detail/function_template.hpp +++ b/include/turtle/detail/function_template.hpp @@ -9,7 +9,7 @@ #include "function_impl_template.hpp" #define MOCK_FORWARD(z, n, d) \ - boost::forward< T##n >( t##n ) + boost::move_if_not_lvalue_reference< T##n >( t##n ) namespace mock { diff --git a/include/turtle/detail/matcher_base_template.hpp b/include/turtle/detail/matcher_base_template.hpp index f8b64ee..d92590e 100644 --- a/include/turtle/detail/matcher_base_template.hpp +++ b/include/turtle/detail/matcher_base_template.hpp @@ -6,8 +6,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#define MOCK_RV_REF(z, n, d) \ - BOOST_RV_REF(T##n) +#define MOCK_ARG_TYPE(z, n, d) \ + typename ::mock::detail::ref_arg< T##n >::type a##n namespace mock { @@ -24,7 +24,7 @@ namespace detail virtual ~matcher_base() {} virtual bool operator()( - BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF, _) ) = 0; + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_ARG_TYPE, _) ) = 0; friend std::ostream& operator<<( std::ostream& s, const matcher_base& m ) @@ -38,3 +38,6 @@ namespace detail }; } } // mock + +#undef MOCK_ARG_TYPE +#undef MOCK_REF_ARG_TYPEDEF diff --git a/include/turtle/matcher.hpp b/include/turtle/matcher.hpp index 91f1f23..517d0ee 100644 --- a/include/turtle/matcher.hpp +++ b/include/turtle/matcher.hpp @@ -71,6 +71,10 @@ namespace mock { return c_( boost::forward< Actual >( actual ) ); } + bool operator()( Actual& actual ) + { + return c_( actual ); + } friend std::ostream& operator<<( std::ostream& s, const matcher& m ) { @@ -95,6 +99,10 @@ namespace mock { return c_( boost::forward< Actual >( actual ) ); } + bool operator()( Actual& actual ) + { + return c_( actual ); + } friend std::ostream& operator<<( std::ostream& s, const matcher& m ) { diff --git a/include/turtle/mock.hpp b/include/turtle/mock.hpp index 204061d..c765a13 100644 --- a/include/turtle/mock.hpp +++ b/include/turtle/mock.hpp @@ -87,7 +87,7 @@ BOOST_PP_COMMA_IF(n) d, n >::type >( p##n ) #define MOCK_FORWARD_PARAMS(n, S, tpn) \ BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, \ - boost::forward< MOCK_PARAM(S, tpn)) + boost::move_if_not_lvalue_reference< MOCK_PARAM(S, tpn)) #define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \ { \ diff --git a/test/test_constraints.cpp b/test/test_constraints.cpp index 27d1782..9e918da 100644 --- a/test/test_constraints.cpp +++ b/test/test_constraints.cpp @@ -8,6 +8,7 @@ #include #include +#include BOOST_AUTO_TEST_CASE( all_comparison_constraints_can_be_instanciated ) { @@ -47,7 +48,7 @@ BOOST_AUTO_TEST_CASE( equal_constraint ) BOOST_CHECK( ! mock::equal( std::string( "string" ) ).c_( "not string" ) ); { std::string s; - auto c = mock::equal( boost::cref( s ) ); + BOOST_AUTO( c, mock::equal( boost::cref( s ) ) ); s = "string"; BOOST_CHECK( c.c_( "string" ) ); }