Make is_executor<> trait automatic.
diff --git a/asio/include/asio/bind_executor.hpp b/asio/include/asio/bind_executor.hpp
index 562ce18..f74a8e3 100644
--- a/asio/include/asio/bind_executor.hpp
+++ b/asio/include/asio/bind_executor.hpp
@@ -21,6 +21,7 @@
 #include "asio/associated_allocator.hpp"
 #include "asio/async_result.hpp"
 #include "asio/handler_type.hpp"
+#include "asio/is_executor.hpp"
 #include "asio/uses_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
@@ -166,27 +167,27 @@
 protected:
   template <typename E, typename U>
   executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)
-    : Executor(ASIO_MOVE_CAST(E)(e)),
-      target_(executor_arg_t(), static_cast<const Executor&>(*this),
-          ASIO_MOVE_CAST(U)(u))
+    : executor_(ASIO_MOVE_CAST(E)(e)),
+      target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u))
   {
   }
 
+  Executor executor_;
   T target_;
 };
 
 template <typename T, typename Executor>
 class executor_binder_base<T, Executor, false>
-  : protected Executor
 {
 protected:
   template <typename E, typename U>
   executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)
-    : Executor(ASIO_MOVE_CAST(E)(e)),
+    : executor_(ASIO_MOVE_CAST(E)(e)),
       target_(ASIO_MOVE_CAST(U)(u))
   {
   }
 
+  Executor executor_;
   T target_;
 };
 
@@ -393,7 +394,7 @@
   /// Obtain the associated executor.
   executor_type get_executor() const ASIO_NOEXCEPT
   {
-    return static_cast<const Executor&>(*this);
+    return this->executor_;
   }
 
 #if defined(GENERATING_DOCUMENTATION)
diff --git a/asio/include/asio/detail/is_executor.hpp b/asio/include/asio/detail/is_executor.hpp
new file mode 100644
index 0000000..e5f57b1
--- /dev/null
+++ b/asio/include/asio/detail/is_executor.hpp
@@ -0,0 +1,126 @@
+//
+// detail/is_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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 ASIO_DETAIL_IS_EXECUTOR_HPP
+#define ASIO_DETAIL_IS_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/detail/type_traits.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace detail {
+
+struct executor_memfns_base
+{
+  void context();
+  void on_work_started();
+  void on_work_finished();
+  void dispatch();
+  void post();
+  void defer();
+};
+
+template <typename T>
+struct executor_memfns_derived
+  : T, executor_memfns_base
+{
+};
+
+template <typename T, T>
+struct executor_memfns_check
+{
+};
+
+template <typename>
+char (&context_memfn_helper(...))[2];
+
+template <typename T>
+char context_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::context>*);
+
+template <typename>
+char (&on_work_started_memfn_helper(...))[2];
+
+template <typename T>
+char on_work_started_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::on_work_started>*);
+
+template <typename>
+char (&on_work_finished_memfn_helper(...))[2];
+
+template <typename T>
+char on_work_finished_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::on_work_finished>*);
+
+template <typename>
+char (&dispatch_memfn_helper(...))[2];
+
+template <typename T>
+char dispatch_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::dispatch>*);
+
+template <typename>
+char (&post_memfn_helper(...))[2];
+
+template <typename T>
+char post_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::post>*);
+
+template <typename>
+char (&defer_memfn_helper(...))[2];
+
+template <typename T>
+char defer_memfn_helper(
+    executor_memfns_check<
+      void (executor_memfns_base::*)(),
+      &executor_memfns_derived<T>::defer>*);
+
+template <typename T>
+struct is_executor_class
+  : integral_constant<bool,
+      sizeof(context_memfn_helper<T>(0)) != 1 &&
+      sizeof(on_work_started_memfn_helper<T>(0)) != 1 &&
+      sizeof(on_work_finished_memfn_helper<T>(0)) != 1 &&
+      sizeof(dispatch_memfn_helper<T>(0)) != 1 &&
+      sizeof(post_memfn_helper<T>(0)) != 1 &&
+      sizeof(defer_memfn_helper<T>(0)) != 1>
+{
+};
+
+template <typename T>
+struct is_executor
+  : conditional<is_class<T>::value,
+      is_executor_class<T>,
+      false_type>::type
+{
+};
+
+} // namespace detail
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_DETAIL_IS_EXECUTOR_HPP
diff --git a/asio/include/asio/executor.hpp b/asio/include/asio/executor.hpp
index d1d6fd3..928c6be 100644
--- a/asio/include/asio/executor.hpp
+++ b/asio/include/asio/executor.hpp
@@ -21,7 +21,6 @@
 #include "asio/detail/memory.hpp"
 #include "asio/detail/throw_exception.hpp"
 #include "asio/execution_context.hpp"
-#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -328,10 +327,6 @@
 #endif // !defined(GENERATING_DOCUMENTATION)
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <> struct is_executor<executor> : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
 } // namespace asio
 
 ASIO_USES_ALLOCATOR(asio::executor)
diff --git a/asio/include/asio/executor_work_guard.hpp b/asio/include/asio/executor_work_guard.hpp
index 5774d21..1906af8 100644
--- a/asio/include/asio/executor_work_guard.hpp
+++ b/asio/include/asio/executor_work_guard.hpp
@@ -18,6 +18,7 @@
 #include "asio/detail/config.hpp"
 #include "asio/associated_executor.hpp"
 #include "asio/detail/type_traits.hpp"
+#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
diff --git a/asio/include/asio/io_context.hpp b/asio/include/asio/io_context.hpp
index 96a0a33..f18414d 100644
--- a/asio/include/asio/io_context.hpp
+++ b/asio/include/asio/io_context.hpp
@@ -24,7 +24,6 @@
 #include "asio/detail/wrapped_handler.hpp"
 #include "asio/error_code.hpp"
 #include "asio/execution_context.hpp"
-#include "asio/is_executor.hpp"
 
 #if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
 # include "asio/detail/winsock_init.hpp"
@@ -611,11 +610,6 @@
   io_context& io_context_;
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <> struct is_executor<io_context::executor_type> : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
-
 /// (Deprecated: Use executor_work_guard.) Class to inform the io_context when
 /// it has work to do.
 /**
diff --git a/asio/include/asio/io_context_strand.hpp b/asio/include/asio/io_context_strand.hpp
index 8fe6c14..78bb854 100644
--- a/asio/include/asio/io_context_strand.hpp
+++ b/asio/include/asio/io_context_strand.hpp
@@ -370,11 +370,6 @@
   asio::detail::strand_service::implementation_type impl_;
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <>
-struct is_executor<io_context::strand> : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
diff --git a/asio/include/asio/is_executor.hpp b/asio/include/asio/is_executor.hpp
index 59981ad..10f7d24 100644
--- a/asio/include/asio/is_executor.hpp
+++ b/asio/include/asio/is_executor.hpp
@@ -16,7 +16,7 @@
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
 #include "asio/detail/config.hpp"
-#include "asio/detail/type_traits.hpp"
+#include "asio/detail/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -25,13 +25,19 @@
 /// The is_executor trait detects whether a type T meets the Executor type
 /// requirements.
 /**
- * Meets the UnaryTypeTrait requirements. The asio library implementation
- * provides a definition that is derived from false_type. A program may
- * specialise this template to derive from true_type for a user-defined type T
- * that meets the Executor requirements.
+ * Class template @c is_executor is a UnaryTypeTrait that is derived from @c
+ * true_type if the type @c T meets the syntactic requirements for Executor,
+ * otherwise @c false_type.
  */
 template <typename T>
-struct is_executor : false_type {};
+struct is_executor
+#if defined(GENERATING_DOCUMENTATION)
+  : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+  : asio::detail::is_executor<T>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
 
 } // namespace asio
 
diff --git a/asio/include/asio/strand.hpp b/asio/include/asio/strand.hpp
index 488b540..17a5ffc 100644
--- a/asio/include/asio/strand.hpp
+++ b/asio/include/asio/strand.hpp
@@ -18,7 +18,6 @@
 #include "asio/detail/config.hpp"
 #include "asio/detail/strand_executor_service.hpp"
 #include "asio/detail/type_traits.hpp"
-#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -272,11 +271,6 @@
   implementation_type impl_;
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <typename Executor>
-struct is_executor<strand<Executor> > : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
diff --git a/asio/include/asio/system_executor.hpp b/asio/include/asio/system_executor.hpp
index e227687..73180fd 100644
--- a/asio/include/asio/system_executor.hpp
+++ b/asio/include/asio/system_executor.hpp
@@ -19,7 +19,6 @@
 #include "asio/detail/scheduler.hpp"
 #include "asio/detail/thread_group.hpp"
 #include "asio/execution_context.hpp"
-#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -142,10 +141,6 @@
   };
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <> struct is_executor<system_executor> : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
diff --git a/asio/include/asio/thread_pool.hpp b/asio/include/asio/thread_pool.hpp
index f3182bf..f193506 100644
--- a/asio/include/asio/thread_pool.hpp
+++ b/asio/include/asio/thread_pool.hpp
@@ -20,7 +20,6 @@
 #include "asio/detail/scheduler.hpp"
 #include "asio/detail/thread_group.hpp"
 #include "asio/execution_context.hpp"
-#include "asio/is_executor.hpp"
 
 #include "asio/detail/push_options.hpp"
 
@@ -191,10 +190,6 @@
   thread_pool& pool_;
 };
 
-#if !defined(GENERATING_DOCUMENTATION)
-template <> struct is_executor<thread_pool::executor_type> : true_type {};
-#endif // !defined(GENERATING_DOCUMENTATION)
-
 } // namespace asio
 
 #include "asio/detail/pop_options.hpp"
diff --git a/asio/src/examples/cpp11/executors/fork_join.cpp b/asio/src/examples/cpp11/executors/fork_join.cpp
index f9dcdb3..c996124 100644
--- a/asio/src/examples/cpp11/executors/fork_join.cpp
+++ b/asio/src/examples/cpp11/executors/fork_join.cpp
@@ -252,10 +252,6 @@
   std::shared_ptr<std::size_t> work_count_;
 };
 
-namespace asio {
-  template <> struct is_executor<fork_executor> : std::true_type {};
-}
-
 // Helper class to automatically join a fork_executor when exiting a scope.
 class join_guard
 {
diff --git a/asio/src/examples/cpp11/executors/pipeline.cpp b/asio/src/examples/cpp11/executors/pipeline.cpp
index 4159333..a851e98 100644
--- a/asio/src/examples/cpp11/executors/pipeline.cpp
+++ b/asio/src/examples/cpp11/executors/pipeline.cpp
@@ -101,10 +101,6 @@
 
 execution_context::id thread_executor::thread_bag::id;
 
-namespace asio {
-  template <> struct is_executor<thread_executor> : std::true_type {};
-}
-
 // Base class for all thread-safe queue implementations.
 class queue_impl_base
 {
diff --git a/asio/src/examples/cpp11/executors/priority_scheduler.cpp b/asio/src/examples/cpp11/executors/priority_scheduler.cpp
index 34bb503..c98dd1d 100644
--- a/asio/src/examples/cpp11/executors/priority_scheduler.cpp
+++ b/asio/src/examples/cpp11/executors/priority_scheduler.cpp
@@ -145,10 +145,6 @@
   bool stopped_ = false;
 };
 
-namespace asio {
-  template <> struct is_executor<priority_scheduler::executor_type> : std::true_type {};
-}
-
 int main()
 {
   priority_scheduler sched;
diff --git a/asio/src/examples/cpp14/executors/fork_join.cpp b/asio/src/examples/cpp14/executors/fork_join.cpp
index 918376b..a0cafd6 100644
--- a/asio/src/examples/cpp14/executors/fork_join.cpp
+++ b/asio/src/examples/cpp14/executors/fork_join.cpp
@@ -251,10 +251,6 @@
   std::shared_ptr<std::size_t> work_count_;
 };
 
-namespace asio {
-  template <> struct is_executor<fork_executor> : std::true_type {};
-}
-
 // Helper class to automatically join a fork_executor when exiting a scope.
 class join_guard
 {
diff --git a/asio/src/examples/cpp14/executors/pipeline.cpp b/asio/src/examples/cpp14/executors/pipeline.cpp
index 77a5c0a..1bee173 100644
--- a/asio/src/examples/cpp14/executors/pipeline.cpp
+++ b/asio/src/examples/cpp14/executors/pipeline.cpp
@@ -96,10 +96,6 @@
 
 execution_context::id thread_executor::thread_bag::id;
 
-namespace asio {
-  template <> struct is_executor<thread_executor> : std::true_type {};
-}
-
 // Base class for all thread-safe queue implementations.
 class queue_impl_base
 {
diff --git a/asio/src/examples/cpp14/executors/priority_scheduler.cpp b/asio/src/examples/cpp14/executors/priority_scheduler.cpp
index 3766508..ae2ea18 100644
--- a/asio/src/examples/cpp14/executors/priority_scheduler.cpp
+++ b/asio/src/examples/cpp14/executors/priority_scheduler.cpp
@@ -144,10 +144,6 @@
   bool stopped_ = false;
 };
 
-namespace asio {
-  template <> struct is_executor<priority_scheduler::executor_type> : std::true_type {};
-}
-
 int main()
 {
   priority_scheduler sched;