mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-15 03:38:09 +00:00
Added thirdparty: boost library
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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_DETAIL_ALLOCATOR_HPP
|
||||
#define BOOST_BEAST_DETAIL_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_NO_CXX11_ALLOCATOR
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#else
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// This is a workaround for allocator_traits
|
||||
// implementations which falsely claim C++11
|
||||
// compatibility.
|
||||
|
||||
#ifdef BOOST_NO_CXX11_ALLOCATOR
|
||||
template<class Alloc>
|
||||
using allocator_traits = boost::container::allocator_traits<Alloc>;
|
||||
|
||||
#else
|
||||
template<class Alloc>
|
||||
using allocator_traits = std::allocator_traits<Alloc>;
|
||||
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_ASYNC_BASE_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_ASYNC_BASE_HPP
|
||||
|
||||
#include <boost/core/exchange.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
struct stable_base
|
||||
{
|
||||
static
|
||||
void
|
||||
destroy_list(stable_base*& list)
|
||||
{
|
||||
while(list)
|
||||
{
|
||||
auto next = list->next_;
|
||||
list->destroy();
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
|
||||
stable_base* next_ = nullptr;
|
||||
|
||||
protected:
|
||||
stable_base() = default;
|
||||
virtual ~stable_base() = default;
|
||||
|
||||
virtual void destroy() = 0;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// 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_DETAIL_BASE64_HPP
|
||||
#define BOOST_BEAST_DETAIL_BASE64_HPP
|
||||
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <cctype>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
namespace base64 {
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
char const*
|
||||
get_alphabet();
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
signed char const*
|
||||
get_inverse();
|
||||
|
||||
/// Returns max chars needed to encode a base64 string
|
||||
BOOST_BEAST_DECL
|
||||
std::size_t constexpr
|
||||
encoded_size(std::size_t n)
|
||||
{
|
||||
return 4 * ((n + 2) / 3);
|
||||
}
|
||||
|
||||
/// Returns max bytes needed to decode a base64 string
|
||||
inline
|
||||
std::size_t constexpr
|
||||
decoded_size(std::size_t n)
|
||||
{
|
||||
return n / 4 * 3; // requires n&3==0, smaller
|
||||
}
|
||||
|
||||
/** Encode a series of octets as a padded, base64 string.
|
||||
|
||||
The resulting string will not be null terminated.
|
||||
|
||||
@par Requires
|
||||
|
||||
The memory pointed to by `out` points to valid memory
|
||||
of at least `encoded_size(len)` bytes.
|
||||
|
||||
@return The number of characters written to `out`. This
|
||||
will exclude any null termination.
|
||||
*/
|
||||
BOOST_BEAST_DECL
|
||||
std::size_t
|
||||
encode(void* dest, void const* src, std::size_t len);
|
||||
|
||||
/** Decode a padded base64 string into a series of octets.
|
||||
|
||||
@par Requires
|
||||
|
||||
The memory pointed to by `out` points to valid memory
|
||||
of at least `decoded_size(len)` bytes.
|
||||
|
||||
@return The number of octets written to `out`, and
|
||||
the number of characters read from the input string,
|
||||
expressed as a pair.
|
||||
*/
|
||||
BOOST_BEAST_DECL
|
||||
std::pair<std::size_t, std::size_t>
|
||||
decode(void* dest, char const* src, std::size_t len);
|
||||
|
||||
} // base64
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_BEAST_HEADER_ONLY
|
||||
#include <boost/beast/core/detail/base64.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
/*
|
||||
Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
|
||||
Copyright notice:
|
||||
|
||||
base64.cpp and base64.h
|
||||
|
||||
Copyright (C) 2004-2008 Rene Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
*/
|
||||
|
||||
#ifndef BOOST_BEAST_DETAIL_BASE64_IPP
|
||||
#define BOOST_BEAST_DETAIL_BASE64_IPP
|
||||
|
||||
#include <boost/beast/core/detail/base64.hpp>
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
namespace base64 {
|
||||
|
||||
char const*
|
||||
get_alphabet()
|
||||
{
|
||||
static char constexpr tab[] = {
|
||||
"ABCDEFGHIJKLMNOP"
|
||||
"QRSTUVWXYZabcdef"
|
||||
"ghijklmnopqrstuv"
|
||||
"wxyz0123456789+/"
|
||||
};
|
||||
return &tab[0];
|
||||
}
|
||||
|
||||
signed char const*
|
||||
get_inverse()
|
||||
{
|
||||
static signed char constexpr tab[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
|
||||
};
|
||||
return &tab[0];
|
||||
}
|
||||
|
||||
/** Encode a series of octets as a padded, base64 string.
|
||||
|
||||
The resulting string will not be null terminated.
|
||||
|
||||
@par Requires
|
||||
|
||||
The memory pointed to by `out` points to valid memory
|
||||
of at least `encoded_size(len)` bytes.
|
||||
|
||||
@return The number of characters written to `out`. This
|
||||
will exclude any null termination.
|
||||
*/
|
||||
std::size_t
|
||||
encode(void* dest, void const* src, std::size_t len)
|
||||
{
|
||||
char* out = static_cast<char*>(dest);
|
||||
char const* in = static_cast<char const*>(src);
|
||||
auto const tab = base64::get_alphabet();
|
||||
|
||||
for(auto n = len / 3; n--;)
|
||||
{
|
||||
*out++ = tab[ (in[0] & 0xfc) >> 2];
|
||||
*out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
|
||||
*out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
|
||||
*out++ = tab[ in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
|
||||
switch(len % 3)
|
||||
{
|
||||
case 2:
|
||||
*out++ = tab[ (in[0] & 0xfc) >> 2];
|
||||
*out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
|
||||
*out++ = tab[ (in[1] & 0x0f) << 2];
|
||||
*out++ = '=';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*out++ = tab[ (in[0] & 0xfc) >> 2];
|
||||
*out++ = tab[((in[0] & 0x03) << 4)];
|
||||
*out++ = '=';
|
||||
*out++ = '=';
|
||||
break;
|
||||
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
return out - static_cast<char*>(dest);
|
||||
}
|
||||
|
||||
/** Decode a padded base64 string into a series of octets.
|
||||
|
||||
@par Requires
|
||||
|
||||
The memory pointed to by `out` points to valid memory
|
||||
of at least `decoded_size(len)` bytes.
|
||||
|
||||
@return The number of octets written to `out`, and
|
||||
the number of characters read from the input string,
|
||||
expressed as a pair.
|
||||
*/
|
||||
std::pair<std::size_t, std::size_t>
|
||||
decode(void* dest, char const* src, std::size_t len)
|
||||
{
|
||||
char* out = static_cast<char*>(dest);
|
||||
auto in = reinterpret_cast<unsigned char const*>(src);
|
||||
unsigned char c3[3], c4[4] = {0,0,0,0};
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
auto const inverse = base64::get_inverse();
|
||||
|
||||
while(len-- && *in != '=')
|
||||
{
|
||||
auto const v = inverse[*in];
|
||||
if(v == -1)
|
||||
break;
|
||||
++in;
|
||||
c4[i] = v;
|
||||
if(++i == 4)
|
||||
{
|
||||
c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
|
||||
c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
|
||||
c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
*out++ = c3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(i)
|
||||
{
|
||||
c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
|
||||
c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
|
||||
c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
|
||||
|
||||
for(j = 0; j < i - 1; j++)
|
||||
*out++ = c3[j];
|
||||
}
|
||||
|
||||
return {out - static_cast<char*>(dest),
|
||||
in - reinterpret_cast<unsigned char const*>(src)};
|
||||
}
|
||||
|
||||
} // base64
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// 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_DETAIL_BIND_CONTINUATION_HPP
|
||||
#define BOOST_BEAST_DETAIL_BIND_CONTINUATION_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/detail/remap_post_to_defer.hpp>
|
||||
#include <boost/asio/bind_executor.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
#if 0
|
||||
/** Mark a completion handler as a continuation.
|
||||
|
||||
This function wraps a completion handler to associate it with an
|
||||
executor whose `post` operation is remapped to the `defer` operation.
|
||||
It is used by composed asynchronous operation implementations to
|
||||
indicate that a completion handler submitted to an initiating
|
||||
function represents a continuation of the current asynchronous
|
||||
flow of control.
|
||||
|
||||
@param handler The handler to wrap.
|
||||
The implementation takes ownership of the handler by performing a decay-copy.
|
||||
|
||||
@see
|
||||
|
||||
@li <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4242.html">[N4242] Executors and Asynchronous Operations, Revision 1</a>
|
||||
*/
|
||||
template<class CompletionHandler>
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
__implementation_defined__
|
||||
#else
|
||||
net::executor_binder<
|
||||
typename std::decay<CompletionHandler>::type,
|
||||
detail::remap_post_to_defer<
|
||||
net::associated_executor_t<CompletionHandler>>>
|
||||
#endif
|
||||
bind_continuation(CompletionHandler&& handler)
|
||||
{
|
||||
return net::bind_executor(
|
||||
detail::remap_post_to_defer<
|
||||
net::associated_executor_t<CompletionHandler>>(
|
||||
net::get_associated_executor(handler)),
|
||||
std::forward<CompletionHandler>(handler));
|
||||
}
|
||||
|
||||
/** Mark a completion handler as a continuation.
|
||||
|
||||
This function wraps a completion handler to associate it with an
|
||||
executor whose `post` operation is remapped to the `defer` operation.
|
||||
It is used by composed asynchronous operation implementations to
|
||||
indicate that a completion handler submitted to an initiating
|
||||
function represents a continuation of the current asynchronous
|
||||
flow of control.
|
||||
|
||||
@param ex The executor to use
|
||||
|
||||
@param handler The handler to wrap
|
||||
The implementation takes ownership of the handler by performing a decay-copy.
|
||||
|
||||
@see
|
||||
|
||||
@li <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4242.html">[N4242] Executors and Asynchronous Operations, Revision 1</a>
|
||||
*/
|
||||
template<class Executor, class CompletionHandler>
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
__implementation_defined__
|
||||
#else
|
||||
net::executor_binder<typename
|
||||
std::decay<CompletionHandler>::type,
|
||||
detail::remap_post_to_defer<Executor>>
|
||||
#endif
|
||||
bind_continuation(
|
||||
Executor const& ex, CompletionHandler&& handler)
|
||||
{
|
||||
return net::bind_executor(
|
||||
detail::remap_post_to_defer<Executor>(ex),
|
||||
std::forward<CompletionHandler>(handler));
|
||||
}
|
||||
#else
|
||||
// VFALCO I turned these off at the last minute because they cause
|
||||
// the completion handler to be moved before the initiating
|
||||
// function is invoked rather than after, which is a foot-gun.
|
||||
//
|
||||
// REMINDER: Uncomment the tests when this is put back
|
||||
template<class F>
|
||||
F&&
|
||||
bind_continuation(F&& f)
|
||||
{
|
||||
return std::forward<F>(f);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+401
@@ -0,0 +1,401 @@
|
||||
//
|
||||
// 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_DETAIL_BIND_HANDLER_HPP
|
||||
#define BOOST_BEAST_DETAIL_BIND_HANDLER_HPP
|
||||
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/beast/core/detail/tuple.hpp>
|
||||
#include <boost/asio/associated_allocator.hpp>
|
||||
#include <boost/asio/associated_cancellation_slot.hpp>
|
||||
#include <boost/asio/associated_executor.hpp>
|
||||
#include <boost/asio/handler_continuation_hook.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/bind/std_placeholders.hpp>
|
||||
#include <boost/is_placeholder.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// bind_handler
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Handler, class... Args>
|
||||
class bind_wrapper
|
||||
{
|
||||
using args_type = detail::tuple<Args...>;
|
||||
|
||||
Handler h_;
|
||||
args_type args_;
|
||||
|
||||
template<class T, class Executor>
|
||||
friend struct net::associated_executor;
|
||||
|
||||
template<class T, class Allocator>
|
||||
friend struct net::associated_allocator;
|
||||
|
||||
template<class T, class CancellationSlot>
|
||||
friend struct net::associated_cancellation_slot;
|
||||
|
||||
template<class Arg, class Vals>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value == 0 &&
|
||||
boost::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value == 0,
|
||||
Arg&&>::type
|
||||
extract(Arg&& arg, Vals&& vals)
|
||||
{
|
||||
boost::ignore_unused(vals);
|
||||
return std::forward<Arg>(arg);
|
||||
}
|
||||
|
||||
template<class Arg, class Vals>
|
||||
static
|
||||
typename std::enable_if<
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value != 0,
|
||||
tuple_element<std::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1,
|
||||
Vals>>::type&&
|
||||
extract(Arg&&, Vals&& vals)
|
||||
{
|
||||
return detail::get<std::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1>(
|
||||
std::forward<Vals>(vals));
|
||||
}
|
||||
|
||||
template<class Arg, class Vals>
|
||||
static
|
||||
typename std::enable_if<
|
||||
boost::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value != 0 &&
|
||||
std::is_placeholder<typename
|
||||
std::decay<Arg>::type>::value == 0,
|
||||
tuple_element<boost::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1,
|
||||
Vals>>::type&&
|
||||
extract(Arg&&, Vals&& vals)
|
||||
{
|
||||
return detail::get<boost::is_placeholder<
|
||||
typename std::decay<Arg>::type>::value - 1>(
|
||||
std::forward<Vals>(vals));
|
||||
}
|
||||
|
||||
template<class ArgsTuple, std::size_t... S>
|
||||
static
|
||||
void
|
||||
invoke(
|
||||
Handler& h,
|
||||
ArgsTuple& args,
|
||||
tuple<>&&,
|
||||
mp11::index_sequence<S...>)
|
||||
{
|
||||
boost::ignore_unused(args);
|
||||
h(detail::get<S>(std::move(args))...);
|
||||
}
|
||||
|
||||
template<
|
||||
class ArgsTuple,
|
||||
class ValsTuple,
|
||||
std::size_t... S>
|
||||
static
|
||||
void
|
||||
invoke(
|
||||
Handler& h,
|
||||
ArgsTuple& args,
|
||||
ValsTuple&& vals,
|
||||
mp11::index_sequence<S...>)
|
||||
{
|
||||
boost::ignore_unused(args);
|
||||
boost::ignore_unused(vals);
|
||||
h(extract(detail::get<S>(std::move(args)),
|
||||
std::forward<ValsTuple>(vals))...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void; // asio needs this
|
||||
|
||||
bind_wrapper(bind_wrapper&&) = default;
|
||||
bind_wrapper(bind_wrapper const&) = default;
|
||||
|
||||
template<
|
||||
class DeducedHandler,
|
||||
class... Args_>
|
||||
explicit
|
||||
bind_wrapper(
|
||||
DeducedHandler&& handler,
|
||||
Args_&&... args)
|
||||
: h_(std::forward<DeducedHandler>(handler))
|
||||
, args_(std::forward<Args_>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Values>
|
||||
void
|
||||
operator()(Values&&... values)
|
||||
{
|
||||
invoke(h_, args_,
|
||||
tuple<Values&&...>(
|
||||
std::forward<Values>(values)...),
|
||||
mp11::index_sequence_for<Args...>());
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
friend
|
||||
bool asio_handler_is_continuation(
|
||||
bind_wrapper* op)
|
||||
{
|
||||
using boost::asio::asio_handler_is_continuation;
|
||||
return asio_handler_is_continuation(
|
||||
std::addressof(op->h_));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Handler, class... Args>
|
||||
class bind_back_wrapper;
|
||||
|
||||
template<class Handler, class... Args>
|
||||
class bind_front_wrapper;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// bind_front
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class Handler, class... Args>
|
||||
class bind_front_wrapper
|
||||
{
|
||||
Handler h_;
|
||||
detail::tuple<Args...> args_;
|
||||
|
||||
template<class T, class Executor>
|
||||
friend struct net::associated_executor;
|
||||
|
||||
template<class T, class Allocator>
|
||||
friend struct net::associated_allocator;
|
||||
|
||||
template<class T, class CancellationSlot>
|
||||
friend struct net::associated_cancellation_slot;
|
||||
|
||||
|
||||
template<std::size_t... I, class... Ts>
|
||||
void
|
||||
invoke(
|
||||
std::false_type,
|
||||
mp11::index_sequence<I...>,
|
||||
Ts&&... ts)
|
||||
{
|
||||
h_( detail::get<I>(std::move(args_))...,
|
||||
std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
template<std::size_t... I, class... Ts>
|
||||
void
|
||||
invoke(
|
||||
std::true_type,
|
||||
mp11::index_sequence<I...>,
|
||||
Ts&&... ts)
|
||||
{
|
||||
std::mem_fn(h_)(
|
||||
detail::get<I>(std::move(args_))...,
|
||||
std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
public:
|
||||
using result_type = void; // asio needs this
|
||||
|
||||
bind_front_wrapper(bind_front_wrapper&&) = default;
|
||||
bind_front_wrapper(bind_front_wrapper const&) = default;
|
||||
|
||||
template<class Handler_, class... Args_>
|
||||
bind_front_wrapper(
|
||||
Handler_&& handler,
|
||||
Args_&&... args)
|
||||
: h_(std::forward<Handler_>(handler))
|
||||
, args_(std::forward<Args_>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
template<class... Ts>
|
||||
void operator()(Ts&&... ts)
|
||||
{
|
||||
invoke(
|
||||
std::is_member_function_pointer<Handler>{},
|
||||
mp11::index_sequence_for<Args...>{},
|
||||
std::forward<Ts>(ts)...);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
friend
|
||||
bool asio_handler_is_continuation(
|
||||
bind_front_wrapper* op)
|
||||
{
|
||||
using boost::asio::asio_handler_is_continuation;
|
||||
return asio_handler_is_continuation(
|
||||
std::addressof(op->h_));
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace boost {
|
||||
namespace asio {
|
||||
|
||||
template<class Handler, class... Args, class Executor>
|
||||
struct associated_executor<
|
||||
beast::detail::bind_wrapper<Handler, Args...>, Executor>
|
||||
{
|
||||
using type = typename
|
||||
associated_executor<Handler, Executor>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_wrapper<Handler, Args...> const& op,
|
||||
Executor const& ex = Executor{}) noexcept
|
||||
{
|
||||
return associated_executor<
|
||||
Handler, Executor>::get(op.h_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Handler, class... Args, class Executor>
|
||||
struct associated_executor<
|
||||
beast::detail::bind_front_wrapper<Handler, Args...>, Executor>
|
||||
{
|
||||
using type = typename
|
||||
associated_executor<Handler, Executor>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
|
||||
Executor const& ex = Executor{}) noexcept
|
||||
{
|
||||
return associated_executor<
|
||||
Handler, Executor>::get(op.h_, ex);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template<class Handler, class... Args, class Allocator>
|
||||
struct associated_allocator<
|
||||
beast::detail::bind_wrapper<Handler, Args...>, Allocator>
|
||||
{
|
||||
using type = typename
|
||||
associated_allocator<Handler, Allocator>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_wrapper<Handler, Args...> const& op,
|
||||
Allocator const& alloc = Allocator{}) noexcept
|
||||
{
|
||||
return associated_allocator<
|
||||
Handler, Allocator>::get(op.h_, alloc);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Handler, class... Args, class Allocator>
|
||||
struct associated_allocator<
|
||||
beast::detail::bind_front_wrapper<Handler, Args...>, Allocator>
|
||||
{
|
||||
using type = typename
|
||||
associated_allocator<Handler, Allocator>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
|
||||
Allocator const& alloc = Allocator{}) noexcept
|
||||
{
|
||||
return associated_allocator<
|
||||
Handler, Allocator>::get(op.h_, alloc);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Handler, class... Args, class CancellationSlot>
|
||||
struct associated_cancellation_slot<
|
||||
beast::detail::bind_wrapper<Handler, Args...>, CancellationSlot>
|
||||
{
|
||||
using type = typename
|
||||
associated_cancellation_slot<Handler>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_wrapper<Handler, Args...> const& op,
|
||||
CancellationSlot const& slot = CancellationSlot{}) noexcept
|
||||
{
|
||||
return associated_cancellation_slot<
|
||||
Handler, CancellationSlot>::get(op.h_, slot);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Handler, class... Args, class CancellationSlot>
|
||||
struct associated_cancellation_slot<
|
||||
beast::detail::bind_front_wrapper<Handler, Args...>, CancellationSlot>
|
||||
{
|
||||
using type = typename
|
||||
associated_cancellation_slot<Handler>::type;
|
||||
|
||||
static
|
||||
type
|
||||
get(beast::detail::bind_front_wrapper<Handler, Args...> const& op,
|
||||
CancellationSlot const& slot = CancellationSlot{}) noexcept
|
||||
{
|
||||
return associated_cancellation_slot<
|
||||
Handler, CancellationSlot>::get(op.h_, slot);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // asio
|
||||
} // boost
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace std {
|
||||
|
||||
// VFALCO Using std::bind on a completion handler will
|
||||
// cause undefined behavior later, because the executor
|
||||
// associated with the handler is not propagated to the
|
||||
// wrapper returned by std::bind; these overloads are
|
||||
// deleted to prevent mistakes. If this creates a problem
|
||||
// please contact me.
|
||||
|
||||
template<class Handler, class... Args>
|
||||
void
|
||||
bind(boost::beast::detail::bind_wrapper<
|
||||
Handler, Args...>, ...) = delete;
|
||||
|
||||
template<class Handler, class... Args>
|
||||
void
|
||||
bind(boost::beast::detail::bind_front_wrapper<
|
||||
Handler, Args...>, ...) = delete;
|
||||
|
||||
} // std
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_BUFFER_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_BUFFER_HPP
|
||||
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<
|
||||
class DynamicBuffer,
|
||||
class ErrorValue>
|
||||
auto
|
||||
dynamic_buffer_prepare_noexcept(
|
||||
DynamicBuffer& buffer,
|
||||
std::size_t size,
|
||||
error_code& ec,
|
||||
ErrorValue ev) ->
|
||||
boost::optional<typename
|
||||
DynamicBuffer::mutable_buffers_type>
|
||||
{
|
||||
if(buffer.max_size() - buffer.size() < size)
|
||||
{
|
||||
// length error
|
||||
BOOST_BEAST_ASSIGN_EC(ec, ev);
|
||||
return boost::none;
|
||||
}
|
||||
boost::optional<typename
|
||||
DynamicBuffer::mutable_buffers_type> result;
|
||||
result.emplace(buffer.prepare(size));
|
||||
ec = {};
|
||||
return result;
|
||||
}
|
||||
|
||||
template<
|
||||
class DynamicBuffer,
|
||||
class ErrorValue>
|
||||
auto
|
||||
dynamic_buffer_prepare(
|
||||
DynamicBuffer& buffer,
|
||||
std::size_t size,
|
||||
error_code& ec,
|
||||
ErrorValue ev) ->
|
||||
boost::optional<typename
|
||||
DynamicBuffer::mutable_buffers_type>
|
||||
{
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
boost::optional<typename
|
||||
DynamicBuffer::mutable_buffers_type> result;
|
||||
result.emplace(buffer.prepare(size));
|
||||
ec = {};
|
||||
return result;
|
||||
}
|
||||
catch(std::length_error const&)
|
||||
{
|
||||
BOOST_BEAST_ASSIGN_EC(ec, ev);
|
||||
}
|
||||
return boost::none;
|
||||
|
||||
#else
|
||||
return dynamic_buffer_prepare_noexcept(
|
||||
buffer, size, ec, ev);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFER_TRAITS_HPP
|
||||
#define BOOST_BEAST_DETAIL_BUFFER_TRAITS_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
template<class T>
|
||||
struct buffers_iterator_type_helper
|
||||
{
|
||||
using type = decltype(
|
||||
net::buffer_sequence_begin(
|
||||
std::declval<T const&>()));
|
||||
};
|
||||
|
||||
template<>
|
||||
struct buffers_iterator_type_helper<
|
||||
net::const_buffer>
|
||||
{
|
||||
using type = net::const_buffer const*;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct buffers_iterator_type_helper<
|
||||
net::mutable_buffer>
|
||||
{
|
||||
using type = net::mutable_buffer const*;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct buffer_bytes_impl
|
||||
{
|
||||
std::size_t
|
||||
operator()(net::const_buffer b) const noexcept
|
||||
{
|
||||
return net::const_buffer(b).size();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
operator()(net::mutable_buffer b) const noexcept
|
||||
{
|
||||
return net::mutable_buffer(b).size();
|
||||
}
|
||||
|
||||
template<
|
||||
class B,
|
||||
class = typename std::enable_if<
|
||||
net::is_const_buffer_sequence<B>::value>::type>
|
||||
std::size_t
|
||||
operator()(B const& b) const noexcept
|
||||
{
|
||||
using net::buffer_size;
|
||||
return buffer_size(b);
|
||||
}
|
||||
};
|
||||
|
||||
/** Return `true` if a buffer sequence is empty
|
||||
|
||||
This is sometimes faster than using @ref buffer_bytes
|
||||
*/
|
||||
template<class ConstBufferSequence>
|
||||
bool
|
||||
buffers_empty(ConstBufferSequence const& buffers)
|
||||
{
|
||||
auto it = net::buffer_sequence_begin(buffers);
|
||||
auto end = net::buffer_sequence_end(buffers);
|
||||
while(it != end)
|
||||
{
|
||||
if(net::const_buffer(*it).size() > 0)
|
||||
return false;
|
||||
++it;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFERS_PAIR_HPP
|
||||
#define BOOST_BEAST_DETAIL_BUFFERS_PAIR_HPP
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4521) // multiple copy constructors specified
|
||||
# pragma warning (disable: 4522) // multiple assignment operators specified
|
||||
#endif
|
||||
|
||||
template<bool isMutable>
|
||||
class buffers_pair
|
||||
{
|
||||
public:
|
||||
// VFALCO: This type is public otherwise
|
||||
// asio::buffers_iterator won't compile.
|
||||
using value_type = typename
|
||||
std::conditional<isMutable,
|
||||
net::mutable_buffer,
|
||||
net::const_buffer>::type;
|
||||
|
||||
using const_iterator = value_type const*;
|
||||
|
||||
buffers_pair() = default;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
buffers_pair(buffers_pair const& other)
|
||||
: buffers_pair(
|
||||
*other.begin(), *(other.begin() + 1))
|
||||
{
|
||||
}
|
||||
|
||||
buffers_pair&
|
||||
operator=(buffers_pair const& other)
|
||||
{
|
||||
b_[0] = *other.begin();
|
||||
b_[1] = *(other.begin() + 1);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
buffers_pair(buffers_pair const& other) = default;
|
||||
buffers_pair& operator=(buffers_pair const& other) = default;
|
||||
#endif
|
||||
|
||||
template<
|
||||
bool isMutable_ = isMutable,
|
||||
class = typename std::enable_if<
|
||||
! isMutable_>::type>
|
||||
buffers_pair(buffers_pair<true> const& other)
|
||||
: buffers_pair(
|
||||
*other.begin(), *(other.begin() + 1))
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
bool isMutable_ = isMutable,
|
||||
class = typename std::enable_if<
|
||||
! isMutable_>::type>
|
||||
buffers_pair&
|
||||
operator=(buffers_pair<true> const& other)
|
||||
{
|
||||
b_[0] = *other.begin();
|
||||
b_[1] = *(other.begin() + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
buffers_pair(value_type b0, value_type b1)
|
||||
: b_{b0, b1}
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return &b_[0];
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
if(b_[1].size() > 0)
|
||||
return &b_[2];
|
||||
return &b_[1];
|
||||
}
|
||||
|
||||
private:
|
||||
value_type b_[2];
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFERS_RANGE_ADAPTOR_HPP
|
||||
#define BOOST_BEAST_DETAIL_BUFFERS_RANGE_ADAPTOR_HPP
|
||||
|
||||
#include <boost/beast/core/buffer_traits.hpp>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class BufferSequence>
|
||||
class buffers_range_adaptor
|
||||
{
|
||||
BufferSequence b_;
|
||||
|
||||
public:
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
using value_type = __see_below__;
|
||||
#else
|
||||
using value_type = buffers_type<BufferSequence>;
|
||||
#endif
|
||||
|
||||
class const_iterator
|
||||
{
|
||||
friend class buffers_range_adaptor;
|
||||
|
||||
using iter_type =
|
||||
buffers_iterator_type<BufferSequence>;
|
||||
|
||||
iter_type it_{};
|
||||
|
||||
const_iterator(iter_type const& it)
|
||||
: it_(it)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = typename
|
||||
buffers_range_adaptor::value_type;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category =
|
||||
std::bidirectional_iterator_tag;
|
||||
|
||||
const_iterator() = default;
|
||||
|
||||
bool
|
||||
operator==(const_iterator const& other) const
|
||||
{
|
||||
return it_ == other.it_;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const = delete;
|
||||
|
||||
const_iterator&
|
||||
operator++()
|
||||
{
|
||||
++it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator--()
|
||||
{
|
||||
--it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator--(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
--(*this);
|
||||
return temp;
|
||||
}
|
||||
};
|
||||
|
||||
explicit
|
||||
buffers_range_adaptor(BufferSequence const& b)
|
||||
: b_(b)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return {net::buffer_sequence_begin(b_)};
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return {net::buffer_sequence_end(b_)};
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// 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_DETAIL_BUFFERS_REF_HPP
|
||||
#define BOOST_BEAST_DETAIL_BUFFERS_REF_HPP
|
||||
|
||||
#include <boost/beast/core/buffer_traits.hpp>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// A very lightweight reference to a buffer sequence
|
||||
template<class BufferSequence>
|
||||
class buffers_ref
|
||||
{
|
||||
BufferSequence const* buffers_;
|
||||
|
||||
public:
|
||||
using const_iterator =
|
||||
buffers_iterator_type<BufferSequence>;
|
||||
|
||||
using value_type = typename
|
||||
std::iterator_traits<const_iterator>::value_type;
|
||||
|
||||
buffers_ref(buffers_ref const&) = default;
|
||||
buffers_ref& operator=(buffers_ref const&) = default;
|
||||
|
||||
explicit
|
||||
buffers_ref(BufferSequence const& buffers)
|
||||
: buffers_(std::addressof(buffers))
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return net::buffer_sequence_begin(*buffers_);
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return net::buffer_sequence_end(*buffers_);
|
||||
}
|
||||
};
|
||||
|
||||
// Return a reference to a buffer sequence
|
||||
template<class BufferSequence>
|
||||
buffers_ref<BufferSequence>
|
||||
make_buffers_ref(BufferSequence const& buffers)
|
||||
{
|
||||
static_assert(
|
||||
is_const_buffer_sequence<BufferSequence>::value,
|
||||
"BufferSequence type requirements not met");
|
||||
return buffers_ref<BufferSequence>(buffers);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
//
|
||||
// This is a derivative work, original copyright follows:
|
||||
//
|
||||
|
||||
/*
|
||||
Copyright (c) 2015 Orson Peters <orsonpeters@gmail.com>
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty. In no event will the
|
||||
authors be held liable for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the
|
||||
original software. If you use this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as
|
||||
being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_BEAST_CORE_DETAIL_CHACHA_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_CHACHA_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t R>
|
||||
class chacha
|
||||
{
|
||||
alignas(16) std::uint32_t block_[16];
|
||||
std::uint32_t keysetup_[8];
|
||||
std::uint64_t ctr_ = 0;
|
||||
int idx_ = 16;
|
||||
|
||||
void generate_block()
|
||||
{
|
||||
std::uint32_t constexpr constants[4] = {
|
||||
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 };
|
||||
std::uint32_t input[16];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
input[i] = constants[i];
|
||||
for (int i = 0; i < 8; ++i)
|
||||
input[4 + i] = keysetup_[i];
|
||||
input[12] = (ctr_ / 16) & 0xffffffffu;
|
||||
input[13] = (ctr_ / 16) >> 32;
|
||||
input[14] = input[15] = 0xdeadbeef; // Could use 128-bit counter.
|
||||
for (int i = 0; i < 16; ++i)
|
||||
block_[i] = input[i];
|
||||
chacha_core();
|
||||
for (int i = 0; i < 16; ++i)
|
||||
block_[i] += input[i];
|
||||
}
|
||||
|
||||
void chacha_core()
|
||||
{
|
||||
#define BOOST_BEAST_CHACHA_ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
#define BOOST_BEAST_CHACHA_QUARTERROUND(x, a, b, c, d) \
|
||||
x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BOOST_BEAST_CHACHA_ROTL32(x[d], 16); \
|
||||
x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BOOST_BEAST_CHACHA_ROTL32(x[b], 12); \
|
||||
x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BOOST_BEAST_CHACHA_ROTL32(x[d], 8); \
|
||||
x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BOOST_BEAST_CHACHA_ROTL32(x[b], 7)
|
||||
|
||||
for (unsigned i = 0; i < R; i += 2)
|
||||
{
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 0, 4, 8, 12);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 1, 5, 9, 13);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 2, 6, 10, 14);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 3, 7, 11, 15);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 0, 5, 10, 15);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 1, 6, 11, 12);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 2, 7, 8, 13);
|
||||
BOOST_BEAST_CHACHA_QUARTERROUND(block_, 3, 4, 9, 14);
|
||||
}
|
||||
|
||||
#undef BOOST_BEAST_CHACHA_QUARTERROUND
|
||||
#undef BOOST_BEAST_CHACHA_ROTL32
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr std::size_t state_size = sizeof(chacha::keysetup_);
|
||||
|
||||
using result_type = std::uint32_t;
|
||||
|
||||
chacha(std::uint32_t const* v, std::uint64_t stream)
|
||||
{
|
||||
for (int i = 0; i < 6; ++i)
|
||||
keysetup_[i] = v[i];
|
||||
keysetup_[6] = v[6] + (stream & 0xffffffff);
|
||||
keysetup_[7] = v[7] + ((stream >> 32) & 0xffffffff);
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
operator()()
|
||||
{
|
||||
if(idx_ == 16)
|
||||
{
|
||||
idx_ = 0;
|
||||
++ctr_;
|
||||
generate_block();
|
||||
}
|
||||
return block_[idx_++];
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_CORE_DETAIL_CHAR_BUFFER_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_CHAR_BUFFER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template <std::size_t N>
|
||||
class char_buffer
|
||||
{
|
||||
public:
|
||||
bool try_push_back(char c)
|
||||
{
|
||||
if (size_ == N)
|
||||
return false;
|
||||
buf_[size_++] = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_append(char const* first, char const* last)
|
||||
{
|
||||
std::size_t const n = last - first;
|
||||
if (n > N - size_)
|
||||
return false;
|
||||
std::memmove(&buf_[size_], first, n);
|
||||
size_ += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear() noexcept
|
||||
{
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
char* data() noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
char const* data() const noexcept
|
||||
{
|
||||
return buf_;
|
||||
}
|
||||
|
||||
std::size_t size() const noexcept
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t size_= 0;
|
||||
char buf_[N];
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_CLAMP_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_CLAMP_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class UInt>
|
||||
static
|
||||
std::size_t
|
||||
clamp(UInt x)
|
||||
{
|
||||
if(x >= (std::numeric_limits<std::size_t>::max)())
|
||||
return (std::numeric_limits<std::size_t>::max)();
|
||||
return static_cast<std::size_t>(x);
|
||||
}
|
||||
|
||||
template<class UInt>
|
||||
static
|
||||
std::size_t
|
||||
clamp(UInt x, std::size_t limit)
|
||||
{
|
||||
if(x >= limit)
|
||||
return limit;
|
||||
return static_cast<std::size_t>(x);
|
||||
}
|
||||
|
||||
// return `true` if x + y > z, which are unsigned
|
||||
template<
|
||||
class U1, class U2, class U3>
|
||||
constexpr
|
||||
bool
|
||||
sum_exceeds(U1 x, U2 y, U3 z)
|
||||
{
|
||||
static_assert(
|
||||
std::is_unsigned<U1>::value &&
|
||||
std::is_unsigned<U2>::value &&
|
||||
std::is_unsigned<U3>::value, "");
|
||||
return y > z || x > z - y;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_CONFIG_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_CONFIG_HPP
|
||||
|
||||
// Available to every header
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace asio
|
||||
{
|
||||
} // asio
|
||||
namespace beast {
|
||||
namespace net = boost::asio;
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
/*
|
||||
_MSC_VER and _MSC_FULL_VER by version:
|
||||
|
||||
14.0 (2015) 1900 190023026
|
||||
14.0 (2015 Update 1) 1900 190023506
|
||||
14.0 (2015 Update 2) 1900 190023918
|
||||
14.0 (2015 Update 3) 1900 190024210
|
||||
*/
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# if BOOST_MSVC_FULL_VER < 190024210
|
||||
# error Beast requires C++11: Visual Studio 2015 Update 3 or later needed
|
||||
# endif
|
||||
|
||||
#elif defined(BOOST_GCC)
|
||||
# if(BOOST_GCC < 50000)
|
||||
# error Beast requires C++11: gcc version 5 or later needed
|
||||
# endif
|
||||
|
||||
#else
|
||||
# if \
|
||||
defined(BOOST_NO_CXX11_DECLTYPE) || \
|
||||
defined(BOOST_NO_CXX11_HDR_TUPLE) || \
|
||||
defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) || \
|
||||
defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
# error Beast requires C++11: a conforming compiler is needed
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#define BOOST_BEAST_DEPRECATION_STRING \
|
||||
"This is a deprecated interface, #define BOOST_BEAST_ALLOW_DEPRECATED to allow it"
|
||||
|
||||
#ifndef BOOST_BEAST_ASSUME
|
||||
# ifdef BOOST_GCC
|
||||
# define BOOST_BEAST_ASSUME(cond) \
|
||||
do { if (!(cond)) __builtin_unreachable(); } while (0)
|
||||
# else
|
||||
# define BOOST_BEAST_ASSUME(cond) do { } while(0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Default to a header-only implementation. The user must specifically
|
||||
// request separate compilation by defining BOOST_BEAST_SEPARATE_COMPILATION
|
||||
#ifndef BOOST_BEAST_HEADER_ONLY
|
||||
# ifndef BOOST_BEAST_SEPARATE_COMPILATION
|
||||
# define BOOST_BEAST_HEADER_ONLY 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if BOOST_BEAST_DOXYGEN
|
||||
# define BOOST_BEAST_DECL
|
||||
#elif defined(BOOST_BEAST_HEADER_ONLY)
|
||||
# define BOOST_BEAST_DECL inline
|
||||
#else
|
||||
# define BOOST_BEAST_DECL
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_BEAST_ASYNC_RESULT1
|
||||
#define BOOST_BEAST_ASYNC_RESULT1(type) \
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(type, void(::boost::beast::error_code))
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_BEAST_ASYNC_RESULT2
|
||||
#define BOOST_BEAST_ASYNC_RESULT2(type) \
|
||||
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(type, void(::boost::beast::error_code, ::std::size_t))
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_BEAST_ASYNC_TPARAM1
|
||||
#define BOOST_BEAST_ASYNC_TPARAM1 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::beast::error_code))
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_BEAST_ASYNC_TPARAM2
|
||||
#define BOOST_BEAST_ASYNC_TPARAM2 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::beast::error_code, ::std::size_t))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOOST_BEAST_NO_SOURCE_LOCATION
|
||||
#define BOOST_BEAST_ASSIGN_EC(ec, error) ec = error
|
||||
#else
|
||||
|
||||
#define BOOST_BEAST_ASSIGN_EC(ec, error) \
|
||||
static constexpr auto BOOST_PP_CAT(loc_, __LINE__) ((BOOST_CURRENT_LOCATION)); \
|
||||
ec.assign(error, & BOOST_PP_CAT(loc_, __LINE__) )
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_BEAST_FILE_BUFFER_SIZE
|
||||
#define BOOST_BEAST_FILE_BUFFER_SIZE 4096
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright (c) 2017 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_DETAIL_CPU_INFO_HPP
|
||||
#define BOOST_BEAST_DETAIL_CPU_INFO_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef BOOST_BEAST_NO_INTRINSICS
|
||||
# if defined(BOOST_MSVC) || ((defined(BOOST_GCC) || defined(BOOST_CLANG)) && defined(__SSE4_2__))
|
||||
# define BOOST_BEAST_NO_INTRINSICS 0
|
||||
# else
|
||||
# define BOOST_BEAST_NO_INTRINSICS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ! BOOST_BEAST_NO_INTRINSICS
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#include <intrin.h> // __cpuid
|
||||
#else
|
||||
#include <cpuid.h> // __get_cpuid
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
/* Portions from Boost,
|
||||
Copyright Andrey Semashev 2007 - 2015.
|
||||
*/
|
||||
template<class = void>
|
||||
void
|
||||
cpuid(
|
||||
std::uint32_t id,
|
||||
std::uint32_t& eax,
|
||||
std::uint32_t& ebx,
|
||||
std::uint32_t& ecx,
|
||||
std::uint32_t& edx)
|
||||
{
|
||||
#ifdef BOOST_MSVC
|
||||
int regs[4];
|
||||
__cpuid(regs, id);
|
||||
eax = regs[0];
|
||||
ebx = regs[1];
|
||||
ecx = regs[2];
|
||||
edx = regs[3];
|
||||
#else
|
||||
__get_cpuid(id, &eax, &ebx, &ecx, &edx);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct cpu_info
|
||||
{
|
||||
bool sse42 = false;
|
||||
|
||||
cpu_info();
|
||||
};
|
||||
|
||||
inline
|
||||
cpu_info::
|
||||
cpu_info()
|
||||
{
|
||||
constexpr std::uint32_t SSE42 = 1 << 20;
|
||||
|
||||
std::uint32_t eax = 0;
|
||||
std::uint32_t ebx = 0;
|
||||
std::uint32_t ecx = 0;
|
||||
std::uint32_t edx = 0;
|
||||
|
||||
cpuid(0, eax, ebx, ecx, edx);
|
||||
if(eax >= 1)
|
||||
{
|
||||
cpuid(1, eax, ebx, ecx, edx);
|
||||
sse42 = (ecx & SSE42) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class = void>
|
||||
cpu_info const&
|
||||
get_cpu_info()
|
||||
{
|
||||
static cpu_info const ci;
|
||||
return ci;
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
|
||||
//
|
||||
// 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_BEAST_CORE_DETAIL_FILTERING_CANCELLATION_SLOT_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_FILTERING_CANCELLATION_SLOT_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/asio/cancellation_signal.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<typename CancellationSlot = net::cancellation_slot>
|
||||
struct filtering_cancellation_slot : CancellationSlot
|
||||
{
|
||||
template<typename ... Args>
|
||||
filtering_cancellation_slot(net::cancellation_type type, Args && ... args)
|
||||
: CancellationSlot(std::forward<Args>(args)...), type(type) {}
|
||||
|
||||
net::cancellation_type type = net::cancellation_type::terminal;
|
||||
|
||||
using CancellationSlot::operator=;
|
||||
|
||||
template<typename Handler>
|
||||
struct handler_wrapper
|
||||
{
|
||||
Handler handler;
|
||||
const net::cancellation_type type;
|
||||
|
||||
template<typename ... Args>
|
||||
handler_wrapper(net::cancellation_type type, Args && ... args)
|
||||
: handler(std::forward<Args>(args)...),
|
||||
type(type) {}
|
||||
|
||||
void operator()(net::cancellation_type tp)
|
||||
{
|
||||
if ((tp & type) != net::cancellation_type::none)
|
||||
handler(tp);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CancellationHandler, typename ... Args>
|
||||
CancellationHandler& emplace(Args && ... args)
|
||||
{
|
||||
return CancellationSlot::template emplace<handler_wrapper<CancellationHandler>>(
|
||||
type, std::forward<Args>(args)...).handler;
|
||||
}
|
||||
|
||||
template <typename CancellationHandler>
|
||||
CancellationHandler& assign(CancellationHandler && ch)
|
||||
{
|
||||
return CancellationSlot::template emplace<handler_wrapper<CancellationHandler>>(
|
||||
type, std::forward<CancellationHandler>(ch)).handler;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //BOOST_BEAST_CORE_DETAIL_FILTERING_CANCELLATION_SLOT_HPP
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_FLAT_STREAM_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_FLAT_STREAM_HPP
|
||||
|
||||
#include <boost/beast/core/buffer_traits.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
class flat_stream_base
|
||||
{
|
||||
public:
|
||||
// Largest buffer size we will flatten.
|
||||
// 16KB is the upper limit on reasonably sized HTTP messages.
|
||||
static std::size_t constexpr max_size = 16 * 1024;
|
||||
|
||||
// Largest stack we will use to flatten
|
||||
static std::size_t constexpr max_stack = 8 * 1024;
|
||||
|
||||
struct flatten_result
|
||||
{
|
||||
std::size_t size;
|
||||
bool flatten;
|
||||
};
|
||||
|
||||
// calculates the flatten settings for a buffer sequence
|
||||
template<class BufferSequence>
|
||||
static
|
||||
flatten_result
|
||||
flatten(
|
||||
BufferSequence const& buffers, std::size_t limit)
|
||||
{
|
||||
flatten_result result{0, false};
|
||||
auto first = net::buffer_sequence_begin(buffers);
|
||||
auto last = net::buffer_sequence_end(buffers);
|
||||
if(first != last)
|
||||
{
|
||||
result.size = buffer_bytes(*first);
|
||||
if(result.size < limit)
|
||||
{
|
||||
auto it = first;
|
||||
auto prev = first;
|
||||
while(++it != last)
|
||||
{
|
||||
auto const n = buffer_bytes(*it);
|
||||
if(result.size + n > limit)
|
||||
break;
|
||||
result.size += n;
|
||||
prev = it;
|
||||
}
|
||||
result.flatten = prev != first;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
//
|
||||
// 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_DETAIL_GET_IO_CONTEXT_HPP
|
||||
#define BOOST_BEAST_DETAIL_GET_IO_CONTEXT_HPP
|
||||
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#ifdef BOOST_ASIO_NO_TS_EXECUTORS
|
||||
#include <boost/asio/execution.hpp>
|
||||
#endif
|
||||
#include <boost/asio/executor.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::io_context& ioc)
|
||||
{
|
||||
return std::addressof(ioc);
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::io_context::executor_type const& ex)
|
||||
{
|
||||
return std::addressof(net::query(ex, net::execution::context));
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(net::strand<
|
||||
net::io_context::executor_type> const& ex)
|
||||
{
|
||||
return get_io_context(ex.get_inner_executor());
|
||||
}
|
||||
|
||||
template<class Executor>
|
||||
net::io_context*
|
||||
get_io_context(net::strand<Executor> const& ex)
|
||||
{
|
||||
return get_io_context(ex.get_inner_executor());
|
||||
}
|
||||
|
||||
template<
|
||||
class T,
|
||||
class = typename std::enable_if<
|
||||
std::is_same<T, net::executor>::value || std::is_same<T, net::any_io_executor>::value>::type>
|
||||
net::io_context*
|
||||
get_io_context(T const& ex)
|
||||
{
|
||||
auto p = ex.template target<typename
|
||||
net::io_context::executor_type>();
|
||||
if(! p)
|
||||
return nullptr;
|
||||
return get_io_context(*p);
|
||||
}
|
||||
|
||||
inline
|
||||
net::io_context*
|
||||
get_io_context(...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context_impl(T& t, std::true_type)
|
||||
{
|
||||
return get_io_context(
|
||||
t.get_executor());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context_impl(T const&, std::false_type)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns the io_context*, or nullptr, for any object.
|
||||
template<class T>
|
||||
net::io_context*
|
||||
get_io_context(T& t)
|
||||
{
|
||||
return get_io_context_impl(t,
|
||||
has_get_executor<T>{});
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
//
|
||||
// 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_DETAIL_IMPL_READ_HPP
|
||||
#define BOOST_BEAST_DETAIL_IMPL_READ_HPP
|
||||
|
||||
#include <boost/beast/core/bind_handler.hpp>
|
||||
#include <boost/beast/core/async_base.hpp>
|
||||
#include <boost/beast/core/flat_static_buffer.hpp>
|
||||
#include <boost/beast/core/read_size.hpp>
|
||||
#include <boost/asio/basic_stream_socket.hpp>
|
||||
#include <boost/asio/coroutine.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// The number of bytes in the stack buffer when using non-blocking.
|
||||
static std::size_t constexpr default_max_stack_buffer = 16384;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct dynamic_read_ops
|
||||
{
|
||||
|
||||
// read into a dynamic buffer until the
|
||||
// condition is met or an error occurs
|
||||
template<
|
||||
class Stream,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class Handler>
|
||||
class read_op
|
||||
: public asio::coroutine
|
||||
, public async_base<
|
||||
Handler, beast::executor_type<Stream>>
|
||||
{
|
||||
Stream& s_;
|
||||
DynamicBuffer& b_;
|
||||
Condition cond_;
|
||||
error_code ec_;
|
||||
std::size_t total_ = 0;
|
||||
|
||||
public:
|
||||
read_op(read_op&&) = default;
|
||||
|
||||
template<class Handler_, class Condition_>
|
||||
read_op(
|
||||
Handler_&& h,
|
||||
Stream& s,
|
||||
DynamicBuffer& b,
|
||||
Condition_&& cond)
|
||||
: async_base<Handler,
|
||||
beast::executor_type<Stream>>(
|
||||
std::forward<Handler_>(h),
|
||||
s.get_executor())
|
||||
, s_(s)
|
||||
, b_(b)
|
||||
, cond_(std::forward<Condition_>(cond))
|
||||
{
|
||||
(*this)({}, 0, false);
|
||||
}
|
||||
|
||||
void
|
||||
operator()(
|
||||
error_code ec,
|
||||
std::size_t bytes_transferred,
|
||||
bool cont = true)
|
||||
{
|
||||
std::size_t max_prepare;
|
||||
BOOST_ASIO_CORO_REENTER(*this)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
max_prepare = beast::read_size(b_, cond_(ec, total_, b_));
|
||||
if(max_prepare == 0)
|
||||
break;
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
s_.async_read_some(
|
||||
b_.prepare(max_prepare), std::move(*this));
|
||||
b_.commit(bytes_transferred);
|
||||
total_ += bytes_transferred;
|
||||
}
|
||||
if(! cont)
|
||||
{
|
||||
// run this handler "as-if" using net::post
|
||||
// to reduce template instantiations
|
||||
ec_ = ec;
|
||||
BOOST_ASIO_CORO_YIELD
|
||||
s_.async_read_some(
|
||||
b_.prepare(0), std::move(*this));
|
||||
BOOST_BEAST_ASSIGN_EC(ec, ec_);
|
||||
}
|
||||
this->complete_now(ec, total_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct run_read_op
|
||||
{
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class Condition,
|
||||
class ReadHandler>
|
||||
void
|
||||
operator()(
|
||||
ReadHandler&& h,
|
||||
AsyncReadStream* s,
|
||||
DynamicBuffer* b,
|
||||
Condition&& c)
|
||||
{
|
||||
// If you get an error on the following line it means
|
||||
// that your handler does not meet the documented type
|
||||
// requirements for the handler.
|
||||
|
||||
static_assert(
|
||||
beast::detail::is_invocable<ReadHandler,
|
||||
void(error_code, std::size_t)>::value,
|
||||
"ReadHandler type requirements not met");
|
||||
|
||||
read_op<
|
||||
AsyncReadStream,
|
||||
DynamicBuffer,
|
||||
typename std::decay<Condition>::type,
|
||||
typename std::decay<ReadHandler>::type>(
|
||||
std::forward<ReadHandler>(h),
|
||||
*s,
|
||||
*b,
|
||||
std::forward<Condition>(c));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<
|
||||
class SyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
class>
|
||||
std::size_t
|
||||
read(
|
||||
SyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition cond)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
error_code ec;
|
||||
auto const bytes_transferred = detail::read(
|
||||
stream, buffer, std::move(cond), ec);
|
||||
if(ec)
|
||||
BOOST_THROW_EXCEPTION(system_error{ec});
|
||||
return bytes_transferred;
|
||||
}
|
||||
|
||||
template<
|
||||
class SyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
class>
|
||||
std::size_t
|
||||
read(
|
||||
SyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition cond,
|
||||
error_code& ec)
|
||||
{
|
||||
static_assert(is_sync_read_stream<SyncReadStream>::value,
|
||||
"SyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
ec = {};
|
||||
std::size_t total = 0;
|
||||
std::size_t max_prepare;
|
||||
for(;;)
|
||||
{
|
||||
max_prepare = beast::read_size(buffer, cond(ec, total, buffer));
|
||||
if(max_prepare == 0)
|
||||
break;
|
||||
std::size_t const bytes_transferred =
|
||||
stream.read_some(buffer.prepare(max_prepare), ec);
|
||||
buffer.commit(bytes_transferred);
|
||||
total += bytes_transferred;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
BOOST_BEAST_ASYNC_TPARAM2 ReadHandler,
|
||||
class>
|
||||
BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
|
||||
async_read(
|
||||
AsyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition&& cond,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_async_read_stream<AsyncReadStream>::value,
|
||||
"AsyncReadStream type requirements not met");
|
||||
static_assert(
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value,
|
||||
"DynamicBuffer type requirements not met");
|
||||
static_assert(
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value,
|
||||
"CompletionCondition type requirements not met");
|
||||
return net::async_initiate<
|
||||
ReadHandler,
|
||||
void(error_code, std::size_t)>(
|
||||
typename dynamic_read_ops::run_read_op{},
|
||||
handler,
|
||||
&stream,
|
||||
&buffer,
|
||||
std::forward<CompletionCondition>(cond));
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_DETAIL_IMPL_TEMPORARY_BUFFER_IPP
|
||||
#define BOOST_BEAST_DETAIL_IMPL_TEMPORARY_BUFFER_IPP
|
||||
|
||||
#include <boost/beast/core/detail/temporary_buffer.hpp>
|
||||
#include <boost/beast/core/detail/clamp.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
void
|
||||
temporary_buffer::
|
||||
append(string_view s)
|
||||
{
|
||||
grow(s.size());
|
||||
unchecked_append(s);
|
||||
}
|
||||
|
||||
void
|
||||
temporary_buffer::
|
||||
append(string_view s1, string_view s2)
|
||||
{
|
||||
grow(s1.size() + s2.size());
|
||||
unchecked_append(s1);
|
||||
unchecked_append(s2);
|
||||
}
|
||||
|
||||
void
|
||||
temporary_buffer::
|
||||
unchecked_append(string_view s)
|
||||
{
|
||||
auto n = s.size();
|
||||
std::memcpy(&data_[size_], s.data(), n);
|
||||
size_ += n;
|
||||
}
|
||||
|
||||
void
|
||||
temporary_buffer::
|
||||
grow(std::size_t n)
|
||||
{
|
||||
if (capacity_ - size_ >= n)
|
||||
return;
|
||||
|
||||
auto const capacity = (n + size_) * 2u;
|
||||
BOOST_ASSERT(! detail::sum_exceeds(
|
||||
n, size_, capacity));
|
||||
char* const p = new char[capacity];
|
||||
std::memcpy(p, data_, size_);
|
||||
deallocate(boost::exchange(data_, p));
|
||||
capacity_ = capacity;
|
||||
}
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// 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_DETAIL_IS_INVOCABLE_HPP
|
||||
#define BOOST_BEAST_DETAIL_IS_INVOCABLE_HPP
|
||||
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class R, class C, class ...A>
|
||||
auto
|
||||
is_invocable_test(C&& c, int, A&& ...a)
|
||||
-> decltype(std::is_convertible<
|
||||
decltype(c(std::forward<A>(a)...)), R>::value ||
|
||||
std::is_same<R, void>::value,
|
||||
std::true_type());
|
||||
|
||||
template<class R, class C, class ...A>
|
||||
std::false_type
|
||||
is_invocable_test(C&& c, long, A&& ...a);
|
||||
|
||||
/** Metafunction returns `true` if F callable as R(A...)
|
||||
|
||||
Example:
|
||||
|
||||
@code
|
||||
is_invocable<T, void(std::string)>::value
|
||||
@endcode
|
||||
*/
|
||||
/** @{ */
|
||||
template<class C, class F>
|
||||
struct is_invocable : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class C, class R, class ...A>
|
||||
struct is_invocable<C, R(A...)>
|
||||
: decltype(is_invocable_test<R>(
|
||||
std::declval<C>(), 1, std::declval<A>()...))
|
||||
{
|
||||
};
|
||||
/** @} */
|
||||
|
||||
template<class CompletionToken, class Signature, class = void>
|
||||
struct is_completion_token_for : std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
struct any_initiation
|
||||
{
|
||||
template<class...AnyArgs>
|
||||
void operator()(AnyArgs&&...);
|
||||
};
|
||||
|
||||
template<class CompletionToken, class R, class...Args>
|
||||
struct is_completion_token_for<
|
||||
CompletionToken, R(Args...), boost::void_t<decltype(
|
||||
boost::asio::async_initiate<CompletionToken, R(Args...)>(
|
||||
any_initiation(), std::declval<CompletionToken&>())
|
||||
)>> : std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
//
|
||||
// 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_DETAIL_OSTREAM_HPP
|
||||
#define BOOST_BEAST_DETAIL_OSTREAM_HPP
|
||||
|
||||
#include <boost/beast/core/buffers_prefix.hpp>
|
||||
#include <boost/beast/core/buffers_range.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
struct basic_streambuf_movable_helper :
|
||||
std::basic_streambuf<char, std::char_traits<char>>
|
||||
{
|
||||
basic_streambuf_movable_helper(
|
||||
basic_streambuf_movable_helper&&) = default;
|
||||
};
|
||||
|
||||
using basic_streambuf_movable =
|
||||
std::is_move_constructible<basic_streambuf_movable_helper>;
|
||||
|
||||
template<class DynamicBuffer,
|
||||
class CharT, class Traits, bool isMovable>
|
||||
class ostream_buffer;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
class ostream_buffer
|
||||
<DynamicBuffer, CharT, Traits, true> final
|
||||
: public std::basic_streambuf<CharT, Traits>
|
||||
{
|
||||
using int_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::int_type;
|
||||
|
||||
using traits_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||
|
||||
DynamicBuffer& b_;
|
||||
|
||||
public:
|
||||
ostream_buffer(ostream_buffer&&) = default;
|
||||
ostream_buffer(ostream_buffer const&) = delete;
|
||||
|
||||
~ostream_buffer() noexcept
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
explicit
|
||||
ostream_buffer(DynamicBuffer& b)
|
||||
: b_(b)
|
||||
{
|
||||
b_.prepare(0);
|
||||
}
|
||||
|
||||
int_type
|
||||
overflow(int_type ch) override
|
||||
{
|
||||
BOOST_ASSERT(! Traits::eq_int_type(
|
||||
ch, Traits::eof()));
|
||||
sync();
|
||||
|
||||
static std::size_t constexpr max_size = 65536;
|
||||
auto const max_prepare = std::min<std::size_t>(
|
||||
std::max<std::size_t>(
|
||||
512, b_.capacity() - b_.size()),
|
||||
std::min<std::size_t>(
|
||||
max_size, b_.max_size() - b_.size()));
|
||||
if(max_prepare == 0)
|
||||
return Traits::eof();
|
||||
auto const bs = b_.prepare(max_prepare);
|
||||
auto const b = buffers_front(bs);
|
||||
auto const p = static_cast<CharT*>(b.data());
|
||||
this->setp(p, p + b.size() / sizeof(CharT));
|
||||
|
||||
BOOST_ASSERT(b_.capacity() > b_.size());
|
||||
return this->sputc(
|
||||
Traits::to_char_type(ch));
|
||||
}
|
||||
|
||||
int
|
||||
sync() override
|
||||
{
|
||||
b_.commit(
|
||||
(this->pptr() - this->pbase()) *
|
||||
sizeof(CharT));
|
||||
this->setp(nullptr, nullptr);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// This nonsense is all to work around a glitch in libstdc++
|
||||
// where std::basic_streambuf copy constructor is private:
|
||||
// https://github.com/gcc-mirror/gcc/blob/gcc-4_8-branch/libstdc%2B%2B-v3/include/std/streambuf#L799
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
class ostream_buffer
|
||||
<DynamicBuffer, CharT, Traits, false>
|
||||
: public std::basic_streambuf<CharT, Traits>
|
||||
{
|
||||
using int_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::int_type;
|
||||
|
||||
using traits_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||
|
||||
DynamicBuffer& b_;
|
||||
|
||||
public:
|
||||
ostream_buffer(ostream_buffer&&) = delete;
|
||||
ostream_buffer(ostream_buffer const&) = delete;
|
||||
|
||||
~ostream_buffer() noexcept
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
explicit
|
||||
ostream_buffer(DynamicBuffer& b)
|
||||
: b_(b)
|
||||
{
|
||||
}
|
||||
|
||||
int_type
|
||||
overflow(int_type ch) override
|
||||
{
|
||||
BOOST_ASSERT(! Traits::eq_int_type(
|
||||
ch, Traits::eof()));
|
||||
sync();
|
||||
|
||||
static std::size_t constexpr max_size = 65536;
|
||||
auto const max_prepare = std::min<std::size_t>(
|
||||
std::max<std::size_t>(
|
||||
512, b_.capacity() - b_.size()),
|
||||
std::min<std::size_t>(
|
||||
max_size, b_.max_size() - b_.size()));
|
||||
if(max_prepare == 0)
|
||||
return Traits::eof();
|
||||
auto const bs = b_.prepare(max_prepare);
|
||||
auto const b = buffers_front(bs);
|
||||
auto const p = static_cast<CharT*>(b.data());
|
||||
this->setp(p, p + b.size() / sizeof(CharT));
|
||||
|
||||
BOOST_ASSERT(b_.capacity() > b_.size());
|
||||
return this->sputc(
|
||||
Traits::to_char_type(ch));
|
||||
}
|
||||
|
||||
int
|
||||
sync() override
|
||||
{
|
||||
b_.commit(
|
||||
(this->pptr() - this->pbase()) *
|
||||
sizeof(CharT));
|
||||
this->setp(nullptr, nullptr);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class DynamicBuffer,
|
||||
class CharT, class Traits, bool isMovable>
|
||||
class ostream_helper;
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
class ostream_helper<
|
||||
DynamicBuffer, CharT, Traits, true>
|
||||
: public std::basic_ostream<CharT, Traits>
|
||||
{
|
||||
ostream_buffer<
|
||||
DynamicBuffer, CharT, Traits, true> osb_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
ostream_helper(DynamicBuffer& b);
|
||||
|
||||
ostream_helper(ostream_helper&& other);
|
||||
};
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
ostream_helper<DynamicBuffer, CharT, Traits, true>::
|
||||
ostream_helper(DynamicBuffer& b)
|
||||
: std::basic_ostream<CharT, Traits>(&this->osb_)
|
||||
, osb_(b)
|
||||
{
|
||||
}
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
ostream_helper<DynamicBuffer, CharT, Traits, true>::
|
||||
ostream_helper(ostream_helper&& other)
|
||||
: std::basic_ostream<CharT, Traits>(&osb_)
|
||||
, osb_(std::move(other.osb_))
|
||||
{
|
||||
}
|
||||
|
||||
// This work-around is for libstdc++ versions that
|
||||
// don't have a movable std::basic_streambuf
|
||||
|
||||
template<class T>
|
||||
class ostream_helper_base
|
||||
{
|
||||
protected:
|
||||
std::unique_ptr<T> member;
|
||||
|
||||
ostream_helper_base(
|
||||
ostream_helper_base&&) = default;
|
||||
|
||||
explicit
|
||||
ostream_helper_base(T* t)
|
||||
: member(t)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class DynamicBuffer, class CharT, class Traits>
|
||||
class ostream_helper<
|
||||
DynamicBuffer, CharT, Traits, false>
|
||||
: private ostream_helper_base<ostream_buffer<
|
||||
DynamicBuffer, CharT, Traits, false>>
|
||||
, public std::basic_ostream<CharT, Traits>
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
ostream_helper(DynamicBuffer& b)
|
||||
: ostream_helper_base<ostream_buffer<
|
||||
DynamicBuffer, CharT, Traits, false>>(
|
||||
new ostream_buffer<DynamicBuffer,
|
||||
CharT, Traits, false>(b))
|
||||
, std::basic_ostream<CharT, Traits>(
|
||||
this->member.get())
|
||||
{
|
||||
}
|
||||
|
||||
ostream_helper(ostream_helper&& other)
|
||||
: ostream_helper_base<ostream_buffer<
|
||||
DynamicBuffer, CharT, Traits, false>>(
|
||||
std::move(other))
|
||||
, std::basic_ostream<CharT, Traits>(
|
||||
this->member.get())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_PCG_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_PCG_HPP
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
class pcg
|
||||
{
|
||||
std::uint64_t state_ = 0;
|
||||
std::uint64_t increment_;
|
||||
|
||||
public:
|
||||
using result_type = std::uint32_t;
|
||||
|
||||
// Initialize the generator.
|
||||
// There are no restrictions on the input values.
|
||||
pcg(
|
||||
std::uint64_t seed,
|
||||
std::uint64_t stream)
|
||||
{
|
||||
// increment must be odd
|
||||
increment_ = 2 * stream + 1;
|
||||
boost::ignore_unused((*this)());
|
||||
state_ += seed;
|
||||
boost::ignore_unused((*this)());
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
operator()()
|
||||
{
|
||||
std::uint64_t const p = state_;
|
||||
state_ = p *
|
||||
6364136223846793005ULL +
|
||||
increment_;
|
||||
std::uint32_t const x =
|
||||
static_cast<std::uint32_t>(
|
||||
((p >> 18) ^ p) >> 27);
|
||||
std::uint32_t const r = p >> 59;
|
||||
#ifdef BOOST_MSVC
|
||||
return _rotr(x, r);
|
||||
#else
|
||||
return (x >> r) | (x << ((1 + ~r) & 31));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
//
|
||||
// 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_DETAIL_READ_HPP
|
||||
#define BOOST_BEAST_DETAIL_READ_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/beast/core/stream_traits.hpp>
|
||||
#include <boost/beast/core/detail/is_invocable.hpp>
|
||||
#include <boost/asio/async_result.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Read data into a dynamic buffer from a stream until a condition is met.
|
||||
|
||||
This function is used to read from a stream into a dynamic buffer until
|
||||
a condition is met. The call will block until one of the following is true:
|
||||
|
||||
@li The specified dynamic buffer sequence is full (that is, it has
|
||||
reached its currently configured maximum size).
|
||||
|
||||
@li The `completion_condition` function object returns 0.
|
||||
|
||||
This operation is implemented in terms of zero or more calls to the
|
||||
stream's `read_some` function.
|
||||
|
||||
@param stream The stream from which the data is to be read. The type
|
||||
must support the <em>SyncReadStream</em> requirements.
|
||||
|
||||
@param buffer The dynamic buffer sequence into which the data will be read.
|
||||
|
||||
@param completion_condition The function object to be called to determine
|
||||
whether the read operation is complete. The function object must be invocable
|
||||
with this signature:
|
||||
@code
|
||||
std::size_t
|
||||
completion_condition(
|
||||
// Modifiable result of latest read_some operation.
|
||||
error_code& ec,
|
||||
|
||||
// Number of bytes transferred so far.
|
||||
std::size_t bytes_transferred
|
||||
|
||||
// The dynamic buffer used to store the bytes read
|
||||
DynamicBuffer& buffer
|
||||
);
|
||||
@endcode
|
||||
A non-zero return value indicates the maximum number of bytes to be read on
|
||||
the next call to the stream's `read_some` function. A return value of 0
|
||||
from the completion condition indicates that the read operation is complete;
|
||||
in this case the optionally modifiable error passed to the completion
|
||||
condition will be delivered to the caller as an exception.
|
||||
|
||||
@returns The number of bytes transferred from the stream.
|
||||
|
||||
@throws net::system_error Thrown on failure.
|
||||
*/
|
||||
template<
|
||||
class SyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
, class = typename std::enable_if<
|
||||
is_sync_read_stream<SyncReadStream>::value &&
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value &&
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value
|
||||
>::type
|
||||
#endif
|
||||
>
|
||||
std::size_t
|
||||
read(
|
||||
SyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition completion_condition);
|
||||
|
||||
/** Read data into a dynamic buffer from a stream until a condition is met.
|
||||
|
||||
This function is used to read from a stream into a dynamic buffer until
|
||||
a condition is met. The call will block until one of the following is true:
|
||||
|
||||
@li The specified dynamic buffer sequence is full (that is, it has
|
||||
reached its currently configured maximum size).
|
||||
|
||||
@li The `completion_condition` function object returns 0.
|
||||
|
||||
This operation is implemented in terms of zero or more calls to the
|
||||
stream's `read_some` function.
|
||||
|
||||
@param stream The stream from which the data is to be read. The type
|
||||
must support the <em>SyncReadStream</em> requirements.
|
||||
|
||||
@param buffer The dynamic buffer sequence into which the data will be read.
|
||||
|
||||
@param completion_condition The function object to be called to determine
|
||||
whether the read operation is complete. The function object must be invocable
|
||||
with this signature:
|
||||
@code
|
||||
std::size_t
|
||||
completion_condition(
|
||||
// Modifiable result of latest read_some operation.
|
||||
error_code& ec,
|
||||
|
||||
// Number of bytes transferred so far.
|
||||
std::size_t bytes_transferred
|
||||
|
||||
// The dynamic buffer used to store the bytes read
|
||||
DynamicBuffer& buffer
|
||||
);
|
||||
@endcode
|
||||
A non-zero return value indicates the maximum number of bytes to be read on
|
||||
the next call to the stream's `read_some` function. A return value of 0
|
||||
from the completion condition indicates that the read operation is complete;
|
||||
in this case the optionally modifiable error passed to the completion
|
||||
condition will be delivered to the caller.
|
||||
|
||||
@returns The number of bytes transferred from the stream.
|
||||
*/
|
||||
template<
|
||||
class SyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
, class = typename std::enable_if<
|
||||
is_sync_read_stream<SyncReadStream>::value &&
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value &&
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value
|
||||
>::type
|
||||
#endif
|
||||
>
|
||||
std::size_t
|
||||
read(
|
||||
SyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition completion_condition,
|
||||
error_code& ec);
|
||||
|
||||
/** Asynchronously read data into a dynamic buffer from a stream until a condition is met.
|
||||
|
||||
This function is used to asynchronously read from a stream into a dynamic
|
||||
buffer until a condition is met. The function call always returns immediately.
|
||||
The asynchronous operation will continue until one of the following is true:
|
||||
|
||||
@li The specified dynamic buffer sequence is full (that is, it has
|
||||
reached its currently configured maximum size).
|
||||
|
||||
@li The `completion_condition` function object returns 0.
|
||||
|
||||
This operation is implemented in terms of zero or more calls to the stream's
|
||||
`async_read_some` function, and is known as a <em>composed operation</em>. The
|
||||
program must ensure that the stream performs no other read operations (such
|
||||
as `async_read`, the stream's `async_read_some` function, or any other composed
|
||||
operations that perform reads) until this operation completes.
|
||||
|
||||
@param stream The stream from which the data is to be read. The type must
|
||||
support the <em>AsyncReadStream</em> requirements.
|
||||
|
||||
@param buffer The dynamic buffer sequence into which the data will be read.
|
||||
Ownership of the object is retained by the caller, which must guarantee
|
||||
that it remains valid until the handler is called.
|
||||
|
||||
@param completion_condition The function object to be called to determine
|
||||
whether the read operation is complete. The function object must be invocable
|
||||
with this signature:
|
||||
@code
|
||||
std::size_t
|
||||
completion_condition(
|
||||
// Modifiable result of latest async_read_some operation.
|
||||
error_code& ec,
|
||||
|
||||
// Number of bytes transferred so far.
|
||||
std::size_t bytes_transferred,
|
||||
|
||||
// The dynamic buffer used to store the bytes read
|
||||
DynamicBuffer& buffer
|
||||
);
|
||||
@endcode
|
||||
A non-zero return value indicates the maximum number of bytes to be read on
|
||||
the next call to the stream's `async_read_some` function. A return value of 0
|
||||
from the completion condition indicates that the read operation is complete;
|
||||
in this case the optionally modifiable error passed to the completion
|
||||
condition will be delivered to the completion handler.
|
||||
|
||||
@param handler The completion handler to invoke when the operation
|
||||
completes. The implementation takes ownership of the handler by
|
||||
performing a decay-copy. The equivalent function signature of
|
||||
the handler must be:
|
||||
@code
|
||||
void
|
||||
handler(
|
||||
error_code const& ec, // Result of operation.
|
||||
|
||||
std::size_t bytes_transferred // Number of bytes copied into
|
||||
// the dynamic buffer. If an error
|
||||
// occurred, this will be the number
|
||||
// of bytes successfully transferred
|
||||
// prior to the error.
|
||||
);
|
||||
@endcode
|
||||
If the handler has an associated immediate executor,
|
||||
an immediate completion will be dispatched to it.
|
||||
Otherwise, the handler will not be invoked from within
|
||||
this function. Invocation of the handler will be performed in a
|
||||
manner equivalent to using `net::post`.
|
||||
*/
|
||||
template<
|
||||
class AsyncReadStream,
|
||||
class DynamicBuffer,
|
||||
class CompletionCondition,
|
||||
BOOST_BEAST_ASYNC_TPARAM2 ReadHandler
|
||||
#if ! BOOST_BEAST_DOXYGEN
|
||||
, class = typename std::enable_if<
|
||||
is_async_read_stream<AsyncReadStream>::value &&
|
||||
net::is_dynamic_buffer<DynamicBuffer>::value &&
|
||||
detail::is_invocable<CompletionCondition,
|
||||
void(error_code&, std::size_t, DynamicBuffer&)>::value
|
||||
>::type
|
||||
#endif
|
||||
>
|
||||
BOOST_BEAST_ASYNC_RESULT2(ReadHandler)
|
||||
async_read(
|
||||
AsyncReadStream& stream,
|
||||
DynamicBuffer& buffer,
|
||||
CompletionCondition&& completion_condition,
|
||||
ReadHandler&& handler);
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#include <boost/beast/core/detail/impl/read.hpp>
|
||||
|
||||
#endif
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// 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_DETAIL_REMAP_POST_TO_DEFER_HPP
|
||||
#define BOOST_BEAST_DETAIL_REMAP_POST_TO_DEFER_HPP
|
||||
|
||||
#include <boost/asio/is_executor.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class Executor>
|
||||
class remap_post_to_defer
|
||||
: private boost::empty_value<Executor>
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
net::is_executor<Executor>::value);
|
||||
|
||||
Executor const&
|
||||
ex() const noexcept
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
public:
|
||||
remap_post_to_defer(
|
||||
remap_post_to_defer&&) = default;
|
||||
|
||||
remap_post_to_defer(
|
||||
remap_post_to_defer const&) = default;
|
||||
|
||||
explicit
|
||||
remap_post_to_defer(
|
||||
Executor const& ex)
|
||||
: boost::empty_value<Executor>(
|
||||
boost::empty_init_t{}, ex)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(
|
||||
remap_post_to_defer const& other) const noexcept
|
||||
{
|
||||
return ex() == other.ex();
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(
|
||||
remap_post_to_defer const& other) const noexcept
|
||||
{
|
||||
return ex() != other.ex();
|
||||
}
|
||||
|
||||
decltype(std::declval<Executor const&>().context())
|
||||
context() const noexcept
|
||||
{
|
||||
return ex().context();
|
||||
}
|
||||
|
||||
void
|
||||
on_work_started() const noexcept
|
||||
{
|
||||
ex().on_work_started();
|
||||
}
|
||||
|
||||
void
|
||||
on_work_finished() const noexcept
|
||||
{
|
||||
ex().on_work_finished();
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
dispatch(F&& f, A const& a) const
|
||||
{
|
||||
ex().dispatch(std::forward<F>(f), a);
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
post(F&& f, A const& a) const
|
||||
{
|
||||
ex().defer(std::forward<F>(f), a);
|
||||
}
|
||||
|
||||
template<class F, class A>
|
||||
void
|
||||
defer(F&& f, A const& a) const
|
||||
{
|
||||
ex().defer(std::forward<F>(f), a);
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// 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_DETAIL_SERVICE_BASE_HPP
|
||||
#define BOOST_BEAST_DETAIL_SERVICE_BASE_HPP
|
||||
|
||||
#include <boost/asio/execution_context.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
struct service_base : net::execution_context::service
|
||||
{
|
||||
static net::execution_context::id const id;
|
||||
|
||||
explicit
|
||||
service_base(net::execution_context& ctx)
|
||||
: net::execution_context::service(ctx)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
net::execution_context::id const service_base<T>::id;
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// 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_DETAIL_SHA1_HPP
|
||||
#define BOOST_BEAST_DETAIL_SHA1_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
// Based on https://github.com/vog/sha1
|
||||
/*
|
||||
Original authors:
|
||||
Steve Reid (Original C Code)
|
||||
Bruce Guenter (Small changes to fit into bglibs)
|
||||
Volker Grabsch (Translation to simpler C++ Code)
|
||||
Eugene Hopkinson (Safety improvements)
|
||||
Vincent Falco (beast adaptation)
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
namespace sha1 {
|
||||
|
||||
static std::size_t constexpr BLOCK_INTS = 16;
|
||||
static std::size_t constexpr BLOCK_BYTES = 64;
|
||||
static std::size_t constexpr DIGEST_BYTES = 20;
|
||||
|
||||
} // sha1
|
||||
|
||||
struct sha1_context
|
||||
{
|
||||
static unsigned int constexpr block_size = sha1::BLOCK_BYTES;
|
||||
static unsigned int constexpr digest_size = 20;
|
||||
|
||||
std::size_t buflen;
|
||||
std::size_t blocks;
|
||||
std::uint32_t digest[5];
|
||||
std::uint8_t buf[block_size];
|
||||
};
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
init(sha1_context& ctx) noexcept;
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
update(
|
||||
sha1_context& ctx,
|
||||
void const* message,
|
||||
std::size_t size) noexcept;
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
finish(
|
||||
sha1_context& ctx,
|
||||
void* digest) noexcept;
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_BEAST_HEADER_ONLY
|
||||
#include <boost/beast/core/detail/sha1.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
//
|
||||
// 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_DETAIL_SHA1_IPP
|
||||
#define BOOST_BEAST_DETAIL_SHA1_IPP
|
||||
|
||||
#include <boost/beast/core/detail/sha1.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
// Based on https://github.com/vog/sha1
|
||||
/*
|
||||
Original authors:
|
||||
Steve Reid (Original C Code)
|
||||
Bruce Guenter (Small changes to fit into bglibs)
|
||||
Volker Grabsch (Translation to simpler C++ Code)
|
||||
Eugene Hopkinson (Safety improvements)
|
||||
Vincent Falco (beast adaptation)
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
namespace sha1 {
|
||||
|
||||
inline
|
||||
std::uint32_t
|
||||
rol(std::uint32_t value, std::size_t bits)
|
||||
{
|
||||
return (value << bits) | (value >> (32 - bits));
|
||||
}
|
||||
|
||||
inline
|
||||
std::uint32_t
|
||||
blk(std::uint32_t block[BLOCK_INTS], std::size_t i)
|
||||
{
|
||||
return rol(
|
||||
block[(i+13)&15] ^ block[(i+8)&15] ^
|
||||
block[(i+2)&15] ^ block[i], 1);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
R0(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
|
||||
std::uint32_t &w, std::uint32_t x, std::uint32_t y,
|
||||
std::uint32_t &z, std::size_t i)
|
||||
{
|
||||
z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
void
|
||||
R1(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
|
||||
std::uint32_t &w, std::uint32_t x, std::uint32_t y,
|
||||
std::uint32_t &z, std::size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
R2(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
|
||||
std::uint32_t &w, std::uint32_t x, std::uint32_t y,
|
||||
std::uint32_t &z, std::size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (w^x^y) + block[i] + 0x6ed9eba1 + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
R3(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
|
||||
std::uint32_t &w, std::uint32_t x, std::uint32_t y,
|
||||
std::uint32_t &z, std::size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (((w|x)&y)|(w&x)) + block[i] + 0x8f1bbcdc + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
R4(std::uint32_t block[BLOCK_INTS], std::uint32_t v,
|
||||
std::uint32_t &w, std::uint32_t x, std::uint32_t y,
|
||||
std::uint32_t &z, std::size_t i)
|
||||
{
|
||||
block[i] = blk(block, i);
|
||||
z += (w^x^y) + block[i] + 0xca62c1d6 + rol(v, 5);
|
||||
w = rol(w, 30);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
make_block(std::uint8_t const* p,
|
||||
std::uint32_t block[BLOCK_INTS])
|
||||
{
|
||||
for(std::size_t i = 0; i < BLOCK_INTS; i++)
|
||||
block[i] =
|
||||
(static_cast<std::uint32_t>(p[4*i+3])) |
|
||||
(static_cast<std::uint32_t>(p[4*i+2]))<< 8 |
|
||||
(static_cast<std::uint32_t>(p[4*i+1]))<<16 |
|
||||
(static_cast<std::uint32_t>(p[4*i+0]))<<24;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
transform(
|
||||
std::uint32_t digest[], std::uint32_t block[BLOCK_INTS])
|
||||
{
|
||||
std::uint32_t a = digest[0];
|
||||
std::uint32_t b = digest[1];
|
||||
std::uint32_t c = digest[2];
|
||||
std::uint32_t d = digest[3];
|
||||
std::uint32_t e = digest[4];
|
||||
|
||||
R0(block, a, b, c, d, e, 0);
|
||||
R0(block, e, a, b, c, d, 1);
|
||||
R0(block, d, e, a, b, c, 2);
|
||||
R0(block, c, d, e, a, b, 3);
|
||||
R0(block, b, c, d, e, a, 4);
|
||||
R0(block, a, b, c, d, e, 5);
|
||||
R0(block, e, a, b, c, d, 6);
|
||||
R0(block, d, e, a, b, c, 7);
|
||||
R0(block, c, d, e, a, b, 8);
|
||||
R0(block, b, c, d, e, a, 9);
|
||||
R0(block, a, b, c, d, e, 10);
|
||||
R0(block, e, a, b, c, d, 11);
|
||||
R0(block, d, e, a, b, c, 12);
|
||||
R0(block, c, d, e, a, b, 13);
|
||||
R0(block, b, c, d, e, a, 14);
|
||||
R0(block, a, b, c, d, e, 15);
|
||||
R1(block, e, a, b, c, d, 0);
|
||||
R1(block, d, e, a, b, c, 1);
|
||||
R1(block, c, d, e, a, b, 2);
|
||||
R1(block, b, c, d, e, a, 3);
|
||||
R2(block, a, b, c, d, e, 4);
|
||||
R2(block, e, a, b, c, d, 5);
|
||||
R2(block, d, e, a, b, c, 6);
|
||||
R2(block, c, d, e, a, b, 7);
|
||||
R2(block, b, c, d, e, a, 8);
|
||||
R2(block, a, b, c, d, e, 9);
|
||||
R2(block, e, a, b, c, d, 10);
|
||||
R2(block, d, e, a, b, c, 11);
|
||||
R2(block, c, d, e, a, b, 12);
|
||||
R2(block, b, c, d, e, a, 13);
|
||||
R2(block, a, b, c, d, e, 14);
|
||||
R2(block, e, a, b, c, d, 15);
|
||||
R2(block, d, e, a, b, c, 0);
|
||||
R2(block, c, d, e, a, b, 1);
|
||||
R2(block, b, c, d, e, a, 2);
|
||||
R2(block, a, b, c, d, e, 3);
|
||||
R2(block, e, a, b, c, d, 4);
|
||||
R2(block, d, e, a, b, c, 5);
|
||||
R2(block, c, d, e, a, b, 6);
|
||||
R2(block, b, c, d, e, a, 7);
|
||||
R3(block, a, b, c, d, e, 8);
|
||||
R3(block, e, a, b, c, d, 9);
|
||||
R3(block, d, e, a, b, c, 10);
|
||||
R3(block, c, d, e, a, b, 11);
|
||||
R3(block, b, c, d, e, a, 12);
|
||||
R3(block, a, b, c, d, e, 13);
|
||||
R3(block, e, a, b, c, d, 14);
|
||||
R3(block, d, e, a, b, c, 15);
|
||||
R3(block, c, d, e, a, b, 0);
|
||||
R3(block, b, c, d, e, a, 1);
|
||||
R3(block, a, b, c, d, e, 2);
|
||||
R3(block, e, a, b, c, d, 3);
|
||||
R3(block, d, e, a, b, c, 4);
|
||||
R3(block, c, d, e, a, b, 5);
|
||||
R3(block, b, c, d, e, a, 6);
|
||||
R3(block, a, b, c, d, e, 7);
|
||||
R3(block, e, a, b, c, d, 8);
|
||||
R3(block, d, e, a, b, c, 9);
|
||||
R3(block, c, d, e, a, b, 10);
|
||||
R3(block, b, c, d, e, a, 11);
|
||||
R4(block, a, b, c, d, e, 12);
|
||||
R4(block, e, a, b, c, d, 13);
|
||||
R4(block, d, e, a, b, c, 14);
|
||||
R4(block, c, d, e, a, b, 15);
|
||||
R4(block, b, c, d, e, a, 0);
|
||||
R4(block, a, b, c, d, e, 1);
|
||||
R4(block, e, a, b, c, d, 2);
|
||||
R4(block, d, e, a, b, c, 3);
|
||||
R4(block, c, d, e, a, b, 4);
|
||||
R4(block, b, c, d, e, a, 5);
|
||||
R4(block, a, b, c, d, e, 6);
|
||||
R4(block, e, a, b, c, d, 7);
|
||||
R4(block, d, e, a, b, c, 8);
|
||||
R4(block, c, d, e, a, b, 9);
|
||||
R4(block, b, c, d, e, a, 10);
|
||||
R4(block, a, b, c, d, e, 11);
|
||||
R4(block, e, a, b, c, d, 12);
|
||||
R4(block, d, e, a, b, c, 13);
|
||||
R4(block, c, d, e, a, b, 14);
|
||||
R4(block, b, c, d, e, a, 15);
|
||||
|
||||
digest[0] += a;
|
||||
digest[1] += b;
|
||||
digest[2] += c;
|
||||
digest[3] += d;
|
||||
digest[4] += e;
|
||||
}
|
||||
|
||||
} // sha1
|
||||
|
||||
void
|
||||
init(sha1_context& ctx) noexcept
|
||||
{
|
||||
ctx.buflen = 0;
|
||||
ctx.blocks = 0;
|
||||
ctx.digest[0] = 0x67452301;
|
||||
ctx.digest[1] = 0xefcdab89;
|
||||
ctx.digest[2] = 0x98badcfe;
|
||||
ctx.digest[3] = 0x10325476;
|
||||
ctx.digest[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
void
|
||||
update(
|
||||
sha1_context& ctx,
|
||||
void const* message,
|
||||
std::size_t size) noexcept
|
||||
{
|
||||
auto p = static_cast<
|
||||
std::uint8_t const*>(message);
|
||||
for(;;)
|
||||
{
|
||||
auto const n = (std::min)(
|
||||
size, sizeof(ctx.buf) - ctx.buflen);
|
||||
std::memcpy(ctx.buf + ctx.buflen, p, n);
|
||||
ctx.buflen += n;
|
||||
if(ctx.buflen != 64)
|
||||
return;
|
||||
p += n;
|
||||
size -= n;
|
||||
ctx.buflen = 0;
|
||||
std::uint32_t block[sha1::BLOCK_INTS];
|
||||
sha1::make_block(ctx.buf, block);
|
||||
sha1::transform(ctx.digest, block);
|
||||
++ctx.blocks;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
finish(
|
||||
sha1_context& ctx,
|
||||
void* digest) noexcept
|
||||
{
|
||||
using sha1::BLOCK_INTS;
|
||||
using sha1::BLOCK_BYTES;
|
||||
|
||||
std::uint64_t total_bits =
|
||||
(ctx.blocks*64 + ctx.buflen) * 8;
|
||||
// pad
|
||||
ctx.buf[ctx.buflen++] = 0x80;
|
||||
auto const buflen = ctx.buflen;
|
||||
while(ctx.buflen < 64)
|
||||
ctx.buf[ctx.buflen++] = 0x00;
|
||||
std::uint32_t block[BLOCK_INTS];
|
||||
sha1::make_block(ctx.buf, block);
|
||||
if(buflen > BLOCK_BYTES - 8)
|
||||
{
|
||||
sha1::transform(ctx.digest, block);
|
||||
for(size_t i = 0; i < BLOCK_INTS - 2; i++)
|
||||
block[i] = 0;
|
||||
}
|
||||
|
||||
/* Append total_bits, split this uint64_t into two uint32_t */
|
||||
block[BLOCK_INTS - 1] = total_bits & 0xffffffff;
|
||||
block[BLOCK_INTS - 2] = (total_bits >> 32);
|
||||
sha1::transform(ctx.digest, block);
|
||||
for(std::size_t i = 0; i < sha1::DIGEST_BYTES/4; i++)
|
||||
{
|
||||
std::uint8_t* d =
|
||||
static_cast<std::uint8_t*>(digest) + 4 * i;
|
||||
d[3] = ctx.digest[i] & 0xff;
|
||||
d[2] = (ctx.digest[i] >> 8) & 0xff;
|
||||
d[1] = (ctx.digest[i] >> 16) & 0xff;
|
||||
d[0] = (ctx.digest[i] >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// 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_DETAIL_STATIC_CONST_HPP
|
||||
#define BOOST_BEAST_DETAIL_STATIC_CONST_HPP
|
||||
|
||||
/* This is a derivative work, original copyright:
|
||||
|
||||
Copyright Eric Niebler 2013-present
|
||||
|
||||
Use, modification and distribution is subject to 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)
|
||||
|
||||
Project home: https://github.com/ericniebler/range-v3
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct static_const
|
||||
{
|
||||
static constexpr T value {};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr T static_const<T>::value;
|
||||
|
||||
#define BOOST_BEAST_INLINE_VARIABLE(name, type) \
|
||||
namespace \
|
||||
{ \
|
||||
constexpr auto& name = \
|
||||
::boost::beast::detail::static_const<type>::value; \
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// 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_DETAIL_STATIC_OSTREAM_HPP
|
||||
#define BOOST_BEAST_DETAIL_STATIC_OSTREAM_HPP
|
||||
|
||||
#include <locale>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
|
||||
|
||||
class static_ostream_buffer
|
||||
: public std::basic_streambuf<char>
|
||||
{
|
||||
using CharT = char;
|
||||
using Traits = std::char_traits<CharT>;
|
||||
using int_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::int_type;
|
||||
using traits_type = typename
|
||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||
|
||||
char* data_;
|
||||
std::size_t size_;
|
||||
std::size_t len_ = 0;
|
||||
std::string s_;
|
||||
|
||||
public:
|
||||
static_ostream_buffer(static_ostream_buffer&&) = delete;
|
||||
static_ostream_buffer(static_ostream_buffer const&) = delete;
|
||||
|
||||
static_ostream_buffer(char* data, std::size_t size)
|
||||
: data_(data)
|
||||
, size_(size)
|
||||
{
|
||||
this->setp(data_, data_ + size - 1);
|
||||
}
|
||||
|
||||
~static_ostream_buffer() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
string_view
|
||||
str() const
|
||||
{
|
||||
if(! s_.empty())
|
||||
return {s_.data(), len_};
|
||||
return {data_, len_};
|
||||
}
|
||||
|
||||
int_type
|
||||
overflow(int_type ch) override
|
||||
{
|
||||
if(! Traits::eq_int_type(ch, Traits::eof()))
|
||||
{
|
||||
Traits::assign(*this->pptr(),
|
||||
static_cast<CharT>(ch));
|
||||
flush(1);
|
||||
prepare();
|
||||
return ch;
|
||||
}
|
||||
flush();
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
int
|
||||
sync() override
|
||||
{
|
||||
flush();
|
||||
prepare();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
prepare()
|
||||
{
|
||||
static auto const growth_factor = 1.5;
|
||||
|
||||
if(len_ < size_ - 1)
|
||||
{
|
||||
this->setp(
|
||||
data_ + len_, data_ + size_ - 2);
|
||||
return;
|
||||
}
|
||||
if(s_.empty())
|
||||
{
|
||||
s_.resize(static_cast<std::size_t>(
|
||||
growth_factor * len_));
|
||||
Traits::copy(&s_[0], data_, len_);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_.resize(static_cast<std::size_t>(
|
||||
growth_factor * len_));
|
||||
}
|
||||
this->setp(&s_[len_], &s_[len_] +
|
||||
s_.size() - len_ - 1);
|
||||
}
|
||||
|
||||
void
|
||||
flush(int extra = 0)
|
||||
{
|
||||
len_ += static_cast<std::size_t>(
|
||||
this->pptr() - this->pbase() + extra);
|
||||
}
|
||||
};
|
||||
|
||||
class static_ostream : public std::basic_ostream<char>
|
||||
{
|
||||
static_ostream_buffer osb_;
|
||||
|
||||
public:
|
||||
static_ostream(char* data, std::size_t size)
|
||||
: std::basic_ostream<char>(&this->osb_)
|
||||
, osb_(data, size)
|
||||
{
|
||||
imbue(std::locale::classic());
|
||||
}
|
||||
|
||||
string_view
|
||||
str() const
|
||||
{
|
||||
return osb_.str();
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// 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_DETAIL_STATIC_STRING_HPP
|
||||
#define BOOST_BEAST_DETAIL_STATIC_STRING_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// Maximum number of characters in the decimal
|
||||
// representation of a binary number. This includes
|
||||
// the potential minus sign.
|
||||
//
|
||||
inline
|
||||
std::size_t constexpr
|
||||
max_digits(std::size_t bytes)
|
||||
{
|
||||
return static_cast<std::size_t>(
|
||||
bytes * 2.41) + 1 + 1;
|
||||
}
|
||||
|
||||
template<class CharT, class Integer, class Traits>
|
||||
CharT*
|
||||
raw_to_string(
|
||||
CharT* buf, Integer x, std::true_type)
|
||||
{
|
||||
if(x == 0)
|
||||
{
|
||||
Traits::assign(*--buf, '0');
|
||||
return buf;
|
||||
}
|
||||
if(x < 0)
|
||||
{
|
||||
x = -x;
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
Traits::assign(*--buf, '-');
|
||||
return buf;
|
||||
}
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
template<class CharT, class Integer, class Traits>
|
||||
CharT*
|
||||
raw_to_string(
|
||||
CharT* buf, Integer x, std::false_type)
|
||||
{
|
||||
if(x == 0)
|
||||
{
|
||||
*--buf = '0';
|
||||
return buf;
|
||||
}
|
||||
for(;x > 0; x /= 10)
|
||||
Traits::assign(*--buf ,
|
||||
"0123456789"[x % 10]);
|
||||
return buf;
|
||||
}
|
||||
|
||||
template<
|
||||
class CharT,
|
||||
class Integer,
|
||||
class Traits = std::char_traits<CharT>>
|
||||
CharT*
|
||||
raw_to_string(CharT* last, std::size_t size, Integer i)
|
||||
{
|
||||
boost::ignore_unused(size);
|
||||
BOOST_ASSERT(size >= max_digits(sizeof(Integer)));
|
||||
return raw_to_string<CharT, Integer, Traits>(
|
||||
last, i, std::is_signed<Integer>{});
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
//
|
||||
// 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_CORE_DETAIL_STREAM_BASE_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_STREAM_BASE_HPP
|
||||
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/exchange.hpp>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
struct any_endpoint
|
||||
{
|
||||
template<class Error, class Endpoint>
|
||||
bool
|
||||
operator()(
|
||||
Error const&, Endpoint const&) const noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct stream_base
|
||||
{
|
||||
using clock_type = std::chrono::steady_clock;
|
||||
using time_point = typename
|
||||
std::chrono::steady_clock::time_point;
|
||||
using tick_type = std::uint64_t;
|
||||
|
||||
template<typename Executor>
|
||||
struct basic_op_state
|
||||
{
|
||||
net::basic_waitable_timer<
|
||||
std::chrono::steady_clock,
|
||||
net::wait_traits<
|
||||
std::chrono::steady_clock>,
|
||||
Executor> timer; // for timing out
|
||||
tick_type tick = 0; // counts waits
|
||||
bool pending = false; // if op is pending
|
||||
bool timeout = false; // if timed out
|
||||
|
||||
template<class... Args>
|
||||
explicit
|
||||
basic_op_state(Args&&... args)
|
||||
: timer(std::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class pending_guard
|
||||
{
|
||||
bool* b_ = nullptr;
|
||||
bool clear_ = true;
|
||||
|
||||
public:
|
||||
~pending_guard()
|
||||
{
|
||||
if(clear_ && b_)
|
||||
*b_ = false;
|
||||
}
|
||||
|
||||
pending_guard()
|
||||
: b_(nullptr)
|
||||
, clear_(true)
|
||||
{
|
||||
}
|
||||
|
||||
explicit
|
||||
pending_guard(bool& b)
|
||||
: b_(&b)
|
||||
{
|
||||
// If this assert goes off, it means you are attempting
|
||||
// to issue two of the same asynchronous I/O operation
|
||||
// at the same time, without waiting for the first one
|
||||
// to complete. For example, attempting two simultaneous
|
||||
// calls to async_read_some. Only one pending call of
|
||||
// each I/O type (read and write) is permitted.
|
||||
//
|
||||
BOOST_ASSERT(! *b_);
|
||||
*b_ = true;
|
||||
}
|
||||
|
||||
pending_guard(
|
||||
pending_guard&& other) noexcept
|
||||
: b_(other.b_)
|
||||
, clear_(boost::exchange(
|
||||
other.clear_, false))
|
||||
{
|
||||
}
|
||||
|
||||
void assign(bool& b)
|
||||
{
|
||||
BOOST_ASSERT(!b_);
|
||||
BOOST_ASSERT(clear_);
|
||||
b_ = &b;
|
||||
|
||||
// If this assert goes off, it means you are attempting
|
||||
// to issue two of the same asynchronous I/O operation
|
||||
// at the same time, without waiting for the first one
|
||||
// to complete. For example, attempting two simultaneous
|
||||
// calls to async_read_some. Only one pending call of
|
||||
// each I/O type (read and write) is permitted.
|
||||
//
|
||||
BOOST_ASSERT(! *b_);
|
||||
*b_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
BOOST_ASSERT(clear_);
|
||||
if (b_)
|
||||
*b_ = false;
|
||||
clear_ = false;
|
||||
}
|
||||
};
|
||||
|
||||
static time_point never() noexcept
|
||||
{
|
||||
return (time_point::max)();
|
||||
}
|
||||
|
||||
static std::size_t constexpr no_limit =
|
||||
(std::numeric_limits<std::size_t>::max)();
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// 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_DETAIL_STREAM_TRAITS_HPP
|
||||
#define BOOST_BEAST_DETAIL_STREAM_TRAITS_HPP
|
||||
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// get_lowest_layer
|
||||
// lowest_layer_type
|
||||
// detail::has_next_layer
|
||||
//
|
||||
|
||||
template <class T>
|
||||
std::false_type has_next_layer_impl(void*);
|
||||
|
||||
template <class T>
|
||||
auto has_next_layer_impl(decltype(nullptr)) ->
|
||||
decltype(std::declval<T&>().next_layer(), std::true_type{});
|
||||
|
||||
template <class T>
|
||||
using has_next_layer = decltype(has_next_layer_impl<T>(nullptr));
|
||||
|
||||
template<class T, bool = has_next_layer<T>::value>
|
||||
struct lowest_layer_type_impl
|
||||
{
|
||||
using type = typename std::remove_reference<T>::type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct lowest_layer_type_impl<T, true>
|
||||
{
|
||||
using type = typename lowest_layer_type_impl<
|
||||
decltype(std::declval<T&>().next_layer())>::type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using lowest_layer_type = typename
|
||||
lowest_layer_type_impl<T>::type;
|
||||
|
||||
template<class T>
|
||||
T&
|
||||
get_lowest_layer_impl(
|
||||
T& t, std::false_type) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
lowest_layer_type<T>&
|
||||
get_lowest_layer_impl(
|
||||
T& t, std::true_type) noexcept
|
||||
{
|
||||
return get_lowest_layer_impl(t.next_layer(),
|
||||
has_next_layer<typename std::decay<
|
||||
decltype(t.next_layer())>::type>{});
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
template<class BufferType>
|
||||
struct BufferSequence
|
||||
{
|
||||
using value_type = BufferType;
|
||||
using const_iterator = BufferType const*;
|
||||
~BufferSequence() = default;
|
||||
BufferSequence(BufferSequence const&) = default;
|
||||
const_iterator begin() const noexcept { return {}; }
|
||||
const_iterator end() const noexcept { return {}; }
|
||||
};
|
||||
using ConstBufferSequence =
|
||||
BufferSequence<net::const_buffer>;
|
||||
using MutableBufferSequence =
|
||||
BufferSequence<net::mutable_buffer>;
|
||||
|
||||
//
|
||||
|
||||
// Types that meet the requirements,
|
||||
// for use with std::declval only.
|
||||
struct StreamHandler
|
||||
{
|
||||
StreamHandler(StreamHandler const&) = default;
|
||||
void operator()(error_code, std::size_t) {}
|
||||
};
|
||||
using ReadHandler = StreamHandler;
|
||||
using WriteHandler = StreamHandler;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// 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_DETAIL_STRING_HPP
|
||||
#define BOOST_BEAST_DETAIL_STRING_HPP
|
||||
|
||||
#include <boost/beast/core/string_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Pulling in the UDL directly breaks in some places on MSVC,
|
||||
// so introduce a namespace for this purprose.
|
||||
namespace string_literals {
|
||||
|
||||
inline
|
||||
string_view
|
||||
operator"" _sv(char const* p, std::size_t n)
|
||||
{
|
||||
return string_view{p, n};
|
||||
}
|
||||
|
||||
} // string_literals
|
||||
|
||||
inline
|
||||
char
|
||||
ascii_tolower(char c)
|
||||
{
|
||||
return ((static_cast<unsigned>(c) - 65U) < 26) ?
|
||||
c + 'a' - 'A' : c;
|
||||
}
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Copyright (c) 2019 Damian Jarek(damian.jarek93@gmail.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_DETAIL_TEMPORARY_BUFFER_HPP
|
||||
#define BOOST_BEAST_DETAIL_TEMPORARY_BUFFER_HPP
|
||||
|
||||
#include <boost/beast/core/detail/config.hpp>
|
||||
#include <boost/beast/core/string.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
struct temporary_buffer
|
||||
{
|
||||
temporary_buffer() = default;
|
||||
temporary_buffer(temporary_buffer const&) = delete;
|
||||
temporary_buffer& operator=(temporary_buffer const&) = delete;
|
||||
|
||||
~temporary_buffer() noexcept
|
||||
{
|
||||
deallocate(data_);
|
||||
}
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
append(string_view s);
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
append(string_view s1, string_view s2);
|
||||
|
||||
string_view
|
||||
view() const noexcept
|
||||
{
|
||||
return {data_, size_};
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
unchecked_append(string_view s);
|
||||
|
||||
BOOST_BEAST_DECL
|
||||
void
|
||||
grow(std::size_t n);
|
||||
|
||||
void
|
||||
deallocate(char* data) noexcept
|
||||
{
|
||||
if (data != buffer_)
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
char buffer_[4096];
|
||||
char* data_ = buffer_;
|
||||
std::size_t capacity_ = sizeof(buffer_);
|
||||
std::size_t size_ = 0;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#ifdef BOOST_BEAST_HEADER_ONLY
|
||||
#include <boost/beast/core/detail/impl/temporary_buffer.ipp>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
//
|
||||
// Copyright (c) 2016-2019 Damian Jarek (damian dot jarek93 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_DETAIL_TUPLE_HPP
|
||||
#define BOOST_BEAST_DETAIL_TUPLE_HPP
|
||||
|
||||
#include <boost/mp11/integer_sequence.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/copy_cv.hpp>
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<std::size_t I, class T>
|
||||
struct tuple_element_impl
|
||||
{
|
||||
T t;
|
||||
|
||||
tuple_element_impl(T const& t_)
|
||||
: t(t_)
|
||||
{
|
||||
}
|
||||
|
||||
tuple_element_impl(T&& t_)
|
||||
: t(std::move(t_))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<std::size_t I, class T>
|
||||
struct tuple_element_impl<I, T&>
|
||||
{
|
||||
T& t;
|
||||
|
||||
tuple_element_impl(T& t_)
|
||||
: t(t_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
struct tuple_impl;
|
||||
|
||||
template<class... Ts, std::size_t... Is>
|
||||
struct tuple_impl<
|
||||
boost::mp11::index_sequence<Is...>, Ts...>
|
||||
: tuple_element_impl<Is, Ts>...
|
||||
{
|
||||
template<class... Us>
|
||||
explicit tuple_impl(Us&&... us)
|
||||
: tuple_element_impl<Is, Ts>(
|
||||
std::forward<Us>(us))...
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
struct tuple : tuple_impl<
|
||||
boost::mp11::index_sequence_for<Ts...>, Ts...>
|
||||
{
|
||||
template<class... Us>
|
||||
explicit tuple(Us&&... us)
|
||||
: tuple_impl<
|
||||
boost::mp11::index_sequence_for<Ts...>, Ts...>{
|
||||
std::forward<Us>(us)...}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<std::size_t I, class T>
|
||||
T&
|
||||
get(tuple_element_impl<I, T>& te)
|
||||
{
|
||||
return te.t;
|
||||
}
|
||||
|
||||
template<std::size_t I, class T>
|
||||
T const&
|
||||
get(tuple_element_impl<I, T> const& te)
|
||||
{
|
||||
return te.t;
|
||||
}
|
||||
|
||||
template<std::size_t I, class T>
|
||||
T&&
|
||||
get(tuple_element_impl<I, T>&& te)
|
||||
{
|
||||
return std::move(te.t);
|
||||
}
|
||||
|
||||
template<std::size_t I, class T>
|
||||
T&
|
||||
get(tuple_element_impl<I, T&>&& te)
|
||||
{
|
||||
return te.t;
|
||||
}
|
||||
|
||||
template <std::size_t I, class T>
|
||||
using tuple_element = typename boost::copy_cv<
|
||||
mp11::mp_at_c<typename remove_cv<T>::type, I>, T>::type;
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// 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_DETAIL_TYPE_TRAITS_HPP
|
||||
#define BOOST_BEAST_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <type_traits>
|
||||
#include <new>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class U>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return sizeof(U);
|
||||
}
|
||||
|
||||
template<class U0, class U1, class... Us>
|
||||
std::size_t constexpr
|
||||
max_sizeof()
|
||||
{
|
||||
return
|
||||
max_sizeof<U0>() > max_sizeof<U1, Us...>() ?
|
||||
max_sizeof<U0>() : max_sizeof<U1, Us...>();
|
||||
}
|
||||
|
||||
template<class U>
|
||||
std::size_t constexpr
|
||||
max_alignof()
|
||||
{
|
||||
return alignof(U);
|
||||
}
|
||||
|
||||
template<class U0, class U1, class... Us>
|
||||
std::size_t constexpr
|
||||
max_alignof()
|
||||
{
|
||||
return
|
||||
max_alignof<U0>() > max_alignof<U1, Us...>() ?
|
||||
max_alignof<U0>() : max_alignof<U1, Us...>();
|
||||
}
|
||||
|
||||
// (since C++17)
|
||||
template<class... Ts>
|
||||
using make_void = boost::make_void<Ts...>;
|
||||
template<class... Ts>
|
||||
using void_t = boost::void_t<Ts...>;
|
||||
|
||||
// (since C++11) missing from g++4.8
|
||||
template<std::size_t Len, class... Ts>
|
||||
struct aligned_union
|
||||
{
|
||||
static
|
||||
std::size_t constexpr alignment_value =
|
||||
max_alignof<Ts...>();
|
||||
|
||||
using type = typename boost::aligned_storage<
|
||||
(Len > max_sizeof<Ts...>()) ? Len : (max_sizeof<Ts...>()),
|
||||
alignment_value>::type;
|
||||
};
|
||||
|
||||
template<std::size_t Len, class... Ts>
|
||||
using aligned_union_t =
|
||||
typename aligned_union<Len, Ts...>::type;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class U>
|
||||
T launder_cast(U* u)
|
||||
{
|
||||
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
|
||||
return std::launder(reinterpret_cast<T>(u));
|
||||
#elif defined(BOOST_GCC) && BOOST_GCC_VERSION > 80000
|
||||
return __builtin_launder(reinterpret_cast<T>(u));
|
||||
#else
|
||||
return reinterpret_cast<T>(u);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
//
|
||||
// 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_DETAIL_VARIANT_HPP
|
||||
#define BOOST_BEAST_DETAIL_VARIANT_HPP
|
||||
|
||||
#include <boost/beast/core/detail/type_traits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// This simple variant gets the job done without
|
||||
// causing too much trouble with template depth:
|
||||
//
|
||||
// * Always allows an empty state I==0
|
||||
// * emplace() and get() support 1-based indexes only
|
||||
// * Basic exception guarantee
|
||||
// * Max 255 types
|
||||
//
|
||||
template<class... TN>
|
||||
class variant
|
||||
{
|
||||
detail::aligned_union_t<1, TN...> buf_;
|
||||
unsigned char i_ = 0;
|
||||
|
||||
struct destroy
|
||||
{
|
||||
variant& self;
|
||||
|
||||
void operator()(mp11::mp_size_t<0>)
|
||||
{
|
||||
}
|
||||
|
||||
template<class I>
|
||||
void operator()(I) noexcept
|
||||
{
|
||||
using T =
|
||||
mp11::mp_at_c<variant, I::value - 1>;
|
||||
detail::launder_cast<T*>(&self.buf_)->~T();
|
||||
}
|
||||
};
|
||||
|
||||
struct copy
|
||||
{
|
||||
variant& self;
|
||||
variant const& other;
|
||||
|
||||
void operator()(mp11::mp_size_t<0>)
|
||||
{
|
||||
}
|
||||
|
||||
template<class I>
|
||||
void operator()(I)
|
||||
{
|
||||
using T =
|
||||
mp11::mp_at_c<variant, I::value - 1>;
|
||||
::new(&self.buf_) T(
|
||||
*detail::launder_cast<T const*>(&other.buf_));
|
||||
self.i_ = I::value;
|
||||
}
|
||||
};
|
||||
|
||||
struct move
|
||||
{
|
||||
variant& self;
|
||||
variant& other;
|
||||
|
||||
void operator()(mp11::mp_size_t<0>)
|
||||
{
|
||||
}
|
||||
|
||||
template<class I>
|
||||
void operator()(I)
|
||||
{
|
||||
using T =
|
||||
mp11::mp_at_c<variant, I::value - 1>;
|
||||
::new(&self.buf_) T(std::move(
|
||||
*detail::launder_cast<T*>(&other.buf_)));
|
||||
detail::launder_cast<T*>(&other.buf_)->~T();
|
||||
self.i_ = I::value;
|
||||
}
|
||||
};
|
||||
|
||||
struct equals
|
||||
{
|
||||
variant const& self;
|
||||
variant const& other;
|
||||
|
||||
bool operator()(mp11::mp_size_t<0>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class I>
|
||||
bool operator()(I)
|
||||
{
|
||||
using T =
|
||||
mp11::mp_at_c<variant, I::value - 1>;
|
||||
return
|
||||
*detail::launder_cast<T const*>(&self.buf_) ==
|
||||
*detail::launder_cast<T const*>(&other.buf_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void destruct()
|
||||
{
|
||||
mp11::mp_with_index<
|
||||
sizeof...(TN) + 1>(
|
||||
i_, destroy{*this});
|
||||
i_ = 0;
|
||||
}
|
||||
|
||||
void copy_construct(variant const& other)
|
||||
{
|
||||
mp11::mp_with_index<
|
||||
sizeof...(TN) + 1>(
|
||||
other.i_, copy{*this, other});
|
||||
}
|
||||
|
||||
void move_construct(variant& other)
|
||||
{
|
||||
mp11::mp_with_index<
|
||||
sizeof...(TN) + 1>(
|
||||
other.i_, move{*this, other});
|
||||
other.i_ = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
variant() = default;
|
||||
|
||||
~variant()
|
||||
{
|
||||
destruct();
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(variant const& other) const
|
||||
{
|
||||
if(i_ != other.i_)
|
||||
return false;
|
||||
return mp11::mp_with_index<
|
||||
sizeof...(TN) + 1>(
|
||||
i_, equals{*this, other});
|
||||
}
|
||||
|
||||
// 0 = empty
|
||||
unsigned char
|
||||
index() const
|
||||
{
|
||||
return i_;
|
||||
}
|
||||
|
||||
// moved-from object becomes empty
|
||||
variant(variant&& other) noexcept
|
||||
{
|
||||
move_construct(other);
|
||||
}
|
||||
|
||||
variant(variant const& other)
|
||||
{
|
||||
copy_construct(other);
|
||||
}
|
||||
|
||||
// moved-from object becomes empty
|
||||
variant& operator=(variant&& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
destruct();
|
||||
move_construct(other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
variant& operator=(variant const& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
destruct();
|
||||
copy_construct(other);
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t I, class... Args>
|
||||
void
|
||||
emplace(Args&&... args) noexcept
|
||||
{
|
||||
destruct();
|
||||
::new(&buf_) mp11::mp_at_c<variant, I - 1>(
|
||||
std::forward<Args>(args)...);
|
||||
i_ = I;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
mp11::mp_at_c<variant, I - 1>&
|
||||
get()
|
||||
{
|
||||
BOOST_ASSERT(i_ == I);
|
||||
return *detail::launder_cast<
|
||||
mp11::mp_at_c<variant, I - 1>*>(&buf_);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
mp11::mp_at_c<variant, I - 1> const&
|
||||
get() const
|
||||
{
|
||||
BOOST_ASSERT(i_ == I);
|
||||
return *detail::launder_cast<
|
||||
mp11::mp_at_c<variant, I - 1> const*>(&buf_);
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
destruct();
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Copyright (c) 2017 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_DETAIL_VARINT_HPP
|
||||
#define BOOST_BEAST_DETAIL_VARINT_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
// https://developers.google.com/protocol-buffers/docs/encoding#varints
|
||||
|
||||
inline
|
||||
std::size_t
|
||||
varint_size(std::size_t value)
|
||||
{
|
||||
std::size_t n = 1;
|
||||
while(value > 127)
|
||||
{
|
||||
++n;
|
||||
value /= 128;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
template<class FwdIt>
|
||||
std::size_t
|
||||
varint_read(FwdIt& first)
|
||||
{
|
||||
using value_type = typename
|
||||
std::iterator_traits<FwdIt>::value_type;
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_integral<value_type>::value &&
|
||||
sizeof(value_type) == 1);
|
||||
std::size_t value = 0;
|
||||
std::size_t factor = 1;
|
||||
while((*first & 0x80) != 0)
|
||||
{
|
||||
value += (*first++ & 0x7f) * factor;
|
||||
factor *= 128;
|
||||
}
|
||||
value += *first++ * factor;
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class FwdIt>
|
||||
void
|
||||
varint_write(FwdIt& first, std::size_t value)
|
||||
{
|
||||
using value_type = typename
|
||||
std::iterator_traits<FwdIt>::value_type;
|
||||
BOOST_STATIC_ASSERT(
|
||||
std::is_integral<value_type>::value &&
|
||||
sizeof(value_type) == 1);
|
||||
while(value > 127)
|
||||
{
|
||||
*first++ = static_cast<value_type>(
|
||||
0x80 | value);
|
||||
value /= 128;
|
||||
}
|
||||
*first++ = static_cast<value_type>(value);
|
||||
}
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
|
||||
#endif
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// Copyright (c) 2019 Mika Fischer (mika.fischer@zoopnet.de)
|
||||
//
|
||||
// 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_CORE_DETAIL_WIN32_UNICODE_PATH_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_WIN32_UNICODE_PATH_HPP
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/beast/core/error.hpp>
|
||||
#include <boost/winapi/character_code_conversion.hpp>
|
||||
#include <boost/winapi/file_management.hpp>
|
||||
#include <boost/winapi/get_last_error.hpp>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
class win32_unicode_path
|
||||
{
|
||||
using WCHAR_ = boost::winapi::WCHAR_;
|
||||
|
||||
public:
|
||||
win32_unicode_path(const char* utf8_path, error_code& ec) {
|
||||
int ret = mb2wide(utf8_path, static_buf_.data(),
|
||||
static_buf_.size());
|
||||
if (ret == 0)
|
||||
{
|
||||
int sz = mb2wide(utf8_path, nullptr, 0);
|
||||
if (sz == 0)
|
||||
{
|
||||
ec.assign(boost::winapi::GetLastError(),
|
||||
system_category());
|
||||
return;
|
||||
}
|
||||
dynamic_buf_.resize(sz);
|
||||
int ret2 = mb2wide(utf8_path,
|
||||
dynamic_buf_.data(),
|
||||
dynamic_buf_.size());
|
||||
if (ret2 == 0)
|
||||
{
|
||||
ec.assign(boost::winapi::GetLastError(),
|
||||
system_category());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WCHAR_ const* c_str() const noexcept
|
||||
{
|
||||
return dynamic_buf_.empty()
|
||||
? static_buf_.data()
|
||||
: dynamic_buf_.data();
|
||||
}
|
||||
|
||||
private:
|
||||
int mb2wide(const char* utf8_path, WCHAR_* buf, size_t sz)
|
||||
{
|
||||
return boost::winapi::MultiByteToWideChar(
|
||||
boost::winapi::CP_UTF8_,
|
||||
boost::winapi::MB_ERR_INVALID_CHARS_,
|
||||
utf8_path, -1,
|
||||
buf, static_cast<int>(sz));
|
||||
}
|
||||
|
||||
std::array<WCHAR_, boost::winapi::MAX_PATH_> static_buf_;
|
||||
std::vector<WCHAR_> dynamic_buf_;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // beast
|
||||
} // boost
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright (c) 2020 Richard Hodges (hodges.r@gmail.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_CORE_DETAIL_WORK_GUARD_HPP
|
||||
#define BOOST_BEAST_CORE_DETAIL_WORK_GUARD_HPP
|
||||
|
||||
#include <boost/asio/executor_work_guard.hpp>
|
||||
#include <boost/asio/execution.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
template<class Executor, class Enable = void>
|
||||
struct select_work_guard;
|
||||
|
||||
template<class Executor>
|
||||
using select_work_guard_t = typename
|
||||
select_work_guard<Executor>::type;
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
template<class Executor>
|
||||
struct select_work_guard
|
||||
<
|
||||
Executor,
|
||||
typename std::enable_if
|
||||
<
|
||||
net::is_executor<Executor>::value
|
||||
>::type
|
||||
>
|
||||
{
|
||||
using type = net::executor_work_guard<Executor>;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class Executor>
|
||||
struct execution_work_guard
|
||||
{
|
||||
using executor_type = typename std::decay<decltype(
|
||||
net::prefer(std::declval<Executor const&>(),
|
||||
net::execution::outstanding_work.tracked))>::type;
|
||||
|
||||
execution_work_guard(Executor const& exec)
|
||||
: ex_(net::prefer(exec, net::execution::outstanding_work.tracked))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
executor_type
|
||||
get_executor() const noexcept
|
||||
{
|
||||
BOOST_ASSERT(ex_.has_value());
|
||||
return *ex_;
|
||||
}
|
||||
|
||||
void reset() noexcept
|
||||
{
|
||||
ex_.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
boost::optional<executor_type> ex_;
|
||||
};
|
||||
|
||||
template<class Executor>
|
||||
struct select_work_guard
|
||||
<
|
||||
Executor,
|
||||
typename std::enable_if
|
||||
<
|
||||
net::execution::is_executor<Executor>::value
|
||||
#if defined(BOOST_ASIO_NO_TS_EXECUTORS)
|
||||
|| net::is_executor<Executor>::value
|
||||
#else
|
||||
&& !net::is_executor<Executor>::value
|
||||
#endif
|
||||
>::type
|
||||
>
|
||||
{
|
||||
using type = execution_work_guard<Executor>;
|
||||
};
|
||||
|
||||
template<class Executor>
|
||||
select_work_guard_t<Executor>
|
||||
make_work_guard(Executor const& exec) noexcept
|
||||
{
|
||||
return select_work_guard_t<Executor>(exec);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_BEAST_CORE_DETAIL_WORK_GUARD_HPP
|
||||
Reference in New Issue
Block a user