mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 17:06:00 +00:00
beast, beast::asio improvements and fixes:
* New maybe_const_t alias for maybe_const * New asio::enable_wait_for_async for safe cleanup * New asio::memory_buffer, a managed boost::asio compatible buffer * shared_handler improvements: - Can be 'empty' (no stored handler). - Default constructible as 'empty'. - Safe evaluation in bool contexts, false==empty * Fix is_call_possible metafunction: - Works on empty argument lists - Works with reference types * Replace SafeBool idiom with C++11 explicit operator bool * Move IPAddress function definitions to the header * Move cyclic_iterator to container/ * Remove unused BufferType * Remove obsolete classes: - NamedPipe - ReadWriteLock - ScopedReadLock - ScopedWriteLock - LockGuard
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
#ifndef BEAST_NET_H_INCLUDED
|
||||
#define BEAST_NET_H_INCLUDED
|
||||
|
||||
#include "net/BufferType.h"
|
||||
#include "net/DynamicBuffer.h"
|
||||
|
||||
#include "net/IPEndpoint.h"
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_SAFEBOOL_H_INCLUDED
|
||||
#define BEAST_SAFEBOOL_H_INCLUDED
|
||||
|
||||
namespace beast {
|
||||
|
||||
namespace detail {
|
||||
|
||||
class SafeBoolBase
|
||||
{
|
||||
private:
|
||||
void disallowed () const { }
|
||||
|
||||
public:
|
||||
void allowed () const { }
|
||||
|
||||
protected:
|
||||
typedef void (SafeBoolBase::*boolean_t) () const;
|
||||
|
||||
SafeBoolBase () { }
|
||||
SafeBoolBase (SafeBoolBase const&) { }
|
||||
SafeBoolBase& operator= (SafeBoolBase const&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
~SafeBoolBase () { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/** Safe evaluation of class as `bool`.
|
||||
|
||||
This allows a class to be safely evaluated as a bool without the usual
|
||||
harmful side effects of the straightforward operator conversion approach.
|
||||
To use it, derive your class from SafeBool and implement `asBoolean()` as:
|
||||
|
||||
@code
|
||||
|
||||
bool asBoolean () const;
|
||||
|
||||
@endcode
|
||||
|
||||
Ideas from http://www.artima.com/cppsource/safebool.html
|
||||
|
||||
@class SafeBool
|
||||
*/
|
||||
template <typename T = void>
|
||||
class SafeBool : public detail::SafeBoolBase
|
||||
{
|
||||
public:
|
||||
operator detail::SafeBoolBase::boolean_t () const
|
||||
{
|
||||
return (static_cast <T const*> (this))->asBoolean ()
|
||||
? &SafeBoolBase::allowed : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
~SafeBool () { }
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
void operator== (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
||||
{
|
||||
lhs.disallowed ();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
void operator!= (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
||||
{
|
||||
lhs.disallowed ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#ifndef BEAST_THREADS_H_INCLUDED
|
||||
#define BEAST_THREADS_H_INCLUDED
|
||||
|
||||
#include "threads/LockGuard.h"
|
||||
#include "threads/UnlockGuard.h"
|
||||
#include "threads/TryLockGuard.h"
|
||||
#include "threads/SharedLockGuard.h"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "tests/wrap_handler_tests.cpp"
|
||||
#include "tests/bind_handler_tests.cpp"
|
||||
#include "tests/enable_wait_for_async.test.cpp"
|
||||
#include "tests/shared_handler_tests.cpp"
|
||||
|
||||
#include "abstract_socket.cpp" // TEMPORARY!
|
||||
|
||||
14
beast/asio/README.md
Normal file
14
beast/asio/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# beast::asio
|
||||
|
||||
Wrappers and utilities to make working with boost::asio easier.
|
||||
|
||||
## Rules for asynchronous objects
|
||||
|
||||
If an object calls asynchronous initiating functions it must either:
|
||||
|
||||
1. Manage its lifetime by being reference counted
|
||||
|
||||
or
|
||||
|
||||
2. Wait for all pending completion handlers to be called before
|
||||
allowing itself to be destroyed.
|
||||
@@ -99,6 +99,21 @@ public:
|
||||
{
|
||||
return m_buffers.end ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class ConstBufferSequence>
|
||||
void
|
||||
assign (ConstBufferSequence const& buffers)
|
||||
{
|
||||
auto const n (std::distance (
|
||||
std::begin (buffers), std::end (buffers)));
|
||||
|
||||
for (int i = 0, auto iter (std::begin (buffers));
|
||||
iter != std::end (buffers); ++iter, ++i)
|
||||
m_buffers[i] = Buffer (boost::asio::buffer_cast <void*> (
|
||||
*iter), boost::asio::buffer_size (*iter));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
|
||||
|
||||
265
beast/asio/enable_wait_for_async.h
Normal file
265
beast/asio/enable_wait_for_async.h
Normal file
@@ -0,0 +1,265 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
#define BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||
|
||||
#include "wrap_handler.h"
|
||||
|
||||
#include "../mpl/IsCallPossible.h"
|
||||
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include "../cxx14/type_traits.h" // <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class Owner, class Handler>
|
||||
class ref_counted_wrapped_handler
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
|
||||
"Owner cannot be a const or reference type");
|
||||
|
||||
Handler m_handler;
|
||||
std::reference_wrapper <Owner> m_owner;
|
||||
bool m_continuation;
|
||||
|
||||
public:
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler&& handler, bool continuation)
|
||||
: m_handler (std::move (handler))
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
ref_counted_wrapped_handler (Owner& owner,
|
||||
Handler const& handler, bool continuation)
|
||||
: m_handler (handler)
|
||||
, m_owner (owner)
|
||||
, m_continuation (continuation ? true :
|
||||
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
~ref_counted_wrapped_handler ()
|
||||
{
|
||||
m_owner.get().decrement();
|
||||
}
|
||||
|
||||
ref_counted_wrapped_handler (ref_counted_wrapped_handler const& other)
|
||||
: m_handler (other.m_handler)
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
ref_counted_wrapped_handler (ref_counted_wrapped_handler&& other)
|
||||
: m_handler (std::move (other.m_handler))
|
||||
, m_owner (other.m_owner)
|
||||
, m_continuation (other.m_continuation)
|
||||
{
|
||||
m_owner.get().increment();
|
||||
}
|
||||
|
||||
ref_counted_wrapped_handler& operator= (
|
||||
ref_counted_wrapped_handler const&) = delete;
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args)
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void
|
||||
operator() (Args&&... args) const
|
||||
{
|
||||
m_handler (std::forward <Args> (args)...);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
template <class Function>
|
||||
friend
|
||||
void
|
||||
asio_handler_invoke (Function const& f,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (f, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void*
|
||||
asio_handler_allocate (std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
void
|
||||
asio_handler_deallocate (void* p, std::size_t size,
|
||||
ref_counted_wrapped_handler* h)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, h->m_handler);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
asio_handler_is_continuation (ref_counted_wrapped_handler* h)
|
||||
{
|
||||
return h->m_continuation;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Facilitates blocking until no completion handlers are remaining.
|
||||
If Derived has this member function:
|
||||
|
||||
@code
|
||||
void on_wait_for_async (void)
|
||||
@endcode
|
||||
|
||||
Then it will be called every time the number of pending completion
|
||||
handlers transitions to zero from a non-zero value. The call is made
|
||||
while holding the internal mutex.
|
||||
*/
|
||||
template <class Derived>
|
||||
class enable_wait_for_async
|
||||
{
|
||||
private:
|
||||
BEAST_DEFINE_IS_CALL_POSSIBLE(
|
||||
has_on_wait_for_async,on_wait_for_async);
|
||||
|
||||
void increment()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
++m_count;
|
||||
}
|
||||
|
||||
void notify (std::true_type)
|
||||
{
|
||||
static_cast <Derived*> (this)->on_wait_for_async();
|
||||
}
|
||||
|
||||
void notify (std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||
--m_count;
|
||||
if (m_count == 0)
|
||||
{
|
||||
m_cond.notify_all();
|
||||
notify (std::integral_constant <bool,
|
||||
has_on_wait_for_async<Derived, void(void)>::value>());
|
||||
}
|
||||
}
|
||||
|
||||
template <class Owner, class Handler>
|
||||
friend class detail::ref_counted_wrapped_handler;
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cond;
|
||||
std::size_t m_count;
|
||||
|
||||
public:
|
||||
/** Blocks if there are any pending completion handlers. */
|
||||
void
|
||||
wait_for_async()
|
||||
{
|
||||
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
|
||||
while (m_count != 0)
|
||||
m_cond.wait (lock);
|
||||
}
|
||||
|
||||
protected:
|
||||
enable_wait_for_async()
|
||||
: m_count (0)
|
||||
{
|
||||
}
|
||||
|
||||
~enable_wait_for_async()
|
||||
{
|
||||
assert (m_count == 0);
|
||||
}
|
||||
|
||||
/** Wraps the specified handler so it can be counted. */
|
||||
/** @{ */
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (Handler&& handler, bool continuation = false)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), continuation);
|
||||
}
|
||||
|
||||
template <class Handler>
|
||||
detail::ref_counted_wrapped_handler <
|
||||
enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>
|
||||
>
|
||||
wrap_with_counter (continuation_t, Handler&& handler)
|
||||
{
|
||||
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||
std::remove_reference_t <Handler>> (*this,
|
||||
std::forward <Handler> (handler), true);
|
||||
}
|
||||
/** @} */
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
423
beast/asio/memory_buffer.h
Normal file
423
beast/asio/memory_buffer.h
Normal file
@@ -0,0 +1,423 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||
#define BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||
|
||||
#include "../utility/empty_base_optimization.h"
|
||||
|
||||
#include <boost/asio/buffer.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace asio {
|
||||
|
||||
template <
|
||||
class T,
|
||||
class Alloc = std::allocator <T>
|
||||
>
|
||||
class memory_buffer
|
||||
: private empty_base_optimization <Alloc>
|
||||
{
|
||||
private:
|
||||
static_assert (std::is_trivially_constructible <T>::value,
|
||||
"T must be trivially constructible");
|
||||
|
||||
typedef empty_base_optimization <Alloc> Base;
|
||||
|
||||
using AllocTraits = std::allocator_traits <Alloc>;
|
||||
|
||||
T* m_base;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef Alloc allocator_type;
|
||||
typedef T* iterator;
|
||||
typedef T const* const_iterator;
|
||||
typedef std::reverse_iterator <iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
|
||||
|
||||
memory_buffer ()
|
||||
: m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (memory_buffer&& other)
|
||||
: Base (std::move (other))
|
||||
, m_base (other.m_base)
|
||||
, m_size (other.m_size)
|
||||
{
|
||||
other.m_base = nullptr;
|
||||
other.m_size = 0;
|
||||
}
|
||||
|
||||
explicit memory_buffer (size_type n)
|
||||
: m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
explicit memory_buffer (Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
memory_buffer (size_type n, Alloc const& alloc)
|
||||
: Base (alloc)
|
||||
, m_base (AllocTraits::allocate (Base::member(), n))
|
||||
, m_size (n)
|
||||
{
|
||||
}
|
||||
|
||||
~memory_buffer()
|
||||
{
|
||||
if (m_base != nullptr)
|
||||
AllocTraits::deallocate (Base::member(), m_base, m_size);
|
||||
}
|
||||
|
||||
memory_buffer& operator= (memory_buffer const&) = delete;
|
||||
|
||||
allocator_type
|
||||
get_allocator() const
|
||||
{
|
||||
return Base::member;
|
||||
}
|
||||
|
||||
//
|
||||
// asio support
|
||||
//
|
||||
|
||||
boost::asio::mutable_buffer
|
||||
buffer()
|
||||
{
|
||||
return boost::asio::mutable_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffer
|
||||
buffer() const
|
||||
{
|
||||
return boost::asio::const_buffer (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::mutable_buffers_1
|
||||
buffers()
|
||||
{
|
||||
return boost::asio::mutable_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
boost::asio::const_buffers_1
|
||||
buffers() const
|
||||
{
|
||||
return boost::asio::const_buffers_1 (
|
||||
data(), bytes());
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffer()
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffer() const
|
||||
{
|
||||
return buffer();
|
||||
}
|
||||
|
||||
operator boost::asio::mutable_buffers_1()
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
operator boost::asio::const_buffers_1() const
|
||||
{
|
||||
return buffers();
|
||||
}
|
||||
|
||||
//
|
||||
// Element access
|
||||
//
|
||||
|
||||
reference
|
||||
at (size_type pos)
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
at (size_type pos) const
|
||||
{
|
||||
if (! (pos < size()))
|
||||
throw std::out_of_range ("bad array index");
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
operator[] (size_type pos) noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
const_reference
|
||||
operator[] (size_type pos) const noexcept
|
||||
{
|
||||
return m_base [pos];
|
||||
}
|
||||
|
||||
reference
|
||||
back() noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
const_reference
|
||||
back() const noexcept
|
||||
{
|
||||
return m_base [m_size - 1];
|
||||
}
|
||||
|
||||
reference
|
||||
front() noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
const_reference
|
||||
front() const noexcept
|
||||
{
|
||||
return *m_base;
|
||||
}
|
||||
|
||||
pointer
|
||||
data() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_pointer
|
||||
data() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
|
||||
iterator
|
||||
begin() noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
begin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cbegin() const noexcept
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
iterator
|
||||
end() noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
cend() const noexcept
|
||||
{
|
||||
return m_base + m_size;
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rbegin() noexcept
|
||||
{
|
||||
return reverse_iterator (end());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cend());
|
||||
}
|
||||
|
||||
reverse_iterator
|
||||
rend() noexcept
|
||||
{
|
||||
return reverse_iterator (begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator (cbegin());
|
||||
}
|
||||
|
||||
//
|
||||
// Capacity
|
||||
//
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
size_type
|
||||
size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type
|
||||
capacity() const noexcept
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
size_type bytes() const
|
||||
{
|
||||
return m_size * sizeof(T);
|
||||
}
|
||||
|
||||
//
|
||||
// Modifiers
|
||||
//
|
||||
|
||||
template <class U, class A>
|
||||
friend
|
||||
void
|
||||
swap (memory_buffer <U, A>& lhs,
|
||||
memory_buffer <U, A>& rhs) noexcept;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <class T, class Alloc>
|
||||
void
|
||||
swap (memory_buffer <T, Alloc>& lhs,
|
||||
memory_buffer <T, Alloc>& rhs) noexcept
|
||||
{
|
||||
std::swap (lhs.m_base, rhs.m_base);
|
||||
std::swap (lhs.m_size, rhs.m_size);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator== (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::equal (lhs.cbegin(), lhs.cend(),
|
||||
rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator!= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator< (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return std::lexicographical_compare (
|
||||
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator>= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (lhs < rhs);
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator> (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
inline
|
||||
bool
|
||||
operator<= (memory_buffer <T, A1> const& lhs,
|
||||
memory_buffer <T, A2> const& rhs)
|
||||
{
|
||||
return ! (rhs < lhs);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
#include "../mpl/IsCallPossible.h"
|
||||
|
||||
#include <functional>
|
||||
@@ -260,9 +262,7 @@ public:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Handler shared reference that provides io_service execution guarantees. */
|
||||
template <
|
||||
class Signature
|
||||
>
|
||||
template <class Signature>
|
||||
class shared_handler
|
||||
{
|
||||
private:
|
||||
@@ -318,6 +318,7 @@ public:
|
||||
operator= (std::nullptr_t)
|
||||
{
|
||||
m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
shared_handler&
|
||||
@@ -327,15 +328,17 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const
|
||||
shared_handler&
|
||||
operator= (shared_handler&& rhs)
|
||||
{
|
||||
return ! m_ptr.operator bool();
|
||||
m_ptr = std::move (rhs.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
explicit
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return !empty();
|
||||
return m_ptr.operator bool();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -225,14 +225,9 @@ private:
|
||||
|
||||
boost::asio::io_service& get_io_service () override
|
||||
{
|
||||
#if 0
|
||||
// Apparently has_get_io_service always results in false
|
||||
return get_io_service (
|
||||
Enabled <has_get_io_service <this_layer_type,
|
||||
boost::asio::io_service&()> > ());
|
||||
#else
|
||||
return get_io_service (std::true_type ());
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service (
|
||||
|
||||
108
beast/asio/tests/enable_wait_for_async.test.cpp
Normal file
108
beast/asio/tests/enable_wait_for_async.test.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "BeastConfig.h"
|
||||
|
||||
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
|
||||
|
||||
#include "../bind_handler.h"
|
||||
#include "../enable_wait_for_async.h"
|
||||
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
namespace beast {
|
||||
|
||||
class enable_wait_for_async_Tests : public UnitTest
|
||||
{
|
||||
public:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
void test()
|
||||
{
|
||||
struct handler
|
||||
{
|
||||
void operator()(error_code)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct owner : asio::enable_wait_for_async <owner>
|
||||
{
|
||||
bool notified;
|
||||
|
||||
owner()
|
||||
: notified (false)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (asio::bind_handler (handler(),
|
||||
error_code()));
|
||||
ios.run();
|
||||
ios.reset();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
ios.post (wrap_with_counter (asio::bind_handler (
|
||||
handler(), error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
handler h;
|
||||
ios.post (wrap_with_counter (std::bind (
|
||||
&handler::operator(), &h,
|
||||
error_code())));
|
||||
ios.run();
|
||||
wait_for_async();
|
||||
}
|
||||
}
|
||||
|
||||
void on_wait_for_async()
|
||||
{
|
||||
notified = true;
|
||||
}
|
||||
};
|
||||
|
||||
beginTestCase ("wait_for_async");
|
||||
owner o;
|
||||
o();
|
||||
expect (o.notified);
|
||||
}
|
||||
|
||||
void runTest()
|
||||
{
|
||||
test();
|
||||
}
|
||||
|
||||
enable_wait_for_async_Tests() : UnitTest ("enable_wait_for_async", "beast")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static enable_wait_for_async_Tests enable_wait_for_async_tests;
|
||||
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||
#define BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||
|
||||
#include "../SafeBool.h"
|
||||
#include "UnsignedIntegerCalc.h"
|
||||
#include "MurmurHash.h"
|
||||
|
||||
@@ -38,7 +37,7 @@ namespace beast {
|
||||
may not be aligned.
|
||||
*/
|
||||
template <std::size_t Bytes>
|
||||
class UnsignedInteger : public SafeBool <UnsignedInteger <Bytes> >
|
||||
class UnsignedInteger
|
||||
{
|
||||
public:
|
||||
/** Constant for determining the number of bytes. */
|
||||
@@ -201,9 +200,9 @@ public:
|
||||
|
||||
/** Support conversion to `bool`.
|
||||
@return `true` if any bit is non-zero.
|
||||
@see SafeBool
|
||||
*/
|
||||
bool asBoolean () const
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isNotZero ();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ struct DoubleWidthUInt <std::uint32_t>
|
||||
which return results by value cannot be included in the interface.
|
||||
*/
|
||||
template <typename UInt>
|
||||
class UnsignedIntegerCalc : public SafeBool <UnsignedIntegerCalc <UInt> >
|
||||
class UnsignedIntegerCalc
|
||||
{
|
||||
public:
|
||||
typedef typename detail::DoubleWidthUInt <UInt>::type UIntBig;
|
||||
@@ -182,7 +182,8 @@ public:
|
||||
}
|
||||
|
||||
/** Safe conversion to `bool`, `true` means a non-zero value. */
|
||||
bool asBoolean () const
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isNotZero ();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
||||
#define BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
||||
|
||||
#include "../cxx14/type_traits.h" // <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace mpl {
|
||||
|
||||
@@ -160,10 +162,11 @@ struct trait_name##_detail
|
||||
BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \
|
||||
}; \
|
||||
\
|
||||
template <typename T, typename IsCallPossibleSignature> \
|
||||
template <typename DT, typename IsCallPossibleSignature> \
|
||||
struct trait_name \
|
||||
{ \
|
||||
private: \
|
||||
private: \
|
||||
typedef std::remove_reference_t <DT> T; \
|
||||
class yes {}; \
|
||||
class no { yes m[2]; }; \
|
||||
struct derived : public T \
|
||||
@@ -197,6 +200,18 @@ struct trait_name
|
||||
static const bool value = false; \
|
||||
}; \
|
||||
\
|
||||
template <typename Result> \
|
||||
struct impl<true, Result(void)> \
|
||||
{ \
|
||||
static typename beast::mpl::is_call_possible_detail::add_reference<derived_type>::type test_me; \
|
||||
\
|
||||
static const bool value = \
|
||||
sizeof( \
|
||||
return_value_check<T, Result>::deduce( \
|
||||
(test_me.member_function_name(), beast::mpl::is_call_possible_detail::void_exp_result<T>())) \
|
||||
) == sizeof(yes); \
|
||||
}; \
|
||||
\
|
||||
template <typename Result, typename Arg> \
|
||||
struct impl<true, Result(Arg)> \
|
||||
{ \
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
||||
#define BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** General linear memory buffer.
|
||||
This wraps the underlying buffer type and provides additional methods
|
||||
to create a uniform interface. Specializations allow asio-compatible
|
||||
buffers without having to include boost/asio.h.
|
||||
*/
|
||||
/** @{ */
|
||||
template <bool IsConst>
|
||||
class BufferType
|
||||
{
|
||||
private:
|
||||
typedef typename std::conditional <IsConst,
|
||||
void const*, void*>::type pointer_type;
|
||||
|
||||
typedef typename std::conditional <IsConst,
|
||||
uint8 const, uint8>::type byte_type;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
|
||||
BufferType ()
|
||||
: m_data (nullptr)
|
||||
, m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
BufferType (BufferType <OtherIsConst> const& other)
|
||||
: m_data (other.template cast <pointer_type> ())
|
||||
, m_size (other.size ())
|
||||
{
|
||||
}
|
||||
|
||||
BufferType (pointer_type data, std::size_t size) noexcept
|
||||
: m_data (data)
|
||||
, m_size (size)
|
||||
{
|
||||
}
|
||||
|
||||
BufferType& operator= (BufferType const& other) noexcept
|
||||
{
|
||||
m_data = other.cast <pointer_type> ();
|
||||
m_size = other.size ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
BufferType& operator= (
|
||||
BufferType <OtherIsConst> const& other) noexcept
|
||||
{
|
||||
m_data = other.template cast <pointer_type> ();
|
||||
m_size = other.size ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T cast () const noexcept
|
||||
{
|
||||
return static_cast <T> (m_data);
|
||||
}
|
||||
|
||||
size_type size () const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
BufferType operator+ (size_type n) const noexcept
|
||||
{
|
||||
return BufferType (cast <byte_type*> (),
|
||||
size () - std::min (size(), n));
|
||||
}
|
||||
|
||||
private:
|
||||
pointer_type m_data;
|
||||
std::size_t m_size;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -40,61 +40,159 @@ class Address
|
||||
{
|
||||
public:
|
||||
/** Create an unspecified IPv4 address. */
|
||||
Address ();
|
||||
Address ()
|
||||
: m_type (ipv4)
|
||||
{
|
||||
}
|
||||
|
||||
/** Create an IPv4 address. */
|
||||
Address (AddressV4 const& addr);
|
||||
Address (AddressV4 const& addr)
|
||||
: m_type (ipv4)
|
||||
, m_v4 (addr)
|
||||
{
|
||||
}
|
||||
|
||||
/** Create an IPv6 address. */
|
||||
Address (AddressV6 const& addr);
|
||||
Address (AddressV6 const& addr)
|
||||
: m_type (ipv6)
|
||||
, m_v6 (addr)
|
||||
{
|
||||
}
|
||||
|
||||
/** Assign a copy from another address in any format. */
|
||||
/** @{ */
|
||||
Address& operator= (AddressV4 const& addr);
|
||||
Address& operator= (AddressV6 const& addr);
|
||||
Address&
|
||||
operator= (AddressV4 const& addr)
|
||||
{
|
||||
m_type = ipv4;
|
||||
m_v6 = AddressV6();
|
||||
m_v4 = addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Address&
|
||||
operator= (AddressV6 const& addr)
|
||||
{
|
||||
m_type = ipv6;
|
||||
m_v4 = AddressV4();
|
||||
m_v6 = addr;
|
||||
return *this;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Create an Address from a string.
|
||||
@return A pair with the address, and bool set to `true` on success.
|
||||
*/
|
||||
static std::pair <Address, bool> from_string (std::string const& s);
|
||||
static
|
||||
std::pair <Address, bool>
|
||||
from_string (std::string const& s);
|
||||
|
||||
/** Returns a string representing the address. */
|
||||
std::string to_string () const;
|
||||
std::string
|
||||
to_string () const
|
||||
{
|
||||
return (is_v4 ())
|
||||
? IP::to_string (to_v4())
|
||||
: IP::to_string (to_v6());
|
||||
}
|
||||
|
||||
/** Returns `true` if this address represents an IPv4 address. */
|
||||
bool is_v4 () const
|
||||
{ return m_type == ipv4; }
|
||||
bool
|
||||
is_v4 () const
|
||||
{
|
||||
return m_type == ipv4;
|
||||
}
|
||||
|
||||
/** Returns `true` if this address represents an IPv6 address. */
|
||||
bool is_v6 () const
|
||||
{ return m_type == ipv6; }
|
||||
bool
|
||||
is_v6() const
|
||||
{
|
||||
return m_type == ipv6;
|
||||
}
|
||||
|
||||
/** Returns the IPv4 address.
|
||||
Precondition:
|
||||
is_v4() returns true
|
||||
is_v4() == `true`
|
||||
*/
|
||||
AddressV4 const& to_v4 () const;
|
||||
AddressV4 const&
|
||||
to_v4 () const
|
||||
{
|
||||
if (m_type != ipv4)
|
||||
throw std::bad_cast();
|
||||
return m_v4;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the IPv6 address.
|
||||
Precondition:
|
||||
is_v6() returns true
|
||||
is_v6() == `true`
|
||||
*/
|
||||
AddressV6 const& to_v6 () const;
|
||||
AddressV6 const&
|
||||
to_v6 () const
|
||||
{
|
||||
if (m_type != ipv6)
|
||||
throw std::bad_cast();
|
||||
return m_v6;
|
||||
}
|
||||
|
||||
/** Arithmetic comparison. */
|
||||
/** @{ */
|
||||
friend bool operator== (Address const& lhs, Address const& rhs);
|
||||
friend bool operator< (Address const& lhs, Address const& rhs);
|
||||
friend
|
||||
bool
|
||||
operator== (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
if (lhs.is_v4 ())
|
||||
{
|
||||
if (rhs.is_v4 ())
|
||||
return lhs.to_v4() == rhs.to_v4();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rhs.is_v6 ())
|
||||
return lhs.to_v6() == rhs.to_v6();
|
||||
}
|
||||
|
||||
friend bool operator!= (Address const& lhs, Address const& rhs)
|
||||
{ return ! (lhs == rhs); }
|
||||
friend bool operator> (Address const& lhs, Address const& rhs)
|
||||
{ return rhs < lhs; }
|
||||
friend bool operator<= (Address const& lhs, Address const& rhs)
|
||||
{ return ! (lhs > rhs); }
|
||||
friend bool operator>= (Address const& lhs, Address const& rhs)
|
||||
{ return ! (rhs > lhs); }
|
||||
return false;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator< (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
if (lhs.m_type < rhs.m_type)
|
||||
return true;
|
||||
if (lhs.is_v4 ())
|
||||
return lhs.to_v4() < rhs.to_v4();
|
||||
return lhs.to_v6() < rhs.to_v6();
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator!= (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
return ! (lhs == rhs);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator> (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator<= (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
return ! (lhs > rhs);
|
||||
}
|
||||
|
||||
friend
|
||||
bool
|
||||
operator>= (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
return ! (rhs > lhs);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
private:
|
||||
@@ -114,36 +212,104 @@ private:
|
||||
// Properties
|
||||
|
||||
/** Returns `true` if this is a loopback address. */
|
||||
bool is_loopback (Address const& addr);
|
||||
inline
|
||||
bool
|
||||
is_loopback (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_loopback (addr.to_v4 ())
|
||||
: is_loopback (addr.to_v6 ());
|
||||
}
|
||||
|
||||
/** Returns `true` if the address is unspecified. */
|
||||
bool is_unspecified (Address const& addr);
|
||||
inline
|
||||
bool
|
||||
is_unspecified (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_unspecified (addr.to_v4 ())
|
||||
: is_unspecified (addr.to_v6 ());
|
||||
}
|
||||
|
||||
/** Returns `true` if the address is a multicast address. */
|
||||
bool is_multicast (Address const& addr);
|
||||
inline
|
||||
bool
|
||||
is_multicast (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_multicast (addr.to_v4 ())
|
||||
: is_multicast (addr.to_v6 ());
|
||||
}
|
||||
|
||||
/** Returns `true` if the address is a private unroutable address. */
|
||||
bool is_private (Address const& addr);
|
||||
inline
|
||||
bool
|
||||
is_private (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_private (addr.to_v4 ())
|
||||
: is_private (addr.to_v6 ());
|
||||
}
|
||||
|
||||
/** Returns `true` if the address is a public routable address. */
|
||||
bool is_public (Address const& addr);
|
||||
inline
|
||||
bool
|
||||
is_public (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_public (addr.to_v4 ())
|
||||
: is_public (addr.to_v6 ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** boost::hash support. */
|
||||
std::size_t hash_value (Address const& addr);
|
||||
inline
|
||||
std::size_t
|
||||
hash_value (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? hash_value (addr.to_v4())
|
||||
: hash_value (addr.to_v6());
|
||||
}
|
||||
|
||||
/** Returns the address represented as a string. */
|
||||
inline std::string to_string (Address const& addr)
|
||||
{ return addr.to_string (); }
|
||||
{
|
||||
return addr.to_string ();
|
||||
}
|
||||
|
||||
/** Output stream conversion. */
|
||||
template <typename OutputStream>
|
||||
OutputStream& operator<< (OutputStream& os, Address const& addr)
|
||||
{ return os << to_string (addr); }
|
||||
OutputStream&
|
||||
operator<< (OutputStream& os, Address const& addr)
|
||||
{
|
||||
return os << to_string (addr);
|
||||
}
|
||||
|
||||
/** Input stream conversion. */
|
||||
std::istream& operator>> (std::istream& is, Address& addr);
|
||||
inline
|
||||
std::istream&
|
||||
operator>> (std::istream& is, Address& addr)
|
||||
{
|
||||
// VFALCO TODO Support ipv6!
|
||||
AddressV4 addrv4;
|
||||
is >> addrv4;
|
||||
addr = Address (addrv4);
|
||||
return is;
|
||||
}
|
||||
|
||||
inline
|
||||
std::pair <Address, bool>
|
||||
Address::from_string (std::string const& s)
|
||||
{
|
||||
std::stringstream is (s);
|
||||
Address addr;
|
||||
is >> addr;
|
||||
if (! is.fail() && is.rdbuf()->in_avail() == 0)
|
||||
return std::make_pair (addr, true);
|
||||
return std::make_pair (Address (), false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -154,8 +320,11 @@ namespace std {
|
||||
template <>
|
||||
struct hash <beast::IP::Address>
|
||||
{
|
||||
std::size_t operator() (beast::IP::Address const& addr) const
|
||||
{ return hash_value (addr); }
|
||||
std::size_t
|
||||
operator() (beast::IP::Address const& addr) const
|
||||
{
|
||||
return hash_value (addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -25,150 +25,6 @@
|
||||
namespace beast {
|
||||
namespace IP {
|
||||
|
||||
Address::Address ()
|
||||
: m_type (ipv4)
|
||||
{
|
||||
}
|
||||
|
||||
Address::Address (AddressV4 const& addr)
|
||||
: m_type (ipv4)
|
||||
, m_v4 (addr)
|
||||
{
|
||||
}
|
||||
|
||||
Address::Address (AddressV6 const& addr)
|
||||
: m_type (ipv6)
|
||||
, m_v6 (addr)
|
||||
{
|
||||
}
|
||||
|
||||
Address& Address::operator= (AddressV4 const& addr)
|
||||
{
|
||||
m_type = ipv4;
|
||||
m_v6 = AddressV6();
|
||||
m_v4 = addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Address& Address::operator= (AddressV6 const& addr)
|
||||
{
|
||||
m_type = ipv6;
|
||||
m_v4 = AddressV4();
|
||||
m_v6 = addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair <Address, bool> Address::from_string (std::string const& s)
|
||||
{
|
||||
std::stringstream is (s);
|
||||
Address addr;
|
||||
is >> addr;
|
||||
if (! is.fail() && is.rdbuf()->in_avail() == 0)
|
||||
return std::make_pair (addr, true);
|
||||
return std::make_pair (Address (), false);
|
||||
}
|
||||
|
||||
std::string Address::to_string () const
|
||||
{
|
||||
return (is_v4 ())
|
||||
? IP::to_string (to_v4())
|
||||
: IP::to_string (to_v6());
|
||||
}
|
||||
|
||||
AddressV4 const& Address::to_v4 () const
|
||||
{
|
||||
if (m_type != ipv4)
|
||||
throw std::bad_cast();
|
||||
return m_v4;
|
||||
}
|
||||
|
||||
AddressV6 const& Address::to_v6 () const
|
||||
{
|
||||
if (m_type != ipv6)
|
||||
throw std::bad_cast();
|
||||
return m_v6;
|
||||
}
|
||||
|
||||
bool operator== (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
if (lhs.is_v4 ())
|
||||
{
|
||||
if (rhs.is_v4 ())
|
||||
return lhs.to_v4() == rhs.to_v4();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rhs.is_v6 ())
|
||||
return lhs.to_v6() == rhs.to_v6();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator< (Address const& lhs, Address const& rhs)
|
||||
{
|
||||
if (lhs.m_type < rhs.m_type)
|
||||
return true;
|
||||
if (lhs.is_v4 ())
|
||||
return lhs.to_v4() < rhs.to_v4();
|
||||
return lhs.to_v6() < rhs.to_v6();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool is_loopback (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_loopback (addr.to_v4 ())
|
||||
: is_loopback (addr.to_v6 ());
|
||||
}
|
||||
|
||||
bool is_unspecified (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_unspecified (addr.to_v4 ())
|
||||
: is_unspecified (addr.to_v6 ());
|
||||
}
|
||||
|
||||
bool is_multicast (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_multicast (addr.to_v4 ())
|
||||
: is_multicast (addr.to_v6 ());
|
||||
}
|
||||
|
||||
bool is_private (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_private (addr.to_v4 ())
|
||||
: is_private (addr.to_v6 ());
|
||||
}
|
||||
|
||||
bool is_public (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? is_public (addr.to_v4 ())
|
||||
: is_public (addr.to_v6 ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::size_t hash_value (Address const& addr)
|
||||
{
|
||||
return (addr.is_v4 ())
|
||||
? hash_value (addr.to_v4())
|
||||
: hash_value (addr.to_v6());
|
||||
}
|
||||
|
||||
std::istream& operator>> (std::istream& is, Address& addr)
|
||||
{
|
||||
// VFALCO TODO Support ipv6!
|
||||
AddressV4 addrv4;
|
||||
is >> addrv4;
|
||||
addr = Address (addrv4);
|
||||
return is;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class IPAddressTests : public UnitTest
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_THREADS_LOCKGUARD_H_INCLUDED
|
||||
#define BEAST_THREADS_LOCKGUARD_H_INCLUDED
|
||||
|
||||
#include "../Uncopyable.h"
|
||||
|
||||
namespace beast {
|
||||
|
||||
template <typename Mutex>
|
||||
class LockGuard : public Uncopyable
|
||||
{
|
||||
public:
|
||||
typedef Mutex MutexType;
|
||||
|
||||
explicit LockGuard (Mutex const& mutex)
|
||||
: m_mutex (mutex)
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
~LockGuard ()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
Mutex const& m_mutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -25,10 +25,11 @@
|
||||
#define BEAST_THREADS_RECURSIVEMUTEX_H_INCLUDED
|
||||
|
||||
#include "../Config.h"
|
||||
#include "LockGuard.h"
|
||||
#include "UnlockGuard.h"
|
||||
#include "TryLockGuard.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#if ! BEAST_WINDOWS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
@@ -38,7 +39,7 @@ namespace beast {
|
||||
class RecursiveMutex
|
||||
{
|
||||
public:
|
||||
typedef LockGuard <RecursiveMutex> ScopedLockType;
|
||||
typedef std::lock_guard <RecursiveMutex> ScopedLockType;
|
||||
typedef UnlockGuard <RecursiveMutex> ScopedUnlockType;
|
||||
typedef TryLockGuard <RecursiveMutex> ScopedTryLockType;
|
||||
|
||||
|
||||
@@ -30,19 +30,20 @@ template <typename ScopedType, typename Context, typename Handler>
|
||||
class ScopedWrapper
|
||||
{
|
||||
public:
|
||||
ScopedWrapper (Context const& context, Handler const& handler)
|
||||
ScopedWrapper (Context& context, Handler const& handler)
|
||||
: m_context (context)
|
||||
, m_handler (handler)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
void operator() ()
|
||||
{
|
||||
ScopedType const scope (m_context);
|
||||
ScopedType scope (m_context);
|
||||
m_handler();
|
||||
}
|
||||
|
||||
private:
|
||||
Context const& m_context;
|
||||
Context& m_context;
|
||||
Handler m_handler;
|
||||
};
|
||||
|
||||
@@ -55,17 +56,19 @@ template <typename Context, typename ScopedType>
|
||||
class ScopedWrapperContext
|
||||
{
|
||||
public:
|
||||
typedef Context context_type;
|
||||
typedef ScopedType scoped_type;
|
||||
typedef Context context_type;
|
||||
typedef ScopedType scoped_type;
|
||||
|
||||
class Scope
|
||||
{
|
||||
public:
|
||||
explicit Scope (ScopedWrapperContext const& owner)
|
||||
: m_scope (owner.m_context)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
scoped_type m_scope;
|
||||
scoped_type mutable m_scope;
|
||||
};
|
||||
|
||||
ScopedWrapperContext ()
|
||||
@@ -74,7 +77,8 @@ public:
|
||||
template <typename Arg>
|
||||
explicit ScopedWrapperContext (Arg& arg)
|
||||
: m_context (arg)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
detail::ScopedWrapper <ScopedType, Context, Handler> wrap (
|
||||
@@ -85,7 +89,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Context m_context;
|
||||
Context mutable m_context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
#ifndef BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||
#define BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||
|
||||
#include "LockGuard.h"
|
||||
#include "SharedLockGuard.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace beast {
|
||||
|
||||
/** Adapts a regular Lockable to conform to the SharedMutex concept.
|
||||
@@ -35,7 +36,7 @@ class SharedMutexAdapter
|
||||
{
|
||||
public:
|
||||
typedef Mutex MutexType;
|
||||
typedef LockGuard <SharedMutexAdapter> LockGuardType;
|
||||
typedef std::lock_guard <SharedMutexAdapter> LockGuardType;
|
||||
typedef SharedLockGuard <SharedMutexAdapter> SharedLockGuardType;
|
||||
|
||||
void lock() const
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#define BEAST_THREADS_SPINLOCK_H_INCLUDED
|
||||
|
||||
#include "../Atomic.h"
|
||||
#include "LockGuard.h"
|
||||
#include "UnlockGuard.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace beast {
|
||||
|
||||
//==============================================================================
|
||||
@@ -47,7 +48,7 @@ class BEAST_API SpinLock : public Uncopyable
|
||||
{
|
||||
public:
|
||||
/** Provides the type of scoped lock to use for locking a SpinLock. */
|
||||
typedef LockGuard <SpinLock> ScopedLockType;
|
||||
typedef std::lock_guard <SpinLock> ScopedLockType;
|
||||
|
||||
/** Provides the type of scoped unlocker to use with a SpinLock. */
|
||||
typedef UnlockGuard <SpinLock> ScopedUnlockType;
|
||||
|
||||
@@ -187,8 +187,8 @@ private:
|
||||
Type object;
|
||||
};
|
||||
|
||||
mutable Atomic<ObjectHolder*> first;
|
||||
SpinLock lock;
|
||||
Atomic<ObjectHolder*> mutable first;
|
||||
SpinLock mutable lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ struct maybe_const
|
||||
typename std::remove_const <T>::type>::type type;
|
||||
};
|
||||
|
||||
/** Alias for omitting `typename`. */
|
||||
template <bool IsConst, class T>
|
||||
using maybe_const_t = typename maybe_const <IsConst,T>::type;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "../Config.h"
|
||||
|
||||
#include "../SafeBool.h"
|
||||
#include "../strings/String.h"
|
||||
|
||||
#include <stdexcept>
|
||||
@@ -43,7 +42,6 @@ namespace beast {
|
||||
*/
|
||||
class Error
|
||||
: public std::exception
|
||||
, public SafeBool <Error>
|
||||
{
|
||||
public:
|
||||
/** Numeric code.
|
||||
@@ -88,7 +86,10 @@ public:
|
||||
Code code () const;
|
||||
bool failed () const;
|
||||
|
||||
bool asBoolean () const;
|
||||
explicit operator bool () const
|
||||
{
|
||||
return code () != success;
|
||||
}
|
||||
|
||||
String const getReasonText () const;
|
||||
String const getSourceFilename () const;
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||
|
||||
#include "../SafeBool.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace beast {
|
||||
@@ -150,7 +148,7 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
class Stream : public SafeBool <Stream>
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
/** Create a stream which produces no output. */
|
||||
@@ -177,7 +175,12 @@ public:
|
||||
/** Returns `true` if sink logs anything at this stream's severity. */
|
||||
/** @{ */
|
||||
bool active() const;
|
||||
bool asBoolean() const;
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return ! m_disabled;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** Output stream support. */
|
||||
|
||||
@@ -81,11 +81,6 @@ bool Error::failed () const
|
||||
return code () != success;
|
||||
}
|
||||
|
||||
bool Error::asBoolean () const
|
||||
{
|
||||
return code () != success;
|
||||
}
|
||||
|
||||
String const Error::getReasonText () const
|
||||
{
|
||||
return m_reasonText;
|
||||
|
||||
@@ -211,11 +211,6 @@ bool Journal::Stream::active () const
|
||||
return ! m_disabled && m_sink->active (m_level);
|
||||
}
|
||||
|
||||
bool Journal::Stream::asBoolean () const
|
||||
{
|
||||
return active();
|
||||
}
|
||||
|
||||
Journal::Stream& Journal::Stream::operator= (Stream const& other)
|
||||
{
|
||||
m_sink = other.m_sink;
|
||||
|
||||
Reference in New Issue
Block a user