diff --git a/build/build.xml b/build/build.xml
index cab6e14..3a35e40 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -96,7 +96,7 @@
-
+
diff --git a/build/vc100/turtle.vcxproj b/build/vc100/turtle.vcxproj
index c714e46..05fa556 100644
--- a/build/vc100/turtle.vcxproj
+++ b/build/vc100/turtle.vcxproj
@@ -39,8 +39,11 @@
-
+
+
+
+
diff --git a/build/vc100/turtle.vcxproj.filters b/build/vc100/turtle.vcxproj.filters
index 77db42a..a64dfb7 100644
--- a/build/vc100/turtle.vcxproj.filters
+++ b/build/vc100/turtle.vcxproj.filters
@@ -25,9 +25,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -97,5 +94,17 @@
Source Files\detail
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
\ No newline at end of file
diff --git a/turtle/expectation.hpp b/turtle/expectation.hpp
deleted file mode 100644
index 3d9cab5..0000000
--- a/turtle/expectation.hpp
+++ /dev/null
@@ -1,261 +0,0 @@
-// http://turtle.sourceforge.net
-//
-// Copyright Mathieu Champlon 2008
-//
-// 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)
-
-#ifndef MOCK_EXPECTATION_HPP_INCLUDED
-#define MOCK_EXPECTATION_HPP_INCLUDED
-
-#include "config.hpp"
-#include "invocation.hpp"
-#include "action.hpp"
-#include "sequence.hpp"
-#include "check.hpp"
-#include "constraints.hpp"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace mock
-{
-namespace detail
-{
- class expectation_base
- {
- public:
- expectation_base()
- : i_( new detail::unlimited() )
- , file_( "unknown location" )
- , line_( 0 )
- {}
- void set_location( const char* file, int line )
- {
- file_ = file;
- line_ = line;
- }
-
- bool verify() const
- {
- return i_->verify();
- }
-
- bool invoke() const
- {
- for( sequences_cit it = sequences_.begin();
- it != sequences_.end(); ++it )
- if( ! (*it)->is_valid( this ) )
- return false;
- bool result = i_->invoke();
- for( sequences_cit it = sequences_.begin();
- it != sequences_.end(); ++it )
- (*it)->invalidate( this );
- return result;
- }
-
- bool invoked() const
- {
- return i_->invoked();
- }
-
- const char* file() const
- {
- return file_;
- }
- int line() const
- {
- return line_;
- }
-
- protected:
- ~expectation_base()
- {
- for( sequences_cit it = sequences_.begin();
- it != sequences_.end(); ++it )
- (*it)->remove( this );
- }
-
- void expect( detail::invocation* i )
- {
- i_.reset( i );
- }
-
- void add( boost::shared_ptr< detail::sequence_impl > s )
- {
- s->add( this );
- sequences_.push_back( s );
- }
-
- boost::shared_ptr< detail::invocation > i_;
-
- private:
- typedef std::vector<
- boost::shared_ptr< detail::sequence_impl >
- > sequences_type;
- typedef sequences_type::const_iterator sequences_cit;
-
- sequences_type sequences_;
- const char* file_;
- int line_;
- };
-
- template< typename Signature, int Arity >
- class expectation
- {
- };
-
-#define MOCK_EXPECTATION_METHODS \
- expectation& in( sequence& s ) \
- { \
- add( s.impl_ ); \
- return *this; \
- } \
- expectation& once() \
- { \
- expect( new detail::once() ); \
- return *this; \
- } \
- expectation& never() \
- { \
- expect( new detail::never() ); \
- return *this; \
- } \
- expectation& exactly( std::size_t count ) \
- { \
- expect( new detail::exactly( count ) ); \
- return *this; \
- } \
- expectation& at_least( std::size_t min ) \
- { \
- expect( new detail::at_least( min ) ); \
- return *this; \
- } \
- expectation& at_most( std::size_t max ) \
- { \
- expect( new detail::at_most( max ) ); \
- return *this; \
- } \
- expectation& between( std::size_t min, std::size_t max ) \
- { \
- expect( new detail::between( min, max ) ); \
- return *this; \
- }
-
- template< typename Signature >
- class expectation< Signature, 0 >
- : public expectation_base
- , public action< BOOST_DEDUCED_TYPENAME
- boost::function_types::result_type< Signature >::type, Signature >
- {
- public:
- bool is_valid() const
- {
- return ! i_->exhausted();
- }
-
- MOCK_EXPECTATION_METHODS
-
- friend std::ostream& operator<<( std::ostream& s,
- const expectation& m )
- {
- return s << (m.i_->exhausted() ? 'v' : '.') << ' ' << *m.i_;
- }
- };
-
-#define MOCK_EXPECTATION_TYPEDEF(z, n, d) \
- typedef BOOST_DEDUCED_TYPENAME \
- boost::mpl::at_c< \
- BOOST_DEDUCED_TYPENAME \
- boost::function_types::parameter_types< Signature >, \
- n \
- >::type arg##n##_type;
-#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
- BOOST_PP_COMMA_IF(n) c##n##_( \
- new detail::check< \
- arg##n##_type, \
- constraint< detail::any > \
- >( mock::any ) )
-#define MOCK_EXPECTATION_WITH(z, n, d) \
- c##n##_.reset( \
- new detail::check< \
- arg##n##_type, \
- Constraint_##n \
- >( c##n ) );
-#define MOCK_EXPECTATION_MEMBER(z, n, d) \
- boost::shared_ptr< detail::check_base< arg##n##_type > > c##n##_;
-#define MOCK_EXPECTATION_ARGS(z, n, d) \
- BOOST_PP_COMMA_IF(n) arg##n##_type a##n
-#define MOCK_EXPECTATION_IS_VALID(z, n, d) \
- && (*c##n##_)( a##n )
-#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
- BOOST_PP_IF(n, << ", " <<,) *m.c##n##_
-#define MOCK_EXPECTATION(z, n, d) \
- template< typename Signature > \
- class expectation< Signature, n > \
- : public expectation_base \
- , public action< \
- BOOST_DEDUCED_TYPENAME \
- boost::function_types::result_type< Signature >::type, \
- Signature \
- > \
- { \
- BOOST_PP_REPEAT(n, MOCK_EXPECTATION_TYPEDEF, BOOST_PP_EMPTY) \
- public: \
- expectation() \
- : BOOST_PP_REPEAT(n, MOCK_EXPECTATION_INITIALIZE, BOOST_PP_EMPTY) \
- {} \
- template< BOOST_PP_ENUM_PARAMS(n, typename Constraint_) > \
- expectation& with( BOOST_PP_ENUM_BINARY_PARAMS(n, Constraint_, c) ) \
- { \
- BOOST_PP_REPEAT(n, MOCK_EXPECTATION_WITH, BOOST_PP_EMPTY) \
- return *this; \
- } \
- bool is_valid( \
- BOOST_PP_REPEAT(n, MOCK_EXPECTATION_ARGS, BOOST_PP_EMPTY) ) const \
- { \
- return ! i_->exhausted() \
- BOOST_PP_REPEAT(n, \
- MOCK_EXPECTATION_IS_VALID, BOOST_PP_EMPTY); \
- } \
- MOCK_EXPECTATION_METHODS \
- friend std::ostream& operator<<( \
- std::ostream& s, const expectation& m ) \
- { \
- return s << (m.i_->exhausted() ? 'v' : '.') \
- << ' ' << *m.i_ << ".with( " \
- << BOOST_PP_REPEAT(n, \
- MOCK_EXPECTATION_SERIALIZE, BOOST_PP_EMPTY) \
- << " )"; \
- } \
- private: \
- BOOST_PP_REPEAT(n, MOCK_EXPECTATION_MEMBER, BOOST_PP_EMPTY) \
- };
-
- BOOST_PP_REPEAT_FROM_TO(
- 1,
- BOOST_PP_INC(MOCK_MAX_ARGS),
- MOCK_EXPECTATION,
- BOOST_PP_EMPTY)
-
-#undef MOCK_EXPECTATION_METHODS
-#undef MOCK_EXPECTATION_TYPEDEF
-#undef MOCK_EXPECTATION_INITIALIZE
-#undef MOCK_EXPECTATION_WITH
-#undef MOCK_EXPECTATION_MEMBER
-#undef MOCK_EXPECTATION_ARGS
-#undef MOCK_EXPECTATION_IS_VALID
-#undef MOCK_EXPECTATION_SERIALIZE
-#undef MOCK_EXPECTATION
-
-}
-} // mock
-
-#endif // MOCK_EXPECTATION_HPP_INCLUDED
diff --git a/turtle/expectation_base.hpp b/turtle/expectation_base.hpp
new file mode 100644
index 0000000..b436424
--- /dev/null
+++ b/turtle/expectation_base.hpp
@@ -0,0 +1,101 @@
+// 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)
+
+#ifndef MOCK_EXPECTATION_BASE_HPP_INCLUDED
+#define MOCK_EXPECTATION_BASE_HPP_INCLUDED
+
+#include "invocation.hpp"
+#include "sequence.hpp"
+#include
+#include
+
+namespace mock
+{
+namespace detail
+{
+ class expectation_base
+ {
+ public:
+ expectation_base()
+ : i_( new detail::unlimited() )
+ , file_( "unknown location" )
+ , line_( 0 )
+ {}
+ void set_location( const char* file, int line )
+ {
+ file_ = file;
+ line_ = line;
+ }
+
+ bool verify() const
+ {
+ return i_->verify();
+ }
+
+ bool invoke() const
+ {
+ for( sequences_cit it = sequences_.begin();
+ it != sequences_.end(); ++it )
+ if( ! (*it)->is_valid( this ) )
+ return false;
+ bool result = i_->invoke();
+ for( sequences_cit it = sequences_.begin();
+ it != sequences_.end(); ++it )
+ (*it)->invalidate( this );
+ return result;
+ }
+
+ bool invoked() const
+ {
+ return i_->invoked();
+ }
+
+ const char* file() const
+ {
+ return file_;
+ }
+ int line() const
+ {
+ return line_;
+ }
+
+ protected:
+ ~expectation_base()
+ {
+ for( sequences_cit it = sequences_.begin();
+ it != sequences_.end(); ++it )
+ (*it)->remove( this );
+ }
+
+ void expect( detail::invocation* i )
+ {
+ i_.reset( i );
+ }
+
+ void add( boost::shared_ptr< detail::sequence_impl > s )
+ {
+ s->add( this );
+ sequences_.push_back( s );
+ }
+
+ boost::shared_ptr< detail::invocation > i_;
+
+ private:
+ typedef std::vector<
+ boost::shared_ptr< detail::sequence_impl >
+ > sequences_type;
+ typedef sequences_type::const_iterator sequences_cit;
+
+ sequences_type sequences_;
+ const char* file_;
+ int line_;
+ };
+}
+} // mock
+
+#endif // MOCK_EXPECTATION_BASE_HPP_INCLUDED
diff --git a/turtle/expectation_template.hpp b/turtle/expectation_template.hpp
new file mode 100644
index 0000000..93718ae
--- /dev/null
+++ b/turtle/expectation_template.hpp
@@ -0,0 +1,141 @@
+// 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_base.hpp"
+
+#define MOCK_EXPECTATION_TYPEDEF(z, n, d) \
+ typedef T##n arg##n##_type;
+
+#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
+ BOOST_PP_COMMA_IF(n) c##n##_( \
+ new detail::check< \
+ arg##n##_type, \
+ constraint< detail::any > \
+ >( mock::any ) )
+
+#define MOCK_EXPECTATION_WITH(z, n, d) \
+ c##n##_.reset( \
+ new detail::check< \
+ arg##n##_type, \
+ Constraint_##n \
+ >( c##n ) );
+
+#define MOCK_EXPECTATION_MEMBER(z, n, d) \
+ boost::shared_ptr< detail::check_base< arg##n##_type > > c##n##_;
+
+#define MOCK_EXPECTATION_ARGS(z, n, d) \
+ BOOST_PP_COMMA_IF(n) arg##n##_type a##n
+
+#define MOCK_EXPECTATION_IS_VALID(z, n, d) \
+ && (*c##n##_)( a##n )
+
+#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
+ BOOST_PP_IF(n, << ", " <<,) *m.c##n##_
+
+namespace mock
+{
+namespace detail
+{
+ template< typename Signature > class expectation;
+
+ template< typename R BOOST_PP_COMMA_IF(MOCK_NUM_ARGS)
+ BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
+ class expectation< R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
+ : public expectation_base
+ , public action< R, R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
+ {
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_TYPEDEF, BOOST_PP_EMPTY)
+ public:
+#ifndef MOCK_NUM_ARGS_0
+ expectation()
+ :
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_INITIALIZE, BOOST_PP_EMPTY)
+ {}
+ template< BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_) >
+ expectation& with(
+ BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
+ {
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_WITH, BOOST_PP_EMPTY)
+ return *this;
+ }
+#endif
+ bool is_valid(
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_ARGS, BOOST_PP_EMPTY) ) const
+ {
+ return ! i_->exhausted()
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_IS_VALID, BOOST_PP_EMPTY);
+ }
+
+ expectation& in( sequence& s )
+ {
+ add( s.impl_ );
+ return *this;
+ }
+ expectation& once()
+ {
+ expect( new detail::once() );
+ return *this;
+ }
+ expectation& never()
+ {
+ expect( new detail::never() );
+ return *this;
+ }
+ expectation& exactly( std::size_t count )
+ {
+ expect( new detail::exactly( count ) );
+ return *this;
+ }
+ expectation& at_least( std::size_t min )
+ {
+ expect( new detail::at_least( min ) );
+ return *this;
+ }
+ expectation& at_most( std::size_t max )
+ {
+ expect( new detail::at_most( max ) );
+ return *this;
+ }
+ expectation& between( std::size_t min, std::size_t max )
+ {
+ expect( new detail::between( min, max ) );
+ return *this;
+ }
+
+ friend std::ostream& operator<<(
+ std::ostream& s, const expectation& m )
+ {
+ return s << (m.i_->exhausted() ? 'v' : '.')
+ << ' ' << *m.i_
+#ifndef MOCK_NUM_ARGS_0
+ << ".with( "
+ << BOOST_PP_REPEAT(MOCK_NUM_ARGS,
+ MOCK_EXPECTATION_SERIALIZE, BOOST_PP_EMPTY)
+ << " )"
+#endif
+ ;
+ }
+ private:
+ BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, BOOST_PP_EMPTY)
+ };
+}
+} // mock
+
+#undef MOCK_EXPECTATION_TYPEDEF
+#undef MOCK_EXPECTATION_INITIALIZE
+#undef MOCK_EXPECTATION_WITH
+#undef MOCK_EXPECTATION_MEMBER
+#undef MOCK_EXPECTATION_ARGS
+#undef MOCK_EXPECTATION_IS_VALID
+#undef MOCK_EXPECTATION_SERIALIZE
+#undef MOCK_EXPECTATION
diff --git a/turtle/function.hpp b/turtle/function.hpp
index 9a637fb..1e29701 100644
--- a/turtle/function.hpp
+++ b/turtle/function.hpp
@@ -11,309 +11,41 @@
#include "config.hpp"
#include "error.hpp"
-#include "expectation.hpp"
#include "log.hpp"
+#include "check.hpp"
+#include "action.hpp"
+#include "invocation.hpp"
+#include "constraints.hpp"
+#include "sequence.hpp"
#include "detail/verifiable.hpp"
#include "detail/type_name.hpp"
#include "detail/context.hpp"
-#include "detail/args.hpp"
-#include
-#include
-#include
#include
#include
#include
#include
#include
#include
+#include
#include
-#include
#include
#include
+#include
#include
+#define MOCK_NUM_ARGS 0
+#define MOCK_NUM_ARGS_0
+#include "function_template.hpp"
+#undef MOCK_NUM_ARGS_0
+#undef MOCK_NUM_ARGS
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+ (3,(1,MOCK_MAX_ARGS,"function_iterate.hpp"))
+#include BOOST_PP_ITERATE()
+#undef BOOST_PP_ITERATION_PARAMS_1
+
namespace mock
{
- template< typename Signature >
- class function
- {
- public:
- typedef BOOST_DEDUCED_TYPENAME
- boost::function_types::result_type< Signature >::type result_type;
-
- template< typename Args >
- struct sig
- {
- typedef result_type type;
- };
-
- private:
- typedef BOOST_DEDUCED_TYPENAME
- boost::function_types::function_arity< Signature > arity;
- typedef BOOST_DEDUCED_TYPENAME
- detail::expectation< Signature, arity::value > expectation_type;
-
- public:
- function()
- : impl_( new function_impl() )
- {}
-
- bool verify() const
- {
- return impl_->verify();
- }
- bool verify( const char* file, int line ) const
- {
- function_impl::error_type::checkpoint( file, line );
- return impl_->verify();
- }
- void reset()
- {
- impl_->reset();
- }
- void reset( const char* file, int line )
- {
- function_impl::error_type::checkpoint( file, line );
- return impl_->reset();
- }
-
- expectation_type& expect( const char* file, int line )
- {
- function_impl::error_type::checkpoint( file, line );
- return impl_->expect();
- }
- expectation_type& expect()
- {
- return impl_->expect();
- }
-
- void test() const
- {
- impl_->test();
- }
-
- result_type operator()() const
- {
- return (*impl_)();
- }
-
-#define MOCK_FUNCTION_OPERATOR(z, n, d) \
- MOCK_DECL(operator(), n, Signature, const, BOOST_DEDUCED_TYPENAME) \
- { \
- return (*impl_)( BOOST_PP_ENUM_PARAMS(n, p) ); \
- }
-
- BOOST_PP_REPEAT_FROM_TO(
- 1,
- BOOST_PP_INC(MOCK_MAX_ARGS),
- MOCK_FUNCTION_OPERATOR,
- BOOST_PP_EMPTY)
-
-#undef MOCK_FUNCTION_OPERATOR
-
- friend std::ostream& operator<<( std::ostream& s, const function& e )
- {
- return s << *e.impl_;
- }
-
- function& operator()( detail::context& c,
- boost::unit_test::const_string instance )
- {
- if( ! impl_->context_ )
- c.add( *impl_ );
- c.add( impl_.get(), *impl_, instance,
- boost::optional< detail::type_name >(), "" );
- impl_->context_ = &c;
- return *this;
- }
-
- void configure( detail::context& c, const void* p,
- boost::unit_test::const_string instance,
- const boost::optional< detail::type_name >& type,
- boost::unit_test::const_string name ) const
- {
- if( ! impl_->context_ )
- c.add( *impl_ );
- c.add( p, *impl_, instance, type, name );
- impl_->context_ = &c;
- }
-
- private:
- class function_impl : public detail::verifiable,
- public boost::enable_shared_from_this< function_impl >
- {
- public:
- typedef MOCK_ERROR_POLICY< result_type > 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_FUNCTION_FORMAT(z, n, N) \
- << " " << mock::format( p##n ) \
- << BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",")
-#define MOCK_FUNCTION_CONTEXT(n) \
- boost::unit_test::lazy_ostream::instance() \
- << lazy_context( this ) \
- << "(" BOOST_PP_REPEAT(n, MOCK_FUNCTION_FORMAT, BOOST_PP_DEC(n)) \
- << ")" \
- << lazy_expectations( this )
-#define MOCK_FUNCTION_INVOKE(z, n, A) \
- { \
- valid_ = false; \
- for( expectations_cit it = expectations_.begin(); \
- it != expectations_.end(); ++it ) \
- if( it->is_valid( BOOST_PP_ENUM_PARAMS(n, p) ) ) \
- { \
- if( ! it->invoke() ) \
- { \
- error_type::sequence_failed( \
- MOCK_FUNCTION_CONTEXT(n), it->file(), it->line() ); \
- return A; \
- } \
- if( ! it->functor() ) \
- { \
- error_type::missing_action( \
- MOCK_FUNCTION_CONTEXT(n), it->file(), it->line() ); \
- return A; \
- } \
- valid_ = true; \
- error_type::expected_call( \
- MOCK_FUNCTION_CONTEXT(n), it->file(), it->line() ); \
- return it->functor()( BOOST_PP_ENUM_PARAMS(n, p) ); \
- } \
- error_type::unexpected_call( MOCK_FUNCTION_CONTEXT(n) ); \
- return A; \
- }
-#define MOCK_FUNCTION_OPERATOR(z, n, P) \
- MOCK_DECL(operator(), n, Signature, const, BOOST_DEDUCED_TYPENAME) \
- MOCK_FUNCTION_INVOKE(z, n, P)
-
- BOOST_PP_REPEAT(
- BOOST_PP_INC(MOCK_MAX_ARGS),
- MOCK_FUNCTION_OPERATOR,
- error_type::abort())
-
- void test() const
- MOCK_FUNCTION_INVOKE(, 0,)
-
-#undef MOCK_FUNCTION_FORMAT
-#undef MOCK_FUNCTION_OPERATOR
-#undef MOCK_FUNCTION_INVOKE
-#undef MOCK_FUNCTION_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_;
- };
-
template< typename Signature >
bool verify( const function< Signature >& f )
{
diff --git a/turtle/function_iterate.hpp b/turtle/function_iterate.hpp
new file mode 100644
index 0000000..7bf1794
--- /dev/null
+++ b/turtle/function_iterate.hpp
@@ -0,0 +1,11 @@
+// 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)
+
+#define MOCK_NUM_ARGS BOOST_PP_ITERATION()
+#include "function_template.hpp"
+#undef MOCK_NUM_ARGS
diff --git a/turtle/function_template.hpp b/turtle/function_template.hpp
new file mode 100644
index 0000000..87749e0
--- /dev/null
+++ b/turtle/function_template.hpp
@@ -0,0 +1,275 @@
+// http://turtle.sourceforge.net
+//
+// Copyright Mathieu Champlon 2008
+//
+// 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"
+
+namespace mock
+{
+ template< typename Signature > class function;
+
+ template< typename R BOOST_PP_COMMA_IF(MOCK_NUM_ARGS)
+ BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
+ class function< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
+ {
+ public:
+ typedef R result_type;
+
+ template< typename Args >
+ struct sig
+ {
+ typedef R type;
+ };
+
+ private:
+ typedef detail::expectation<
+ R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
+ > expectation_type;
+
+ public:
+ function()
+ : impl_( new function_impl() )
+ {}
+
+ bool verify() const
+ {
+ return impl_->verify();
+ }
+ bool verify( const char* file, int line ) const
+ {
+ function_impl::error_type::checkpoint( file, line );
+ return impl_->verify();
+ }
+ void reset()
+ {
+ impl_->reset();
+ }
+ void reset( const char* file, int line )
+ {
+ function_impl::error_type::checkpoint( file, line );
+ return impl_->reset();
+ }
+
+ expectation_type& expect( const char* file, int line )
+ {
+ function_impl::error_type::checkpoint( file, line );
+ return impl_->expect();
+ }
+ expectation_type& expect()
+ {
+ return impl_->expect();
+ }
+
+ void test() const
+ {
+ impl_->test();
+ }
+
+ R operator()( BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
+ {
+ return (*impl_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) );
+ }
+
+ friend std::ostream& operator<<( std::ostream& s, const function& e )
+ {
+ return s << *e.impl_;
+ }
+
+ function& operator()( detail::context& c,
+ boost::unit_test::const_string instance )
+ {
+ if( ! impl_->context_ )
+ c.add( *impl_ );
+ c.add( impl_.get(), *impl_, instance,
+ boost::optional< detail::type_name >(), "" );
+ impl_->context_ = &c;
+ return *this;
+ }
+
+ void configure( detail::context& c, const void* p,
+ boost::unit_test::const_string instance,
+ const boost::optional< detail::type_name >& type,
+ boost::unit_test::const_string name ) const
+ {
+ if( ! impl_->context_ )
+ c.add( *impl_ );
+ c.add( p, *impl_, instance, type, name );
+ impl_->context_ = &c;
+ }
+
+ private:
+ class function_impl : public detail::verifiable,
+ public boost::enable_shared_from_this< function_impl >
+ {
+ public:
+ typedef MOCK_ERROR_POLICY< result_type > 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(n) \
+ boost::unit_test::lazy_ostream::instance() \
+ << lazy_context( this ) \
+ << "(" BOOST_PP_REPEAT(n, MOCK_FORMAT, BOOST_PP_DEC(n)) \
+ << ")" \
+ << lazy_expectations( this )
+#define MOCK_INVOKE(z, n, A) \
+ { \
+ valid_ = false; \
+ for( expectations_cit it = expectations_.begin(); \
+ it != expectations_.end(); ++it ) \
+ if( it->is_valid( BOOST_PP_ENUM_PARAMS(n, t) ) ) \
+ { \
+ if( ! it->invoke() ) \
+ { \
+ error_type::sequence_failed( \
+ MOCK_CONTEXT(n), it->file(), it->line() ); \
+ return A; \
+ } \
+ if( ! it->functor() ) \
+ { \
+ error_type::missing_action( \
+ MOCK_CONTEXT(n), it->file(), it->line() ); \
+ return A; \
+ } \
+ valid_ = true; \
+ error_type::expected_call( \
+ MOCK_CONTEXT(n), it->file(), it->line() ); \
+ return it->functor()( BOOST_PP_ENUM_PARAMS(n, t) ); \
+ } \
+ error_type::unexpected_call( MOCK_CONTEXT(n) ); \
+ return A; \
+ }
+
+ result_type operator()(
+ BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
+ MOCK_INVOKE(, MOCK_NUM_ARGS, error_type::abort())
+
+ void test() const
+ MOCK_INVOKE(, 0,)
+
+#undef MOCK_FORMAT
+#undef MOCK_OPERATOR
+#undef MOCK_INVOKE
+#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_;
+ };
+} // mock