Add support for service identification using the key_type typedef.
diff --git a/asio/include/asio/detail/impl/service_registry.hpp b/asio/include/asio/detail/impl/service_registry.hpp
index efa4733..bba1540 100644
--- a/asio/include/asio/detail/impl/service_registry.hpp
+++ b/asio/include/asio/detail/impl/service_registry.hpp
@@ -24,7 +24,7 @@
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 @@
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 @@
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 @@
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>);
diff --git a/asio/include/asio/detail/impl/service_registry.ipp b/asio/include/asio/detail/impl/service_registry.ipp
index 39dad4d..51dfa94 100644
--- a/asio/include/asio/detail/impl/service_registry.ipp
+++ b/asio/include/asio/detail/impl/service_registry.ipp
@@ -84,7 +84,7 @@
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;
diff --git a/asio/include/asio/detail/service_registry.hpp b/asio/include/asio/detail/service_registry.hpp
index 77af51b..babaec8 100644
--- a/asio/include/asio/detail/service_registry.hpp
+++ b/asio/include/asio/detail/service_registry.hpp
@@ -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 @@
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)
diff --git a/asio/include/asio/detail/type_traits.hpp b/asio/include/asio/detail/type_traits.hpp
index e7e65a8..f7afda6 100644
--- a/asio/include/asio/detail/type_traits.hpp
+++ b/asio/include/asio/detail/type_traits.hpp
@@ -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::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::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;
diff --git a/asio/include/asio/impl/execution_context.hpp b/asio/include/asio/impl/execution_context.hpp
index 06c64ad..69b9604 100644
--- a/asio/include/asio/impl/execution_context.hpp
+++ b/asio/include/asio/impl/execution_context.hpp
@@ -28,7 +28,6 @@
{
// 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 @@
{
// 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 @@
{
// 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>();
}
diff --git a/asio/src/examples/cpp11/executors/pipeline.cpp b/asio/src/examples/cpp11/executors/pipeline.cpp
index 168fbf3..86bf860 100644
--- a/asio/src/examples/cpp11/executors/pipeline.cpp
+++ b/asio/src/examples/cpp11/executors/pipeline.cpp
@@ -29,7 +29,7 @@
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 @@
}
};
-execution_context::id thread_executor::thread_bag::id;
-
// Base class for all thread-safe queue implementations.
class queue_impl_base
{
diff --git a/asio/src/examples/cpp14/executors/pipeline.cpp b/asio/src/examples/cpp14/executors/pipeline.cpp
index 4ee372e..12c2bef 100644
--- a/asio/src/examples/cpp14/executors/pipeline.cpp
+++ b/asio/src/examples/cpp14/executors/pipeline.cpp
@@ -24,7 +24,7 @@
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 @@
}
};
-execution_context::id thread_executor::thread_bag::id;
-
// Base class for all thread-safe queue implementations.
class queue_impl_base
{