Add support for service identification using the key_type typedef.

This commit is contained in:
Christopher Kohlhoff 2016-08-20 18:02:32 +10:00
parent 36302fc75b
commit b39b750f4c
7 changed files with 41 additions and 16 deletions

View File

@ -24,7 +24,7 @@ template <typename Service>
Service& service_registry::use_service()
{
execution_context::service::key key;
init_key(key, Service::id);
init_key<Service>(key, 0);
factory_type factory = &service_registry::create<Service, execution_context>;
return *static_cast<Service*>(do_use_service(key, factory, &owner_));
}
@ -33,7 +33,7 @@ template <typename Service>
Service& service_registry::use_service(io_context& owner)
{
execution_context::service::key key;
init_key(key, Service::id);
init_key<Service>(key, 0);
factory_type factory = &service_registry::create<Service, io_context>;
return *static_cast<Service*>(do_use_service(key, factory, &owner));
}
@ -42,7 +42,7 @@ template <typename Service>
void service_registry::add_service(Service* new_service)
{
execution_context::service::key key;
init_key(key, Service::id);
init_key<Service>(key, 0);
return do_add_service(key, new_service);
}
@ -50,13 +50,29 @@ template <typename Service>
bool service_registry::has_service() const
{
execution_context::service::key key;
init_key(key, Service::id);
init_key<Service>(key, 0);
return do_has_service(key);
}
template <typename Service>
inline void service_registry::init_key(
execution_context::service::key& key, ...)
{
init_key_from_id(key, Service::id);
}
#if !defined(ASIO_NO_TYPEID)
template <typename Service>
void service_registry::init_key(execution_context::service::key& key,
typename enable_if<
is_base_of<typename Service::key_type, Service>::value>::type*)
{
key.type_info_ = &typeid(typeid_wrapper<Service>);
key.id_ = 0;
}
template <typename Service>
void service_registry::init_key_from_id(execution_context::service::key& key,
const service_id<Service>& /*id*/)
{
key.type_info_ = &typeid(typeid_wrapper<Service>);

View File

@ -84,7 +84,7 @@ void service_registry::notify_fork(execution_context::fork_event fork_ev)
services[i - 1]->notify_fork(fork_ev);
}
void service_registry::init_key(execution_context::service::key& key,
void service_registry::init_key_from_id(execution_context::service::key& key,
const execution_context::id& id)
{
key.type_info_ = 0;

View File

@ -19,6 +19,7 @@
#include <typeinfo>
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/execution_context.hpp"
#include "asio/detail/push_options.hpp"
@ -75,15 +76,27 @@ public:
bool has_service() const;
private:
// Initalise a service's key when the key_type typedef is not available.
template <typename Service>
static void init_key(execution_context::service::key& key, ...);
#if !defined(ASIO_NO_TYPEID)
// Initalise a service's key when the key_type typedef is available.
template <typename Service>
static void init_key(execution_context::service::key& key,
typename enable_if<
is_base_of<typename Service::key_type, Service>::value>::type*);
#endif // !defined(ASIO_NO_TYPEID)
// Initialise a service's key based on its id.
ASIO_DECL static void init_key(
ASIO_DECL static void init_key_from_id(
execution_context::service::key& key,
const execution_context::id& id);
#if !defined(ASIO_NO_TYPEID)
// Initialise a service's key based on its id.
template <typename Service>
static void init_key(execution_context::service::key& key,
static void init_key_from_id(execution_context::service::key& key,
const service_id<Service>& /*id*/);
#endif // !defined(ASIO_NO_TYPEID)

View File

@ -24,6 +24,7 @@
# include <boost/type_traits/conditional.hpp>
# include <boost/type_traits/decay.hpp>
# include <boost/type_traits/integral_constant.hpp>
# include <boost/type_traits/is_base_of.hpp>
# include <boost/type_traits/is_class.hpp>
# include <boost/type_traits/is_const.hpp>
# include <boost/type_traits/is_convertible.hpp>
@ -44,6 +45,7 @@ using std::decay;
using std::enable_if;
using std::false_type;
using std::integral_constant;
using std::is_base_of;
using std::is_class;
using std::is_const;
using std::is_convertible;
@ -61,6 +63,7 @@ using boost::conditional;
using boost::decay;
using boost::false_type;
using boost::integral_constant;
using boost::is_base_of;
using boost::is_class;
using boost::is_const;
using boost::is_convertible;

View File

@ -28,7 +28,6 @@ inline Service& use_service(execution_context& e)
{
// Check that Service meets the necessary type requirements.
(void)static_cast<execution_context::service*>(static_cast<Service*>(0));
(void)static_cast<const execution_context::id*>(&Service::id);
return e.service_registry_->template use_service<Service>();
}
@ -83,7 +82,6 @@ inline void add_service(execution_context& e, Service* svc)
{
// Check that Service meets the necessary type requirements.
(void)static_cast<execution_context::service*>(static_cast<Service*>(0));
(void)static_cast<const execution_context::id*>(&Service::id);
e.service_registry_->template add_service<Service>(svc);
}
@ -93,7 +91,6 @@ inline bool has_service(execution_context& e)
{
// Check that Service meets the necessary type requirements.
(void)static_cast<execution_context::service*>(static_cast<Service*>(0));
(void)static_cast<const execution_context::id*>(&Service::id);
return e.service_registry_->template has_service<Service>();
}

View File

@ -29,7 +29,7 @@ private:
class thread_bag : public execution_context::service
{
public:
static execution_context::id id;
typedef thread_bag key_type;
explicit thread_bag(execution_context& ctx)
: execution_context::service(ctx)
@ -101,8 +101,6 @@ public:
}
};
execution_context::id thread_executor::thread_bag::id;
// Base class for all thread-safe queue implementations.
class queue_impl_base
{

View File

@ -24,7 +24,7 @@ private:
class thread_bag : public execution_context::service
{
public:
static execution_context::id id;
typedef thread_bag key_type;
explicit thread_bag(execution_context& ctx)
: execution_context::service(ctx)
@ -96,8 +96,6 @@ public:
}
};
execution_context::id thread_executor::thread_bag::id;
// Base class for all thread-safe queue implementations.
class queue_impl_base
{