forked from boostorg/beast
247 lines
5.4 KiB
C++
247 lines
5.4 KiB
C++
//
|
|
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail 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)
|
|
//
|
|
// Official repository: https://github.com/boostorg/beast
|
|
//
|
|
|
|
#ifndef BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
|
#define BOOST_BEAST_TEST_HANDLER_XXX_HPP
|
|
|
|
#include <boost/beast/core/detail/config.hpp>
|
|
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
|
#include <boost/asio/associated_allocator.hpp>
|
|
#include <boost/asio/associated_executor.hpp>
|
|
#include <boost/asio/handler_alloc_hook.hpp>
|
|
#include <boost/asio/handler_continuation_hook.hpp>
|
|
#include <boost/asio/handler_invoke_hook.hpp>
|
|
|
|
namespace boost {
|
|
namespace beast {
|
|
|
|
class simple_allocator
|
|
{
|
|
std::size_t id_;
|
|
|
|
public:
|
|
simple_allocator()
|
|
: id_([]
|
|
{
|
|
static std::size_t n = 0;
|
|
return ++n;
|
|
}())
|
|
{
|
|
}
|
|
|
|
friend
|
|
bool operator==(
|
|
simple_allocator const& lhs,
|
|
simple_allocator const& rhs) noexcept
|
|
{
|
|
return lhs.id_ == rhs.id_;
|
|
}
|
|
|
|
friend
|
|
bool operator!=(
|
|
simple_allocator const& lhs,
|
|
simple_allocator const& rhs) noexcept
|
|
{
|
|
return lhs.id_ != rhs.id_;
|
|
}
|
|
};
|
|
|
|
class simple_executor
|
|
{
|
|
std::size_t id_;
|
|
|
|
public:
|
|
simple_executor() noexcept
|
|
: id_([]
|
|
{
|
|
static std::size_t n = 0;
|
|
return ++n;
|
|
}())
|
|
{
|
|
}
|
|
|
|
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
|
void* query(net::execution::context_t) const { return nullptr; }
|
|
template<class F>
|
|
void execute(F&&) const {}
|
|
simple_executor prefer(net::execution::outstanding_work_t::tracked_t) const { return *this; }
|
|
#else
|
|
void* context() { return nullptr; }
|
|
void on_work_started() {}
|
|
void on_work_finished() {}
|
|
template<class F> void dispatch(F&&) {}
|
|
template<class F> void post(F&&) {}
|
|
template<class F> void defer(F&&) {}
|
|
#endif
|
|
|
|
friend
|
|
bool operator==(
|
|
simple_executor const& lhs,
|
|
simple_executor const& rhs) noexcept
|
|
{
|
|
return lhs.id_ == rhs.id_;
|
|
}
|
|
|
|
friend
|
|
bool operator!=(
|
|
simple_executor const& lhs,
|
|
simple_executor const& rhs) noexcept
|
|
{
|
|
return lhs.id_ != rhs.id_;
|
|
}
|
|
};
|
|
|
|
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
|
BOOST_STATIC_ASSERT(net::execution::is_executor<simple_executor>::value);
|
|
#endif
|
|
|
|
// A move-only handler
|
|
struct move_only_handler
|
|
{
|
|
move_only_handler() = default;
|
|
move_only_handler(move_only_handler&&) = default;
|
|
move_only_handler(move_only_handler const&) = delete;
|
|
void operator()() const{};
|
|
};
|
|
|
|
// Used to test the legacy handler hooks
|
|
struct legacy_handler
|
|
{
|
|
bool& hook_invoked;
|
|
|
|
simple_executor
|
|
get_executor() const noexcept
|
|
{
|
|
return {};
|
|
};
|
|
|
|
// Signature of `f` is H<legacy_handler> where H is the wrapper to test
|
|
template<class F>
|
|
static
|
|
void
|
|
test(F const& f)
|
|
{
|
|
#if !defined(BOOST_ASIO_NO_DEPRECATED)
|
|
{
|
|
bool hook_invoked = false;
|
|
bool lambda_invoked = false;
|
|
auto h = f(legacy_handler{hook_invoked});
|
|
using net::asio_handler_invoke;
|
|
asio_handler_invoke(
|
|
[&lambda_invoked]
|
|
{
|
|
lambda_invoked =true;
|
|
}, &h);
|
|
BEAST_EXPECT(hook_invoked);
|
|
BEAST_EXPECT(lambda_invoked);
|
|
}
|
|
{
|
|
bool hook_invoked = false;
|
|
auto h = f(legacy_handler{hook_invoked});
|
|
using net::asio_handler_allocate;
|
|
asio_handler_allocate(0, &h);
|
|
BEAST_EXPECT(hook_invoked);
|
|
}
|
|
{
|
|
bool hook_invoked = false;
|
|
auto h = f(legacy_handler{hook_invoked});
|
|
using net::asio_handler_deallocate;
|
|
asio_handler_deallocate(nullptr, 0, &h);
|
|
BEAST_EXPECT(hook_invoked);
|
|
}
|
|
{
|
|
bool hook_invoked = false;
|
|
auto h = f(legacy_handler{hook_invoked});
|
|
using net::asio_handler_is_continuation;
|
|
asio_handler_is_continuation(&h);
|
|
BEAST_EXPECT(hook_invoked);
|
|
}
|
|
#else // !defined(BOOST_ASIO_NO_DEPRECATED)
|
|
boost::ignore_unused(f);
|
|
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
|
|
}
|
|
};
|
|
|
|
template<class Function>
|
|
void
|
|
asio_handler_invoke(
|
|
Function&& f,
|
|
legacy_handler* p)
|
|
{
|
|
p->hook_invoked = true;
|
|
f();
|
|
}
|
|
|
|
inline
|
|
void*
|
|
asio_handler_allocate(
|
|
std::size_t,
|
|
legacy_handler* p)
|
|
{
|
|
p->hook_invoked = true;
|
|
return nullptr;
|
|
}
|
|
|
|
inline
|
|
void
|
|
asio_handler_deallocate(
|
|
void*, std::size_t,
|
|
legacy_handler* p)
|
|
{
|
|
p->hook_invoked = true;
|
|
}
|
|
|
|
inline
|
|
bool
|
|
asio_handler_is_continuation(
|
|
legacy_handler* p)
|
|
{
|
|
p->hook_invoked = true;
|
|
return false;
|
|
}
|
|
|
|
} // beast
|
|
} // boost
|
|
|
|
namespace boost {
|
|
namespace asio {
|
|
|
|
template<class Allocator>
|
|
struct associated_allocator<
|
|
boost::beast::legacy_handler, Allocator>
|
|
{
|
|
using type = std::allocator<int>;
|
|
|
|
static type get(
|
|
boost::beast::legacy_handler const&,
|
|
Allocator const& = Allocator()) noexcept
|
|
{
|
|
return type{};
|
|
}
|
|
};
|
|
|
|
template<class Executor>
|
|
struct associated_executor<
|
|
boost::beast::legacy_handler, Executor>
|
|
{
|
|
using type = boost::beast::simple_executor;
|
|
|
|
static type get(
|
|
boost::beast::legacy_handler const&,
|
|
Executor const& = Executor()) noexcept
|
|
{
|
|
return type{};
|
|
}
|
|
};
|
|
|
|
} // asio
|
|
} // boost
|
|
|
|
#endif
|