Add and use new singleton class

Use a very basic implementation and explicit inst() calls for access
This commit is contained in:
Flamefire 2018-11-15 19:41:35 +01:00
parent e92f52821d
commit 9f1690b5da
10 changed files with 78 additions and 45 deletions

View file

@ -12,36 +12,35 @@
#include "../config.hpp" #include "../config.hpp"
#include "function.hpp" #include "function.hpp"
#include "mutex.hpp" #include "mutex.hpp"
#include "singleton.hpp"
namespace mock namespace mock
{ {
namespace detail namespace detail
{ {
class functor_mutex_t : class functor_mutex_t :
public boost::unit_test::singleton< functor_mutex_t >, public singleton< functor_mutex_t >,
public mutex public mutex
{ {
private: MOCK_SINGLETON_CONS( functor_mutex_t );
BOOST_TEST_SINGLETON_CONS( functor_mutex_t );
}; };
BOOST_TEST_SINGLETON_INST( functor_mutex )
template< typename Signature > template< typename Signature >
struct functor : function< Signature > struct functor : function< Signature >
{ {
functor() functor()
{ {
scoped_lock _( functor_mutex ); scoped_lock _( functor_mutex::inst() );
static functor* f = 0; static functor* f = 0;
if( f ) if( f )
{ {
*this = *f; *this = *f;
f = 0; f = 0;
functor_mutex.unlock(); functor_mutex::inst().unlock();
} }
else else
{ {
functor_mutex.lock(); functor_mutex::inst().lock();
f = this; f = this;
} }
} }

View file

@ -10,7 +10,7 @@
#define MOCK_MUTEX_HPP_INCLUDED #define MOCK_MUTEX_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/test/utils/trivial_singleton.hpp> #include "singleton.hpp"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#ifdef MOCK_THREAD_SAFE #ifdef MOCK_THREAD_SAFE
@ -93,13 +93,11 @@ namespace mock
{ {
namespace detail namespace detail
{ {
class error_mutex_t : public boost::unit_test::singleton< error_mutex_t >, class error_mutex_t : public singleton< error_mutex_t >,
public mutex public mutex
{ {
private: MOCK_SINGLETON_CONS( error_mutex_t );
BOOST_TEST_SINGLETON_CONS( error_mutex_t );
}; };
BOOST_TEST_SINGLETON_INST( error_mutex )
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
# pragma warning( push ) # pragma warning( push )
@ -110,25 +108,25 @@ namespace detail
{ {
static Result abort() static Result abort()
{ {
scoped_lock _( error_mutex ); scoped_lock _( error_mutex::inst() );
return Error::abort(); return Error::abort();
} }
template< typename Context > template< typename Context >
static void fail( const char* message, const Context& context, static void fail( const char* message, const Context& context,
const char* file = "unknown location", int line = 0 ) const char* file = "unknown location", int line = 0 )
{ {
scoped_lock _( error_mutex ); scoped_lock _( error_mutex::inst() );
Error::fail( message, context, file, line ); Error::fail( message, context, file, line );
} }
template< typename Context > template< typename Context >
static void call( const Context& context, const char* file, int line ) static void call( const Context& context, const char* file, int line )
{ {
scoped_lock _( error_mutex ); scoped_lock _( error_mutex::inst() );
Error::call( context, file, line ); Error::call( context, file, line );
} }
static void pass( const char* file, int line ) static void pass( const char* file, int line )
{ {
scoped_lock _( error_mutex ); scoped_lock _( error_mutex::inst() );
Error::pass( file, line ); Error::pass( file, line );
} }
}; };

View file

@ -40,7 +40,7 @@ namespace detail
{ {
lock _( mutex_ ); lock _( mutex_ );
if( children_.empty() ) if( children_.empty() )
detail::root.add( *this ); detail::root::inst().add( *this );
children_[ &v ].update( parent_, instance, type, name ); children_[ &v ].update( parent_, instance, type, name );
} }
virtual void add( verifiable& v ) virtual void add( verifiable& v )
@ -54,7 +54,7 @@ namespace detail
group_.remove( v ); group_.remove( v );
children_.erase( &v ); children_.erase( &v );
if( children_.empty() ) if( children_.empty() )
detail::root.remove( *this ); detail::root::inst().remove( *this );
} }
virtual void serialize( std::ostream& s, const verifiable& v ) const virtual void serialize( std::ostream& s, const verifiable& v ) const

View file

@ -15,7 +15,7 @@
#include "context.hpp" #include "context.hpp"
#include "child.hpp" #include "child.hpp"
#include "mutex.hpp" #include "mutex.hpp"
#include <boost/test/utils/trivial_singleton.hpp> #include "singleton.hpp"
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <ostream> #include <ostream>
#include <map> #include <map>
@ -24,7 +24,7 @@ namespace mock
{ {
namespace detail namespace detail
{ {
class root_t : public boost::unit_test::singleton< root_t >, public context class root_t : public singleton< root_t >, public context
{ {
public: public:
virtual void add( const void* p, verifiable& v, virtual void add( const void* p, verifiable& v,
@ -128,10 +128,8 @@ namespace detail
group group_; group group_;
mutable mutex mutex_; mutable mutex mutex_;
private: MOCK_SINGLETON_CONS( root_t );
BOOST_TEST_SINGLETON_CONS( root_t );
}; };
BOOST_TEST_SINGLETON_INST( root )
} }
} // mock } // mock

View file

@ -0,0 +1,39 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2014
//
// 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_SINGLETON_HPP
#define MOCK_SINGLETON_HPP
#include <boost/config.hpp>
namespace mock {
namespace detail {
template<typename Derived>
class singleton {
public:
static Derived& inst() { static Derived the_inst; return the_inst; }
BOOST_DELETED_FUNCTION(singleton(singleton const&))
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
protected:
BOOST_DEFAULTED_FUNCTION(singleton(), {})
BOOST_DEFAULTED_FUNCTION(~singleton(), {})
};
// Add a private ctor to the type to prevent misuse
#define MOCK_SINGLETON_CONS( type ) \
private: \
friend class ::mock::detail::singleton<type>; \
type() {}
} // detail
} // mock
#endif // MOCK_SINGLETON_HPP

View file

@ -55,9 +55,9 @@
#endif // MOCK_VARIADIC_MACROS #endif // MOCK_VARIADIC_MACROS
#define MOCK_HELPER(t) \ #define MOCK_HELPER(t) \
t##_mock( mock::detail::root, BOOST_PP_STRINGIZE(t) ) t##_mock( mock::detail::root::inst(), BOOST_PP_STRINGIZE(t) )
#define MOCK_ANONYMOUS_HELPER(t) \ #define MOCK_ANONYMOUS_HELPER(t) \
t##_mock( mock::detail::root, "?." ) t##_mock( mock::detail::root::inst(), "?." )
#define MOCK_METHOD_HELPER(S, t, tpn) \ #define MOCK_METHOD_HELPER(S, t, tpn) \
mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \ mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \

View file

@ -40,7 +40,7 @@ namespace detail
typename boost::is_base_of< object, T > typename boost::is_base_of< object, T >
>::type* = 0 ) >::type* = 0 )
{ {
e.configure( detail::root, &t, instance, type, name ); e.configure( detail::root::inst(), &t, instance, type, name );
return e; return e;
} }
} }

View file

@ -18,7 +18,7 @@ namespace mock
{ {
inline void reset() inline void reset()
{ {
detail::root.reset(); detail::root::inst().reset();
} }
inline void reset( const object& o ) inline void reset( const object& o )
{ {

View file

@ -18,7 +18,7 @@ namespace mock
{ {
inline bool verify() inline bool verify()
{ {
return detail::root.verify(); return detail::root::inst().verify();
} }
inline bool verify( const object& o ) inline bool verify( const object& o )
{ {

View file

@ -10,12 +10,12 @@
#define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED #define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED
#define MOCK_ERROR_POLICY mock_error #define MOCK_ERROR_POLICY mock_error
#include <turtle/detail/singleton.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <stdexcept> #include <stdexcept>
struct mock_error_data_t : boost::unit_test::singleton< mock_error_data_t > struct mock_error_data_t : turtle::detail::singleton< mock_error_data_t >
{ {
void reset() void reset()
{ {
@ -52,10 +52,9 @@ struct mock_error_data_t : boost::unit_test::singleton< mock_error_data_t >
std::string last_context; std::string last_context;
std::string last_file; std::string last_file;
int last_line; int last_line;
private:
BOOST_TEST_SINGLETON_CONS( mock_error_data_t ); MOCK_SINGLETON_CONS( mock_error_data_t );
}; };
BOOST_TEST_SINGLETON_INST( mock_error_data )
template< typename Result > template< typename Result >
struct mock_error struct mock_error
@ -72,14 +71,14 @@ struct mock_error
static void call( const Context& /*context*/, static void call( const Context& /*context*/,
const char* /*file*/, int /*line*/ ) const char* /*file*/, int /*line*/ )
{ {
mock_error_data.call(); mock_error_data::inst().call();
} }
template< typename Context > template< typename Context >
static void fail( const std::string& message, const Context& context, static void fail( const std::string& message, const Context& context,
const char* file = "", int line = 0 ) const char* file = "", int line = 0 )
{ {
mock_error_data.fail( message, mock_error_data::inst().fail( message,
boost::lexical_cast< std::string >( context ), file, line ); boost::lexical_cast< std::string >( context ), file, line );
} }
}; };
@ -88,25 +87,25 @@ struct mock_error_fixture
{ {
mock_error_fixture() mock_error_fixture()
{ {
mock_error_data.reset(); mock_error_data::inst().reset();
} }
~mock_error_fixture() ~mock_error_fixture()
{ {
BOOST_CHECK( mock_error_data.verify() ); BOOST_CHECK( mock_error_data::inst().verify() );
BOOST_CHECK_EQUAL( 0, mock_error_data.call_count ); BOOST_CHECK_EQUAL( 0, mock_error_data::inst().call_count );
} }
}; };
#define CHECK_CALLS( calls ) \ #define CHECK_CALLS( calls ) \
BOOST_CHECK_EQUAL( calls, mock_error_data.call_count ); \ BOOST_CHECK_EQUAL( calls, mock_error_data::inst().call_count ); \
mock_error_data.call_count = 0; mock_error_data::inst().call_count = 0;
#define CHECK_ERROR( expr, error, calls, context ) \ #define CHECK_ERROR( expr, error, calls, context ) \
BOOST_CHECK( mock_error_data.verify() ); \ BOOST_CHECK( mock_error_data::inst().verify() ); \
try { expr; } catch( ... ) {} \ try { expr; } catch( ... ) {} \
BOOST_CHECK_EQUAL( 1, mock_error_data.error_count ); \ BOOST_CHECK_EQUAL( 1, mock_error_data::inst().error_count ); \
BOOST_CHECK_EQUAL( error, mock_error_data.last_message ); \ BOOST_CHECK_EQUAL( error, mock_error_data::inst().last_message ); \
BOOST_CHECK_EQUAL( context, mock_error_data.last_context ); \ BOOST_CHECK_EQUAL( context, mock_error_data::inst().last_context ); \
CHECK_CALLS( calls ); \ CHECK_CALLS( calls ); \
mock_error_data.reset(); mock_error_data::inst().reset();
#endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED #endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED