2
0
mirror of https://github.com/boostorg/asio.git synced 2026-03-05 02:42:26 +00:00

Add associator trait.

The associator trait is used to generically forward associators, such as
associated_executor<> and associated_allocator<>, through intermediate
completion handlers. For example:

    template <typename Handler>
    struct intermediate_handler
    {
      Handler handler_;

      template <typename... Args>
      void operator()(Args&... args)
      {
        // ...
      }
    };

    namespace boost {
    namespace asio {

      template <
          template <typename, typename> class Associator,
          typename Handler,
          typename DefaultCandidate>
      struct associator<
          Associator,
          intermediate_handler<Handler>,
          DefaultCandidate>
      {
        using type =
          typename Associator<Handler, DefaultCandidate>::type;

        static type get(
            const intermediate_handler<Handler>& h,
            const DefaultCandidate& c = DefaultCandidate()) noexcept
        {
          return Associator<Handler, DefaultCandidate>::get(
              h.handler_, c);
        }
      };

    } // namespace asio
    } // namespace boost
This commit is contained in:
Christopher Kohlhoff
2021-06-05 15:58:26 +10:00
parent 9dfb1ab677
commit e618857ff3
4 changed files with 96 additions and 2 deletions

View File

@@ -19,6 +19,7 @@
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/associator.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/basic_datagram_socket.hpp>

View File

@@ -17,6 +17,7 @@
#include <boost/asio/detail/config.hpp>
#include <memory>
#include <boost/asio/associator.hpp>
#include <boost/asio/detail/functional.hpp>
#include <boost/asio/detail/type_traits.hpp>
@@ -24,9 +25,25 @@
namespace boost {
namespace asio {
template <typename T, typename Allocator>
struct associated_allocator;
namespace detail {
template <typename T, typename E, typename = void>
template <typename T, typename = void>
struct has_allocator_type : false_type
{
};
template <typename T>
struct has_allocator_type<T,
typename void_type<typename T::executor_type>::type>
: true_type
{
};
template <typename T, typename E, typename = void, typename = void>
struct associated_allocator_impl
{
typedef E type;
@@ -49,6 +66,17 @@ struct associated_allocator_impl<T, E,
}
};
template <typename T, typename E>
struct associated_allocator_impl<T, E,
typename enable_if<
!has_allocator_type<T>::value
>::type,
typename void_type<
typename associator<associated_allocator, T, E>::type
>::type> : associator<associated_allocator, T, E>
{
};
} // namespace detail
/// Traits type used to obtain the allocator associated with an object.

View File

@@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/associator.hpp>
#include <boost/asio/detail/functional.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/execution/executor.hpp>
@@ -26,9 +27,25 @@
namespace boost {
namespace asio {
template <typename T, typename Executor>
struct associated_executor;
namespace detail {
template <typename T, typename E, typename = void>
template <typename T, typename = void>
struct has_executor_type : false_type
{
};
template <typename T>
struct has_executor_type<T,
typename void_type<typename T::executor_type>::type>
: true_type
{
};
template <typename T, typename E, typename = void, typename = void>
struct associated_executor_impl
{
typedef void asio_associated_executor_is_unspecialised;
@@ -53,6 +70,17 @@ struct associated_executor_impl<T, E,
}
};
template <typename T, typename E>
struct associated_executor_impl<T, E,
typename enable_if<
!has_executor_type<T>::value
>::type,
typename void_type<
typename associator<associated_executor, T, E>::type
>::type> : associator<associated_executor, T, E>
{
};
} // namespace detail
/// Traits type used to obtain the executor associated with an object.

View File

@@ -0,0 +1,37 @@
//
// associator.hpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 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 BOOST_ASIO_ASSOCIATOR_HPP
#define BOOST_ASIO_ASSOCIATOR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
/// Used to generically specialise associators for a type.
template <template <typename, typename> class Associator,
typename T, typename DefaultCandidate>
struct associator
{
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_ASSOCIATOR_HPP