RESTinio

method_matcher.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
12#pragma once
13
14#include <restinio/http_headers.hpp>
15
16#include <initializer_list>
17#include <vector>
18
19 namespace restinio
20{
21
22 namespace router
23{
24
25//
26// method_matcher_t
27//
38 struct method_matcher_t
39{
40 method_matcher_t( const method_matcher_t & ) = default;
41 method_matcher_t &
42 operator=( const method_matcher_t & ) = default;
43
44 method_matcher_t( method_matcher_t && ) = default;
45 method_matcher_t &
46 operator=( method_matcher_t && ) = default;
47
48 method_matcher_t() = default;
49 virtual ~method_matcher_t() = default;
50
52
56 RESTINIO_NODISCARD
57 virtual bool
58 match( const http_method_id_t & method ) const noexcept = 0;
59};
60
61 namespace impl
62{
63
64//
65// allocated_matcher_proxy_t
66//
79 template< typename Matcher >
80 class allocated_matcher_proxy_t : public method_matcher_t
81{
82 std::unique_ptr< Matcher > m_matcher;
83
84public :
85 template< typename... Args >
86 allocated_matcher_proxy_t( Args && ...args )
87 : m_matcher{ std::make_unique<Matcher>( std::forward<Args>(args)... ) }
88 {}
89
90 RESTINIO_NODISCARD
91 bool
92 match( const http_method_id_t & method ) const noexcept override
93 {
94 return m_matcher->match( method );
95 }
96};
97
98//
99// simple_matcher_t
100//
110 class simple_matcher_t : public method_matcher_t
111{
112 http_method_id_t m_method;
113
114public :
115 simple_matcher_t( http_method_id_t method )
116 : m_method{ std::move(method) }
117 {}
118
119 RESTINIO_NODISCARD
120 bool
121 match( const http_method_id_t & method ) const noexcept override
122 {
123 return m_method == method;
124 }
125};
126
127//
128// fixed_size_any_of_matcher_t
129//
138 template< std::size_t Size >
139 class fixed_size_any_of_matcher_t : public method_matcher_t
140{
141 std::array< http_method_id_t, Size > m_methods;
142
143public :
151 fixed_size_any_of_matcher_t(
152 std::initializer_list< http_method_id_t > values )
153 {
154 assert( Size == values.size() );
155
156 std::copy( values.begin(), values.end(), m_methods.begin() );
157 }
158
159 RESTINIO_NODISCARD
160 bool
161 match( const http_method_id_t & method ) const noexcept override
162 {
163 for( const auto & m : m_methods )
164 if( m == method )
165 return true;
166
167 return false;
168 }
169};
170
171//
172// fixed_size_none_of_matcher_t
173//
182 template< std::size_t Size >
183 class fixed_size_none_of_matcher_t
184 : public fixed_size_any_of_matcher_t<Size>
185{
186 using base_type_t = fixed_size_any_of_matcher_t<Size>;
187
188public :
189 using base_type_t::base_type_t;
190
191 RESTINIO_NODISCARD
192 bool
193 match( const http_method_id_t & method ) const noexcept override
194 {
195 return !base_type_t::match( method );
196 }
197};
198
199//
200// buffered_matcher_holder_t
201//
224 class buffered_matcher_holder_t
225{
227 static constexpr std::size_t buffer_size =
228 sizeof(fixed_size_any_of_matcher_t<4>);
229
231 static constexpr std::size_t alignment =
232 std::max( {
233 alignof(simple_matcher_t),
234 alignof(fixed_size_any_of_matcher_t<4>),
235 alignof(allocated_matcher_proxy_t<
236 fixed_size_any_of_matcher_t<20>>) } );
237
240
245 using pfn_move_t = method_matcher_t* (*)(void* object, void* buffer);
246
248
252 method_matcher_t * m_matcher{ nullptr };
253
255 alignas(alignment) std::array<char, buffer_size> m_buffer;
256
258
261 pfn_move_t m_mover{ nullptr };
262
263 void
264 cleanup()
265 {
266 if( m_matcher ) m_matcher->~method_matcher_t();
267 }
268
269 void
270 move_from( buffered_matcher_holder_t & other )
271 {
272 if( other.m_matcher )
273 {
274 m_matcher = other.m_mover( other.m_matcher, m_buffer.data() );
275 m_mover = other.m_mover;
276
277 other.m_matcher = nullptr;
278 other.m_mover = nullptr;
279 }
280 }
281
282public :
283 buffered_matcher_holder_t() = default;
284
285 ~buffered_matcher_holder_t() noexcept
286 {
287 cleanup();
288 }
289
290 buffered_matcher_holder_t(
291 const buffered_matcher_holder_t & ) = delete;
292
293 buffered_matcher_holder_t &
294 operator=(
295 const buffered_matcher_holder_t & ) = delete;
296
297 buffered_matcher_holder_t(
298 buffered_matcher_holder_t && other ) noexcept
299 {
300 move_from( other );
301 }
302
303 buffered_matcher_holder_t &
304 operator=( buffered_matcher_holder_t && other ) noexcept
305 {
306 if( this != &other )
307 {
308 cleanup();
309 move_from( other );
310 }
311
312 return *this;
313 }
314
327 template< typename Target_Type, typename... Args >
328 void
329 assign( Args &&... args )
330 {
331 static_assert( alignof(Target_Type) <= alignment,
332 "Target_Type should have appropriate alignment" );
333
334 cleanup();
335
336 if( sizeof(Target_Type) <= buffer_size )
337 {
338 m_matcher = new(m_buffer.data()) Target_Type{ std::forward<Args>(args)... };
339 m_mover = [](void * raw_what, void * dest_storage) -> method_matcher_t * {
340 auto * what = reinterpret_cast<Target_Type *>(raw_what);
341 return new(dest_storage) Target_Type{ std::move(*what) };
342 };
343 }
344 else
345 {
346 using actual_type = allocated_matcher_proxy_t<Target_Type>;
347 m_matcher = new(m_buffer.data()) actual_type{ std::forward<Args>(args)... };
348 m_mover = [](void * raw_what, void * dest_storage) -> method_matcher_t * {
349 auto * what = reinterpret_cast<actual_type *>(raw_what);
350 return new(dest_storage) actual_type{ std::move(*what) };
351 };
352 }
353 }
354
356 RESTINIO_NODISCARD
357 method_matcher_t *
358 get() const noexcept { return m_matcher; }
359
361 RESTINIO_NODISCARD
362 method_matcher_t *
363 operator->() const noexcept { return m_matcher; }
364
366 RESTINIO_NODISCARD
367 method_matcher_t &
368 operator*() const noexcept { return *m_matcher; }
369
370 friend void
371 assign( buffered_matcher_holder_t & holder, http_method_id_t method )
372 {
373 holder.assign< simple_matcher_t >( std::move(method) );
374 }
375
376 template< typename Arg >
377 friend void
378 assign( buffered_matcher_holder_t & holder, Arg && method_matcher )
379 {
380 using pure_method_matcher_type = std::decay_t<Arg>;
381
382 static_assert( std::is_base_of<
383 method_matcher_t, pure_method_matcher_type >::value,
384 "Arg should be derived from method_matcher_t" );
385
386 holder.assign< pure_method_matcher_type >(
387 std::forward<Arg>(method_matcher) );
388 }
389};
390
391} /* namespace impl */
392
393//
394// any_of_methods
395//
414 template< typename... Args >
415 RESTINIO_NODISCARD
416impl::fixed_size_any_of_matcher_t< sizeof...(Args) >
417 any_of_methods( Args && ...args )
418{
419 return { std::initializer_list<http_method_id_t>{ std::forward<Args>(args)... } };
420}
421
422//
423// none_of_methods
424//
446 template< typename... Args >
447 RESTINIO_NODISCARD
448impl::fixed_size_none_of_matcher_t< sizeof...(Args) >
449 none_of_methods( Args && ...args )
450{
451 return { std::initializer_list<http_method_id_t>{ std::forward<Args>(args)... } };
452}
453
454//
455// dynamic_any_of_methods_matcher_t
456//
475 class dynamic_any_of_methods_matcher_t : public method_matcher_t
476{
477 std::vector< http_method_id_t > m_methods;
478
479 public:
480 dynamic_any_of_methods_matcher_t() = default;
481
482 RESTINIO_NODISCARD
483 bool
484 match( const http_method_id_t & method ) const noexcept override
485 {
486 for( const auto & m : m_methods )
487 if( m == method )
488 return true;
489
490 return false;
491 }
492
493 dynamic_any_of_methods_matcher_t &
494 add( http_method_id_t method )
495 {
496 m_methods.emplace_back( std::move(method) );
497 return *this;
498 }
499
500 RESTINIO_NODISCARD
501 std::size_t
502 size() const noexcept
503 {
504 return m_methods.size();
505 }
506
507 RESTINIO_NODISCARD
508 bool
509 empty() const noexcept
510 {
511 return m_methods.empty();
512 }
513};
514
515//
516// dynamic_none_of_methods_matcher_t
517//
536 class dynamic_none_of_methods_matcher_t : public method_matcher_t
537{
538 std::vector< http_method_id_t > m_methods;
539
540 public:
541 dynamic_none_of_methods_matcher_t() = default;
542
543 RESTINIO_NODISCARD
544 bool
545 match( const http_method_id_t & method ) const noexcept override
546 {
547 for( const auto & m : m_methods )
548 if( m == method )
549 return false;
550
551 return true;
552 }
553
554 dynamic_none_of_methods_matcher_t &
555 add( http_method_id_t method )
556 {
557 m_methods.emplace_back( std::move(method) );
558 return *this;
559 }
560
561 RESTINIO_NODISCARD
562 std::size_t
563 size() const noexcept
564 {
565 return m_methods.size();
566 }
567
568 RESTINIO_NODISCARD
569 bool
570 empty() const noexcept
571 {
572 return m_methods.empty();
573 }
574};
575
576} /* namespace router */
577
578} /* namespace restinio */
579
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