Skip to content

Commit

Permalink
Use standard placeholders for implementing asio::placeholders.
Browse files Browse the repository at this point in the history
Adds compatibility with both std::bind and boost::bind.
  • Loading branch information
chriskohlhoff committed Oct 28, 2023
1 parent 3a3a8ff commit add946f
Showing 1 changed file with 28 additions and 104 deletions.
132 changes: 28 additions & 104 deletions include/boost/asio/placeholders.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <boost/asio/detail/config.hpp>

#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/arg.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
#include <boost/asio/detail/functional.hpp>

#include <boost/asio/detail/push_options.hpp>

Expand All @@ -29,119 +26,46 @@ namespace placeholders {

#if defined(GENERATING_DOCUMENTATION)

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the error argument of a handler for any of the asynchronous functions.
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the error argument of a handler for any of the asynchronous
/// functions.
unspecified error;

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the bytes_transferred argument of a handler for asynchronous functions such
/// as boost::asio::basic_stream_socket::async_write_some or
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the bytes_transferred argument of a handler for asynchronous
/// functions such as boost::asio::basic_stream_socket::async_write_some or
/// boost::asio::async_write.
unspecified bytes_transferred;

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the iterator argument of a handler for asynchronous functions such as
/// boost::asio::async_connect.
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the iterator argument of a handler for asynchronous functions
/// such as boost::asio::async_connect.
unspecified iterator;

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the results argument of a handler for asynchronous functions such as
/// boost::asio::basic_resolver::async_resolve.
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the results argument of a handler for asynchronous functions
/// such as boost::asio::basic_resolver::async_resolve.
unspecified results;

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the results argument of a handler for asynchronous functions such as
/// boost::asio::async_connect.
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the results argument of a handler for asynchronous functions
/// such as boost::asio::async_connect.
unspecified endpoint;

/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the signal_number argument of a handler for asynchronous functions such as
/// boost::asio::signal_set::async_wait.
/// An argument placeholder, for use with std::bind() or boost::bind(), that
/// corresponds to the signal_number argument of a handler for asynchronous
/// functions such as boost::asio::signal_set::async_wait.
unspecified signal_number;

#elif defined(BOOST_ASIO_HAS_BOOST_BIND)
# if defined(__BORLANDC__) || defined(__GNUC__)

inline boost::arg<1> error()
{
return boost::arg<1>();
}

inline boost::arg<2> bytes_transferred()
{
return boost::arg<2>();
}

inline boost::arg<2> iterator()
{
return boost::arg<2>();
}

inline boost::arg<2> results()
{
return boost::arg<2>();
}

inline boost::arg<2> endpoint()
{
return boost::arg<2>();
}

inline boost::arg<2> signal_number()
{
return boost::arg<2>();
}

# else

namespace detail
{
template <int Number>
struct placeholder
{
static boost::arg<Number>& get()
{
static boost::arg<Number> result;
return result;
}
};
}

# if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC < 1400)

static boost::arg<1>& error
= boost::asio::placeholders::detail::placeholder<1>::get();
static boost::arg<2>& bytes_transferred
= boost::asio::placeholders::detail::placeholder<2>::get();
static boost::arg<2>& iterator
= boost::asio::placeholders::detail::placeholder<2>::get();
static boost::arg<2>& results
= boost::asio::placeholders::detail::placeholder<2>::get();
static boost::arg<2>& endpoint
= boost::asio::placeholders::detail::placeholder<2>::get();
static boost::arg<2>& signal_number
= boost::asio::placeholders::detail::placeholder<2>::get();

# else

namespace
{
boost::arg<1>& error
= boost::asio::placeholders::detail::placeholder<1>::get();
boost::arg<2>& bytes_transferred
= boost::asio::placeholders::detail::placeholder<2>::get();
boost::arg<2>& iterator
= boost::asio::placeholders::detail::placeholder<2>::get();
boost::arg<2>& results
= boost::asio::placeholders::detail::placeholder<2>::get();
boost::arg<2>& endpoint
= boost::asio::placeholders::detail::placeholder<2>::get();
boost::arg<2>& signal_number
= boost::asio::placeholders::detail::placeholder<2>::get();
} // namespace

# endif
# endif
#else

static constexpr auto& error = std::placeholders::_1;
static constexpr auto& bytes_transferred = std::placeholders::_2;
static constexpr auto& iterator = std::placeholders::_2;
static constexpr auto& results = std::placeholders::_2;
static constexpr auto& endpoint = std::placeholders::_2;
static constexpr auto& signal_number = std::placeholders::_2;

#endif

} // namespace placeholders
Expand Down

0 comments on commit add946f

Please sign in to comment.