From 4148ae7bc4cc687d4345edb25f65df5776ed168f Mon Sep 17 00:00:00 2001 From: mat007 Date: Sun, 22 Jul 2012 07:04:48 +0000 Subject: [PATCH] Refactoring git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@491 860be788-9bd5-4423-9f1e-828f051e677b --- build/vc100/turtle.vcxproj | 1 + build/vc100/turtle.vcxproj.filters | 3 + turtle/detail/function_impl_template.hpp | 184 ++++++++++++++++++++++ turtle/detail/function_template.hpp | 185 ++--------------------- 4 files changed, 199 insertions(+), 174 deletions(-) create mode 100644 turtle/detail/function_impl_template.hpp diff --git a/build/vc100/turtle.vcxproj b/build/vc100/turtle.vcxproj index bb4c605..48e4b80 100644 --- a/build/vc100/turtle.vcxproj +++ b/build/vc100/turtle.vcxproj @@ -32,6 +32,7 @@ + diff --git a/build/vc100/turtle.vcxproj.filters b/build/vc100/turtle.vcxproj.filters index a628ba1..7f1ae8e 100644 --- a/build/vc100/turtle.vcxproj.filters +++ b/build/vc100/turtle.vcxproj.filters @@ -109,5 +109,8 @@ Source Files\detail + + Source Files\detail + \ No newline at end of file diff --git a/turtle/detail/function_impl_template.hpp b/turtle/detail/function_impl_template.hpp new file mode 100644 index 0000000..b66e6e4 --- /dev/null +++ b/turtle/detail/function_impl_template.hpp @@ -0,0 +1,184 @@ +// http://turtle.sourceforge.net +// +// Copyright Mathieu Champlon 2012 +// +// 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 "expectation_template.hpp" + +#define MOCK_FORMAT(z, n, N) \ +<< " " << mock::format( t##n ) \ +<< BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",") +#define MOCK_CONTEXT \ +boost::unit_test::lazy_ostream::instance() \ + << lazy_context( this ) \ + << "(" BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FORMAT, \ + BOOST_PP_DEC(MOCK_NUM_ARGS)) \ + << ")" \ + << lazy_expectations( this ) + +namespace mock +{ +namespace detail +{ + template< typename Signature > class function_impl; + + template< typename R BOOST_PP_COMMA_IF(MOCK_NUM_ARGS) + BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) > + class function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > + : public detail::verifiable, + public boost::enable_shared_from_this< + function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )> > + { + public: + typedef MOCK_ERROR_POLICY< R > error_type; + + typedef detail::expectation< + R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) + > expectation_type; + + public: + function_impl() + : context_( 0 ) + , valid_( true ) + {} + virtual ~function_impl() + { + if( valid_ && ! std::uncaught_exception() ) + for( expectations_cit it = expectations_.begin(); + it != expectations_.end(); ++it ) + { + if( ! it->verify() ) + error_type::untriggered_expectation( + boost::unit_test::lazy_ostream::instance() + << *this, it->file(), it->line() ); + else if( ! it->invoked() ) + error_type::expected_call( + boost::unit_test::lazy_ostream::instance() + << *this, it->file(), it->line() ); + } + if( context_ ) + context_->remove( *this ); + } + + virtual bool verify() const + { + for( expectations_cit it = expectations_.begin(); + it != expectations_.end(); ++it ) + if( !it->verify() ) + { + valid_ = false; + error_type::verification_failed( + boost::unit_test::lazy_ostream::instance() + << *this, it->file(), it->line() ); + } + return valid_; + } + + virtual void reset() + { + valid_ = true; + boost::shared_ptr< function_impl > guard = + this->shared_from_this(); + expectations_.clear(); + } + + expectation_type& expect( const char* file, int line ) + { + expectation_type& e = expect(); + e.set_location( file, line ); + return e; + } + expectation_type& expect() + { + expectations_.push_back( expectation_type() ); + valid_ = true; + return expectations_.back(); + } + + R operator()( + BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const + { + valid_ = false; + for( expectations_cit it = expectations_.begin(); + it != expectations_.end(); ++it ) + if( it->is_valid( + BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ) ) + { + if( ! it->invoke() ) + { + error_type::sequence_failed( + MOCK_CONTEXT, it->file(), it->line() ); + return error_type::abort(); + } + if( ! it->functor() ) + { + error_type::missing_action( + MOCK_CONTEXT, it->file(), it->line() ); + return error_type::abort(); + } + valid_ = true; + error_type::expected_call( + MOCK_CONTEXT, it->file(), it->line() ); + return it->functor()( + BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ); + } + error_type::unexpected_call( MOCK_CONTEXT ); + return error_type::abort(); + } + + friend std::ostream& operator<<( + std::ostream& s, const function_impl& e ) + { + return s << lazy_context( &e ) << lazy_expectations( &e ); + } + + struct lazy_context + { + lazy_context( const function_impl* impl ) + : impl_( impl ) + {} + friend std::ostream& operator<<( + std::ostream& s, const lazy_context& c ) + { + if( c.impl_->context_ ) + c.impl_->context_->serialize( s, *c.impl_ ); + else + s << "?"; + return s; + } + const function_impl* impl_; + }; + + struct lazy_expectations + { + lazy_expectations( const function_impl* impl ) + : impl_( impl ) + {} + friend std::ostream& operator<<( + std::ostream& s, const lazy_expectations& e ) + { + for( expectations_cit it = e.impl_->expectations_.begin(); + it != e.impl_->expectations_.end(); ++it ) + s << std::endl << *it; + return s; + } + const function_impl* impl_; + }; + + typedef std::list< expectation_type > expectations_type; + typedef BOOST_DEDUCED_TYPENAME + expectations_type::const_iterator expectations_cit; + + expectations_type expectations_; + detail::context* context_; + mutable bool valid_; + }; +} +} // mock + +#undef MOCK_FORMAT +#undef MOCK_OPERATOR +#undef MOCK_CONTEXT diff --git a/turtle/detail/function_template.hpp b/turtle/detail/function_template.hpp index d1ce2bb..88b5ca4 100644 --- a/turtle/detail/function_template.hpp +++ b/turtle/detail/function_template.hpp @@ -6,7 +6,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include "expectation_template.hpp" +#include "function_impl_template.hpp" namespace mock { @@ -28,13 +28,15 @@ namespace detail }; private: - typedef detail::expectation< - R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) - > expectation_type; + typedef function_impl< + R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > impl_type; + typedef BOOST_DEDUCED_TYPENAME + impl_type::expectation_type expectation_type; + typedef BOOST_DEDUCED_TYPENAME impl_type::error_type error_type; public: function() - : impl_( new function_impl() ) + : impl_( new impl_type() ) {} bool verify() const @@ -43,7 +45,7 @@ namespace detail } bool verify( const char* file, int line ) const { - function_impl::error_type::checkpoint( file, line ); + error_type::checkpoint( file, line ); return impl_->verify(); } void reset() @@ -52,13 +54,13 @@ namespace detail } void reset( const char* file, int line ) { - function_impl::error_type::checkpoint( file, line ); + error_type::checkpoint( file, line ); return impl_->reset(); } expectation_type& expect( const char* file, int line ) { - function_impl::error_type::checkpoint( file, line ); + error_type::checkpoint( file, line ); return impl_->expect(); } expectation_type& expect() @@ -99,172 +101,7 @@ namespace detail } private: - class function_impl : public detail::verifiable, - public boost::enable_shared_from_this< function_impl > - { - public: - typedef MOCK_ERROR_POLICY< R > error_type; - - public: - function_impl() - : context_( 0 ) - , valid_( true ) - {} - virtual ~function_impl() - { - if( valid_ && ! std::uncaught_exception() ) - for( expectations_cit it = expectations_.begin(); - it != expectations_.end(); ++it ) - { - if( ! it->verify() ) - error_type::untriggered_expectation( - boost::unit_test::lazy_ostream::instance() - << lazy_context( this ) - << lazy_expectations( this ), - it->file(), it->line() ); - else if( ! it->invoked() ) - error_type::expected_call( - boost::unit_test::lazy_ostream::instance() - << lazy_context( this ) - << lazy_expectations( this ), - it->file(), it->line() ); - } - if( context_ ) - context_->remove( *this ); - } - - virtual bool verify() const - { - for( expectations_cit it = expectations_.begin(); - it != expectations_.end(); ++it ) - if( !it->verify() ) - { - valid_ = false; - error_type::verification_failed( - boost::unit_test::lazy_ostream::instance() - << lazy_context( this ) - << lazy_expectations( this ), - it->file(), it->line() ); - } - return valid_; - } - - virtual void reset() - { - valid_ = true; - boost::shared_ptr< function_impl > guard = - this->shared_from_this(); - expectations_.clear(); - } - - expectation_type& expect( const char* file, int line ) - { - expectation_type& e = expect(); - e.set_location( file, line ); - return e; - } - expectation_type& expect() - { - expectations_.push_back( expectation_type() ); - valid_ = true; - return expectations_.back(); - } - -#define MOCK_FORMAT(z, n, N) \ - << " " << mock::format( t##n ) \ - << BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",") -#define MOCK_CONTEXT \ - boost::unit_test::lazy_ostream::instance() \ - << lazy_context( this ) \ - << "(" BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FORMAT, \ - BOOST_PP_DEC(MOCK_NUM_ARGS)) \ - << ")" \ - << lazy_expectations( this ) - - R operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const - { - valid_ = false; - for( expectations_cit it = expectations_.begin(); - it != expectations_.end(); ++it ) - if( it->is_valid( \ - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ) ) - { - if( ! it->invoke() ) - { - error_type::sequence_failed( - MOCK_CONTEXT, it->file(), it->line() ); - return error_type::abort(); - } - if( ! it->functor() ) - { - error_type::missing_action( - MOCK_CONTEXT, it->file(), it->line() ); - return error_type::abort(); - } - valid_ = true; - error_type::expected_call( - MOCK_CONTEXT, it->file(), it->line() ); - return it->functor()( \ - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ); - } - error_type::unexpected_call( MOCK_CONTEXT ); - return error_type::abort(); - } - -#undef MOCK_FORMAT -#undef MOCK_OPERATOR -#undef MOCK_CONTEXT - - friend std::ostream& operator<<( - std::ostream& s, const function_impl& e ) - { - return s << lazy_context( &e ) << lazy_expectations( &e ); - } - - struct lazy_context - { - lazy_context( const function_impl* impl ) - : impl_( impl ) - {} - friend std::ostream& operator<<( - std::ostream& s, const lazy_context& c ) - { - if( c.impl_->context_ ) - c.impl_->context_->serialize( s, *c.impl_ ); - else - s << "?"; - return s; - } - const function_impl* impl_; - }; - - struct lazy_expectations - { - lazy_expectations( const function_impl* impl ) - : impl_( impl ) - {} - friend std::ostream& operator<<( - std::ostream& s, const lazy_expectations& e ) - { - for( expectations_cit it = e.impl_->expectations_.begin(); - it != e.impl_->expectations_.end(); ++it ) - s << std::endl << *it; - return s; - } - const function_impl* impl_; - }; - - typedef std::list< expectation_type > expectations_type; - typedef BOOST_DEDUCED_TYPENAME - expectations_type::const_iterator expectations_cit; - - expectations_type expectations_; - detail::context* context_; - mutable bool valid_; - }; - - boost::shared_ptr< function_impl > impl_; + boost::shared_ptr< impl_type > impl_; }; } } // mock