From 9f1690b5da32e27a07de7b4cf9c5b0590b36e338 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Thu, 15 Nov 2018 19:41:35 +0100 Subject: [PATCH] Add and use new singleton class Use a very basic implementation and explicit inst() calls for access --- include/turtle/detail/functor.hpp | 13 +++++---- include/turtle/detail/mutex.hpp | 16 +++++------ include/turtle/detail/object_impl.hpp | 4 +-- include/turtle/detail/root.hpp | 8 +++--- include/turtle/detail/singleton.hpp | 39 +++++++++++++++++++++++++++ include/turtle/mock.hpp | 4 +-- include/turtle/object.hpp | 2 +- include/turtle/reset.hpp | 2 +- include/turtle/verify.hpp | 2 +- test/mock_error.hpp | 33 +++++++++++------------ 10 files changed, 78 insertions(+), 45 deletions(-) create mode 100644 include/turtle/detail/singleton.hpp diff --git a/include/turtle/detail/functor.hpp b/include/turtle/detail/functor.hpp index 232c7c9..54dd9df 100644 --- a/include/turtle/detail/functor.hpp +++ b/include/turtle/detail/functor.hpp @@ -12,36 +12,35 @@ #include "../config.hpp" #include "function.hpp" #include "mutex.hpp" +#include "singleton.hpp" namespace mock { namespace detail { class functor_mutex_t : - public boost::unit_test::singleton< functor_mutex_t >, + public singleton< functor_mutex_t >, public mutex { - private: - BOOST_TEST_SINGLETON_CONS( functor_mutex_t ); + MOCK_SINGLETON_CONS( functor_mutex_t ); }; - BOOST_TEST_SINGLETON_INST( functor_mutex ) template< typename Signature > struct functor : function< Signature > { functor() { - scoped_lock _( functor_mutex ); + scoped_lock _( functor_mutex::inst() ); static functor* f = 0; if( f ) { *this = *f; f = 0; - functor_mutex.unlock(); + functor_mutex::inst().unlock(); } else { - functor_mutex.lock(); + functor_mutex::inst().lock(); f = this; } } diff --git a/include/turtle/detail/mutex.hpp b/include/turtle/detail/mutex.hpp index 4837c6c..12691c3 100644 --- a/include/turtle/detail/mutex.hpp +++ b/include/turtle/detail/mutex.hpp @@ -10,7 +10,7 @@ #define MOCK_MUTEX_HPP_INCLUDED #include "../config.hpp" -#include +#include "singleton.hpp" #include #ifdef MOCK_THREAD_SAFE @@ -93,13 +93,11 @@ namespace mock { 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 { - private: - BOOST_TEST_SINGLETON_CONS( error_mutex_t ); + MOCK_SINGLETON_CONS( error_mutex_t ); }; - BOOST_TEST_SINGLETON_INST( error_mutex ) #ifdef BOOST_MSVC # pragma warning( push ) @@ -110,25 +108,25 @@ namespace detail { static Result abort() { - scoped_lock _( error_mutex ); + scoped_lock _( error_mutex::inst() ); return Error::abort(); } template< typename Context > static void fail( const char* message, const Context& context, const char* file = "unknown location", int line = 0 ) { - scoped_lock _( error_mutex ); + scoped_lock _( error_mutex::inst() ); Error::fail( message, context, file, line ); } template< typename Context > 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 ); } static void pass( const char* file, int line ) { - scoped_lock _( error_mutex ); + scoped_lock _( error_mutex::inst() ); Error::pass( file, line ); } }; diff --git a/include/turtle/detail/object_impl.hpp b/include/turtle/detail/object_impl.hpp index 6aa215f..5679b1c 100644 --- a/include/turtle/detail/object_impl.hpp +++ b/include/turtle/detail/object_impl.hpp @@ -40,7 +40,7 @@ namespace detail { lock _( mutex_ ); if( children_.empty() ) - detail::root.add( *this ); + detail::root::inst().add( *this ); children_[ &v ].update( parent_, instance, type, name ); } virtual void add( verifiable& v ) @@ -54,7 +54,7 @@ namespace detail group_.remove( v ); children_.erase( &v ); if( children_.empty() ) - detail::root.remove( *this ); + detail::root::inst().remove( *this ); } virtual void serialize( std::ostream& s, const verifiable& v ) const diff --git a/include/turtle/detail/root.hpp b/include/turtle/detail/root.hpp index 2006a28..1eed2aa 100644 --- a/include/turtle/detail/root.hpp +++ b/include/turtle/detail/root.hpp @@ -15,7 +15,7 @@ #include "context.hpp" #include "child.hpp" #include "mutex.hpp" -#include +#include "singleton.hpp" #include #include #include @@ -24,7 +24,7 @@ namespace mock { namespace detail { - class root_t : public boost::unit_test::singleton< root_t >, public context + class root_t : public singleton< root_t >, public context { public: virtual void add( const void* p, verifiable& v, @@ -128,10 +128,8 @@ namespace detail group group_; mutable mutex mutex_; - private: - BOOST_TEST_SINGLETON_CONS( root_t ); + MOCK_SINGLETON_CONS( root_t ); }; - BOOST_TEST_SINGLETON_INST( root ) } } // mock diff --git a/include/turtle/detail/singleton.hpp b/include/turtle/detail/singleton.hpp new file mode 100644 index 0000000..7e63bb7 --- /dev/null +++ b/include/turtle/detail/singleton.hpp @@ -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 + +namespace mock { +namespace detail { + +template +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() {} + +} // detail +} // mock + +#endif // MOCK_SINGLETON_HPP \ No newline at end of file diff --git a/include/turtle/mock.hpp b/include/turtle/mock.hpp index 204061d..7eb10b6 100644 --- a/include/turtle/mock.hpp +++ b/include/turtle/mock.hpp @@ -55,9 +55,9 @@ #endif // MOCK_VARIADIC_MACROS #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) \ - t##_mock( mock::detail::root, "?." ) + t##_mock( mock::detail::root::inst(), "?." ) #define MOCK_METHOD_HELPER(S, t, tpn) \ mutable mock::detail::function< MOCK_FUNCTION_TYPE((S), tpn) > t##_mock_; \ diff --git a/include/turtle/object.hpp b/include/turtle/object.hpp index d201757..c309dd1 100644 --- a/include/turtle/object.hpp +++ b/include/turtle/object.hpp @@ -40,7 +40,7 @@ namespace detail typename boost::is_base_of< object, T > >::type* = 0 ) { - e.configure( detail::root, &t, instance, type, name ); + e.configure( detail::root::inst(), &t, instance, type, name ); return e; } } diff --git a/include/turtle/reset.hpp b/include/turtle/reset.hpp index 20237b9..828db29 100644 --- a/include/turtle/reset.hpp +++ b/include/turtle/reset.hpp @@ -18,7 +18,7 @@ namespace mock { inline void reset() { - detail::root.reset(); + detail::root::inst().reset(); } inline void reset( const object& o ) { diff --git a/include/turtle/verify.hpp b/include/turtle/verify.hpp index 61df6df..e40d7c2 100644 --- a/include/turtle/verify.hpp +++ b/include/turtle/verify.hpp @@ -18,7 +18,7 @@ namespace mock { inline bool verify() { - return detail::root.verify(); + return detail::root::inst().verify(); } inline bool verify( const object& o ) { diff --git a/test/mock_error.hpp b/test/mock_error.hpp index ae95ca8..f1990bd 100644 --- a/test/mock_error.hpp +++ b/test/mock_error.hpp @@ -10,12 +10,12 @@ #define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED #define MOCK_ERROR_POLICY mock_error +#include #include #include -#include #include -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() { @@ -52,10 +52,9 @@ struct mock_error_data_t : boost::unit_test::singleton< mock_error_data_t > std::string last_context; std::string last_file; 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 > struct mock_error @@ -72,14 +71,14 @@ struct mock_error static void call( const Context& /*context*/, const char* /*file*/, int /*line*/ ) { - mock_error_data.call(); + mock_error_data::inst().call(); } template< typename Context > static void fail( const std::string& message, const Context& context, 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 ); } }; @@ -88,25 +87,25 @@ struct mock_error_fixture { mock_error_fixture() { - mock_error_data.reset(); + mock_error_data::inst().reset(); } ~mock_error_fixture() { - BOOST_CHECK( mock_error_data.verify() ); - BOOST_CHECK_EQUAL( 0, mock_error_data.call_count ); + BOOST_CHECK( mock_error_data::inst().verify() ); + BOOST_CHECK_EQUAL( 0, mock_error_data::inst().call_count ); } }; #define CHECK_CALLS( calls ) \ - BOOST_CHECK_EQUAL( calls, mock_error_data.call_count ); \ - mock_error_data.call_count = 0; + BOOST_CHECK_EQUAL( calls, mock_error_data::inst().call_count ); \ + mock_error_data::inst().call_count = 0; #define CHECK_ERROR( expr, error, calls, context ) \ - BOOST_CHECK( mock_error_data.verify() ); \ + BOOST_CHECK( mock_error_data::inst().verify() ); \ try { expr; } catch( ... ) {} \ - BOOST_CHECK_EQUAL( 1, mock_error_data.error_count ); \ - BOOST_CHECK_EQUAL( error, mock_error_data.last_message ); \ - BOOST_CHECK_EQUAL( context, mock_error_data.last_context ); \ + BOOST_CHECK_EQUAL( 1, mock_error_data::inst().error_count ); \ + BOOST_CHECK_EQUAL( error, mock_error_data::inst().last_message ); \ + BOOST_CHECK_EQUAL( context, mock_error_data::inst().last_context ); \ CHECK_CALLS( calls ); \ - mock_error_data.reset(); + mock_error_data::inst().reset(); #endif // MOCK_TEST_MOCK_ERROR_HPP_INCLUDED