method_matcher.hpp
Go to the documentation of this file.
/*
* RESTinio
*/
#pragma once
#include <restinio/http_headers.hpp>
#include <initializer_list>
#include <vector>
namespace restinio
{
namespace router
{
//
// method_matcher_t
//
struct method_matcher_t
{
method_matcher_t( const method_matcher_t & ) = default;
method_matcher_t &
operator=( const method_matcher_t & ) = default;
method_matcher_t( method_matcher_t && ) = default;
method_matcher_t &
operator=( method_matcher_t && ) = default;
method_matcher_t() = default;
virtual ~method_matcher_t() = default;
RESTINIO_NODISCARD
virtual bool
match( const http_method_id_t & method ) const noexcept = 0;
};
namespace impl
{
//
// allocated_matcher_proxy_t
//
template< typename Matcher >
class allocated_matcher_proxy_t : public method_matcher_t
{
std::unique_ptr< Matcher > m_matcher;
public :
template< typename... Args >
allocated_matcher_proxy_t( Args && ...args )
: m_matcher{ std::make_unique<Matcher>( std::forward<Args>(args)... ) }
{}
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
return m_matcher->match( method );
}
};
//
// simple_matcher_t
//
class simple_matcher_t : public method_matcher_t
{
http_method_id_t m_method;
public :
simple_matcher_t( http_method_id_t method )
: m_method{ std::move(method) }
{}
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
return m_method == method;
}
};
//
// fixed_size_any_of_matcher_t
//
template< std::size_t Size >
class fixed_size_any_of_matcher_t : public method_matcher_t
{
std::array< http_method_id_t, Size > m_methods;
public :
fixed_size_any_of_matcher_t(
std::initializer_list< http_method_id_t > values )
{
assert( Size == values.size() );
std::copy( values.begin(), values.end(), m_methods.begin() );
}
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
for( const auto & m : m_methods )
if( m == method )
return true;
return false;
}
};
//
// fixed_size_none_of_matcher_t
//
template< std::size_t Size >
class fixed_size_none_of_matcher_t
: public fixed_size_any_of_matcher_t<Size>
{
using base_type_t = fixed_size_any_of_matcher_t<Size>;
public :
using base_type_t::base_type_t;
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
return !base_type_t::match( method );
}
};
//
// buffered_matcher_holder_t
//
class buffered_matcher_holder_t
{
static constexpr std::size_t buffer_size =
sizeof(fixed_size_any_of_matcher_t<4>);
static constexpr std::size_t alignment =
std::max( {
alignof(simple_matcher_t),
alignof(fixed_size_any_of_matcher_t<4>),
alignof(allocated_matcher_proxy_t<
fixed_size_any_of_matcher_t<20>>) } );
using pfn_move_t = method_matcher_t* (*)(void* object, void* buffer);
method_matcher_t * m_matcher{ nullptr };
alignas(alignment) std::array<char, buffer_size> m_buffer;
pfn_move_t m_mover{ nullptr };
void
cleanup()
{
if( m_matcher ) m_matcher->~method_matcher_t();
}
void
move_from( buffered_matcher_holder_t & other )
{
if( other.m_matcher )
{
m_matcher = other.m_mover( other.m_matcher, m_buffer.data() );
m_mover = other.m_mover;
other.m_matcher = nullptr;
other.m_mover = nullptr;
}
}
public :
buffered_matcher_holder_t() = default;
~buffered_matcher_holder_t() noexcept
{
cleanup();
}
buffered_matcher_holder_t(
const buffered_matcher_holder_t & ) = delete;
buffered_matcher_holder_t &
operator=(
const buffered_matcher_holder_t & ) = delete;
buffered_matcher_holder_t(
buffered_matcher_holder_t && other ) noexcept
{
move_from( other );
}
buffered_matcher_holder_t &
operator=( buffered_matcher_holder_t && other ) noexcept
{
if( this != &other )
{
cleanup();
move_from( other );
}
return *this;
}
template< typename Target_Type, typename... Args >
void
assign( Args &&... args )
{
static_assert( alignof(Target_Type) <= alignment,
"Target_Type should have appropriate alignment" );
cleanup();
if( sizeof(Target_Type) <= buffer_size )
{
m_matcher = new(m_buffer.data()) Target_Type{ std::forward<Args>(args)... };
m_mover = [](void * raw_what, void * dest_storage) -> method_matcher_t * {
auto * what = reinterpret_cast<Target_Type *>(raw_what);
return new(dest_storage) Target_Type{ std::move(*what) };
};
}
else
{
using actual_type = allocated_matcher_proxy_t<Target_Type>;
m_matcher = new(m_buffer.data()) actual_type{ std::forward<Args>(args)... };
m_mover = [](void * raw_what, void * dest_storage) -> method_matcher_t * {
auto * what = reinterpret_cast<actual_type *>(raw_what);
return new(dest_storage) actual_type{ std::move(*what) };
};
}
}
RESTINIO_NODISCARD
method_matcher_t *
get() const noexcept { return m_matcher; }
RESTINIO_NODISCARD
method_matcher_t *
operator->() const noexcept { return m_matcher; }
RESTINIO_NODISCARD
method_matcher_t &
operator*() const noexcept { return *m_matcher; }
friend void
assign( buffered_matcher_holder_t & holder, http_method_id_t method )
{
holder.assign< simple_matcher_t >( std::move(method) );
}
template< typename Arg >
friend void
assign( buffered_matcher_holder_t & holder, Arg && method_matcher )
{
using pure_method_matcher_type = std::decay_t<Arg>;
static_assert( std::is_base_of<
method_matcher_t, pure_method_matcher_type >::value,
"Arg should be derived from method_matcher_t" );
holder.assign< pure_method_matcher_type >(
std::forward<Arg>(method_matcher) );
}
};
} /* namespace impl */
//
// any_of_methods
//
template< typename... Args >
RESTINIO_NODISCARD
impl::fixed_size_any_of_matcher_t< sizeof...(Args) >
any_of_methods( Args && ...args )
{
return { std::initializer_list<http_method_id_t>{ std::forward<Args>(args)... } };
}
//
// none_of_methods
//
template< typename... Args >
RESTINIO_NODISCARD
impl::fixed_size_none_of_matcher_t< sizeof...(Args) >
none_of_methods( Args && ...args )
{
return { std::initializer_list<http_method_id_t>{ std::forward<Args>(args)... } };
}
//
// dynamic_any_of_methods_matcher_t
//
class dynamic_any_of_methods_matcher_t : public method_matcher_t
{
std::vector< http_method_id_t > m_methods;
public:
dynamic_any_of_methods_matcher_t() = default;
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
for( const auto & m : m_methods )
if( m == method )
return true;
return false;
}
dynamic_any_of_methods_matcher_t &
add( http_method_id_t method )
{
m_methods.emplace_back( std::move(method) );
return *this;
}
RESTINIO_NODISCARD
std::size_t
size() const noexcept
{
return m_methods.size();
}
RESTINIO_NODISCARD
bool
empty() const noexcept
{
return m_methods.empty();
}
};
//
// dynamic_none_of_methods_matcher_t
//
class dynamic_none_of_methods_matcher_t : public method_matcher_t
{
std::vector< http_method_id_t > m_methods;
public:
dynamic_none_of_methods_matcher_t() = default;
RESTINIO_NODISCARD
bool
match( const http_method_id_t & method ) const noexcept override
{
for( const auto & m : m_methods )
if( m == method )
return false;
return true;
}
dynamic_none_of_methods_matcher_t &
add( http_method_id_t method )
{
m_methods.emplace_back( std::move(method) );
return *this;
}
RESTINIO_NODISCARD
std::size_t
size() const noexcept
{
return m_methods.size();
}
RESTINIO_NODISCARD
bool
empty() const noexcept
{
return m_methods.empty();
}
};
} /* namespace router */
} /* namespace restinio */
restinio::http_method_id_t
A type for representation of HTTP method ID.
Definition: http_headers.hpp:1744
restinio::router::dynamic_any_of_methods_matcher_t
An implementation of method_matcher that allows a method if it's found in a dynamic list of allowed m...
Definition: method_matcher.hpp:476
restinio::router::dynamic_any_of_methods_matcher_t::m_methods
std::vector< http_method_id_t > m_methods
Definition: method_matcher.hpp:477
restinio::router::dynamic_any_of_methods_matcher_t::add
dynamic_any_of_methods_matcher_t & add(http_method_id_t method)
Definition: method_matcher.hpp:494
restinio::router::dynamic_any_of_methods_matcher_t::size
RESTINIO_NODISCARD std::size_t size() const noexcept
Definition: method_matcher.hpp:502
restinio::router::dynamic_any_of_methods_matcher_t::empty
RESTINIO_NODISCARD bool empty() const noexcept
Definition: method_matcher.hpp:509
restinio::router::dynamic_any_of_methods_matcher_t::dynamic_any_of_methods_matcher_t
dynamic_any_of_methods_matcher_t()=default
restinio::router::dynamic_any_of_methods_matcher_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:484
restinio::router::dynamic_none_of_methods_matcher_t
An implementation of method_matcher that allows a method if it isn't found in a dynamic list of disab...
Definition: method_matcher.hpp:537
restinio::router::dynamic_none_of_methods_matcher_t::empty
RESTINIO_NODISCARD bool empty() const noexcept
Definition: method_matcher.hpp:570
restinio::router::dynamic_none_of_methods_matcher_t::size
RESTINIO_NODISCARD std::size_t size() const noexcept
Definition: method_matcher.hpp:563
restinio::router::dynamic_none_of_methods_matcher_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:545
restinio::router::dynamic_none_of_methods_matcher_t::dynamic_none_of_methods_matcher_t
dynamic_none_of_methods_matcher_t()=default
restinio::router::dynamic_none_of_methods_matcher_t::m_methods
std::vector< http_method_id_t > m_methods
Definition: method_matcher.hpp:538
restinio::router::dynamic_none_of_methods_matcher_t::add
dynamic_none_of_methods_matcher_t & add(http_method_id_t method)
Definition: method_matcher.hpp:555
restinio::router::impl::allocated_matcher_proxy_t
A proxy for actual method_matcher that will be allocated in dynamic memory.
Definition: method_matcher.hpp:81
restinio::router::impl::allocated_matcher_proxy_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:92
restinio::router::impl::allocated_matcher_proxy_t::m_matcher
std::unique_ptr< Matcher > m_matcher
Definition: method_matcher.hpp:82
restinio::router::impl::allocated_matcher_proxy_t::allocated_matcher_proxy_t
allocated_matcher_proxy_t(Args &&...args)
Definition: method_matcher.hpp:86
restinio::router::impl::buffered_matcher_holder_t
A special class that allows to hold a copy of small-size method_matchers or a pointer to dynamically ...
Definition: method_matcher.hpp:225
restinio::router::impl::buffered_matcher_holder_t::m_buffer
std::array< char, buffer_size > m_buffer
The internal buffer.
Definition: method_matcher.hpp:255
restinio::router::impl::buffered_matcher_holder_t::assign
friend void assign(buffered_matcher_holder_t &holder, Arg &&method_matcher)
Definition: method_matcher.hpp:378
restinio::router::impl::buffered_matcher_holder_t::m_mover
pfn_move_t m_mover
An actual move-function.
Definition: method_matcher.hpp:261
restinio::router::impl::buffered_matcher_holder_t::assign
friend void assign(buffered_matcher_holder_t &holder, http_method_id_t method)
Definition: method_matcher.hpp:371
restinio::router::impl::buffered_matcher_holder_t::operator*
RESTINIO_NODISCARD method_matcher_t & operator*() const noexcept
Get a reference to actual matcher inside the holder.
Definition: method_matcher.hpp:368
restinio::router::impl::buffered_matcher_holder_t::move_from
void move_from(buffered_matcher_holder_t &other)
Definition: method_matcher.hpp:270
restinio::router::impl::buffered_matcher_holder_t::operator=
buffered_matcher_holder_t & operator=(buffered_matcher_holder_t &&other) noexcept
Definition: method_matcher.hpp:304
restinio::router::impl::buffered_matcher_holder_t::operator->
RESTINIO_NODISCARD method_matcher_t * operator->() const noexcept
Get the pointer to actual matcher inside the holder.
Definition: method_matcher.hpp:363
restinio::router::impl::buffered_matcher_holder_t::operator=
buffered_matcher_holder_t & operator=(const buffered_matcher_holder_t &)=delete
restinio::router::impl::buffered_matcher_holder_t::pfn_move_t
method_matcher_t *(*)(void *object, void *buffer) pfn_move_t
A type of free function to be used to move a value of an object to the specified buffer.
Definition: method_matcher.hpp:245
restinio::router::impl::buffered_matcher_holder_t::assign
void assign(Args &&... args)
Creates an instance of Target_Type and initializes it with arguments Args.
Definition: method_matcher.hpp:329
restinio::router::impl::buffered_matcher_holder_t::buffered_matcher_holder_t
buffered_matcher_holder_t()=default
restinio::router::impl::buffered_matcher_holder_t::get
RESTINIO_NODISCARD method_matcher_t * get() const noexcept
Get the pointer to actual matcher inside the holder.
Definition: method_matcher.hpp:358
restinio::router::impl::buffered_matcher_holder_t::buffered_matcher_holder_t
buffered_matcher_holder_t(buffered_matcher_holder_t &&other) noexcept
Definition: method_matcher.hpp:297
restinio::router::impl::buffered_matcher_holder_t::alignment
static constexpr std::size_t alignment
Alignment to be used by the internal buffer.
Definition: method_matcher.hpp:231
restinio::router::impl::buffered_matcher_holder_t::buffer_size
static constexpr std::size_t buffer_size
The size of the internal buffer.
Definition: method_matcher.hpp:227
restinio::router::impl::buffered_matcher_holder_t::~buffered_matcher_holder_t
~buffered_matcher_holder_t() noexcept
Definition: method_matcher.hpp:285
restinio::router::impl::buffered_matcher_holder_t::m_matcher
method_matcher_t * m_matcher
A pointer to actual matcher allocated inside the internall buffer.
Definition: method_matcher.hpp:252
restinio::router::impl::buffered_matcher_holder_t::buffered_matcher_holder_t
buffered_matcher_holder_t(const buffered_matcher_holder_t &)=delete
restinio::router::impl::buffered_matcher_holder_t::cleanup
void cleanup()
Definition: method_matcher.hpp:264
restinio::router::impl::fixed_size_any_of_matcher_t
A matcher that finds a value in the vector of allowed values of fixed size.
Definition: method_matcher.hpp:140
restinio::router::impl::fixed_size_any_of_matcher_t::fixed_size_any_of_matcher_t
fixed_size_any_of_matcher_t(std::initializer_list< http_method_id_t > values)
Initializing constructor.
Definition: method_matcher.hpp:151
restinio::router::impl::fixed_size_any_of_matcher_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:161
restinio::router::impl::fixed_size_any_of_matcher_t::m_methods
std::array< http_method_id_t, Size > m_methods
Definition: method_matcher.hpp:141
restinio::router::impl::fixed_size_none_of_matcher_t
A matcher that finds a value in the vector of disabled values of fixed size.
Definition: method_matcher.hpp:185
restinio::router::impl::fixed_size_none_of_matcher_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:193
restinio::router::impl::simple_matcher_t
A simple method_matcher that compares just one user-specified value.
Definition: method_matcher.hpp:111
restinio::router::impl::simple_matcher_t::match
RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept override
Is the specified method can be applied to a route?
Definition: method_matcher.hpp:121
restinio::router::impl::simple_matcher_t::simple_matcher_t
simple_matcher_t(http_method_id_t method)
Definition: method_matcher.hpp:115
restinio::router::impl::simple_matcher_t::m_method
http_method_id_t m_method
Definition: method_matcher.hpp:112
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
http_headers.hpp
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
restinio::router::any_of_methods
RESTINIO_NODISCARD impl::fixed_size_any_of_matcher_t< sizeof...(Args) > any_of_methods(Args &&...args)
A factory function that creates a method_matcher that allows a method if it's found in the list of al...
Definition: method_matcher.hpp:417
restinio::router::none_of_methods
RESTINIO_NODISCARD impl::fixed_size_none_of_matcher_t< sizeof...(Args) > none_of_methods(Args &&...args)
A factory function that creates a method_matcher that allows a method if it isn't found in the list o...
Definition: method_matcher.hpp:449
restinio
Definition: asio_include.hpp:21
std
STL namespace.
restinio::router::method_matcher_t
An interface of method_matcher.
Definition: method_matcher.hpp:39
restinio::router::method_matcher_t::method_matcher_t
method_matcher_t(method_matcher_t &&)=default
restinio::router::method_matcher_t::~method_matcher_t
virtual ~method_matcher_t()=default
restinio::router::method_matcher_t::operator=
method_matcher_t & operator=(const method_matcher_t &)=default
restinio::router::method_matcher_t::method_matcher_t
method_matcher_t()=default
restinio::router::method_matcher_t::operator=
method_matcher_t & operator=(method_matcher_t &&)=default
restinio::router::method_matcher_t::method_matcher_t
method_matcher_t(const method_matcher_t &)=default
restinio::router::method_matcher_t::match
virtual RESTINIO_NODISCARD bool match(const http_method_id_t &method) const noexcept=0
Is the specified method can be applied to a route?
const
#define const
Definition: zconf.h:230