RESTinio
method_matcher.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
12 #pragma once
13 
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 //
39 {
40  method_matcher_t( const method_matcher_t & ) = default;
42  operator=( const method_matcher_t & ) = default;
43 
46  operator=( method_matcher_t && ) = default;
47 
48  method_matcher_t() = default;
49  virtual ~method_matcher_t() = default;
50 
52 
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 >
81 {
82  std::unique_ptr< Matcher > m_matcher;
83 
84 public :
85  template< typename... Args >
86  allocated_matcher_proxy_t( Args && ...args )
87  : m_matcher{ std::make_unique<Matcher>( std::forward<Args>(args)... ) }
88  {}
89 
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 //
111 {
113 
114 public :
116  : m_method{ std::move(method) }
117  {}
118 
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 >
140 {
141  std::array< http_method_id_t, Size > m_methods;
142 
143 public :
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 
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 >
184  : public fixed_size_any_of_matcher_t<Size>
185 {
187 
188 public :
189  using base_type_t::base_type_t;
190 
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 //
225 {
227  static constexpr std::size_t buffer_size =
229 
231  static constexpr std::size_t alignment =
232  std::max( {
233  alignof(simple_matcher_t),
237 
240 
245  using pfn_move_t = method_matcher_t* (*)(void* object, void* buffer);
246 
248 
253 
255  alignas(alignment) std::array<char, buffer_size> m_buffer;
256 
258 
261  pfn_move_t m_mover{ nullptr };
262 
263  void
265  {
267  }
268 
269  void
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 
282 public :
284 
286  {
287  cleanup();
288  }
289 
291  const buffered_matcher_holder_t & ) = delete;
292 
295  const buffered_matcher_holder_t & ) = delete;
296 
298  buffered_matcher_holder_t && other ) noexcept
299  {
300  move_from( other );
301  }
302 
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 
358  get() const noexcept { return m_matcher; }
359 
363  operator->() const noexcept { return m_matcher; }
364 
368  operator*() const noexcept { return *m_matcher; }
369 
370  friend void
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 >
416 impl::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 >
448 impl::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 //
476 {
477  std::vector< http_method_id_t > m_methods;
478 
479 public:
481 
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 
495  {
496  m_methods.emplace_back( std::move(method) );
497  return *this;
498  }
499 
501  std::size_t
502  size() const noexcept
503  {
504  return m_methods.size();
505  }
506 
508  bool
509  empty() const noexcept
510  {
511  return m_methods.empty();
512  }
513 };
514 
515 //
516 // dynamic_none_of_methods_matcher_t
517 //
537 {
538  std::vector< http_method_id_t > m_methods;
539 
540 public:
542 
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 
556  {
557  m_methods.emplace_back( std::move(method) );
558  return *this;
559  }
560 
562  std::size_t
563  size() const noexcept
564  {
565  return m_methods.size();
566  }
567 
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::impl::buffered_matcher_holder_t::m_mover
pfn_move_t m_mover
An actual move-function.
Definition: method_matcher.hpp:261
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_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
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
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
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::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
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::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::buffered_matcher_holder_t
buffered_matcher_holder_t(const buffered_matcher_holder_t &)=delete
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::buffered_matcher_holder_t::cleanup
void cleanup()
Definition: method_matcher.hpp:264
restinio::router::dynamic_none_of_methods_matcher_t::dynamic_none_of_methods_matcher_t
dynamic_none_of_methods_matcher_t()=default
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::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::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::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::method_matcher_t::method_matcher_t
method_matcher_t(const method_matcher_t &)=default
restinio::router::impl::buffered_matcher_holder_t::operator=
buffered_matcher_holder_t & operator=(const buffered_matcher_holder_t &)=delete
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?
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::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::method_matcher_t
An interface of method_matcher.
Definition: method_matcher.hpp:39
restinio::router::dynamic_none_of_methods_matcher_t::size
RESTINIO_NODISCARD std::size_t size() const noexcept
Definition: method_matcher.hpp:563
restinio::router::method_matcher_t::method_matcher_t
method_matcher_t(method_matcher_t &&)=default
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::move_from
void move_from(buffered_matcher_holder_t &other)
Definition: method_matcher.hpp:270
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::m_methods
std::array< http_method_id_t, Size > m_methods
Definition: method_matcher.hpp:141
restinio::router::dynamic_any_of_methods_matcher_t::empty
RESTINIO_NODISCARD bool empty() const noexcept
Definition: method_matcher.hpp:509
restinio::router::impl::allocated_matcher_proxy_t::m_matcher
std::unique_ptr< Matcher > m_matcher
Definition: method_matcher.hpp:82
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::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() 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::simple_matcher_t
A simple method_matcher that compares just one user-specified value.
Definition: method_matcher.hpp:111
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::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::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::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::method_matcher_t::operator=
method_matcher_t & operator=(method_matcher_t &&)=default
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::impl::buffered_matcher_holder_t::buffered_matcher_holder_t
buffered_matcher_holder_t()=default
restinio
Definition: asio_include.hpp:21
restinio::router::method_matcher_t::method_matcher_t
method_matcher_t()=default
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::allocated_matcher_proxy_t::allocated_matcher_proxy_t
allocated_matcher_proxy_t(Args &&...args)
Definition: method_matcher.hpp:86
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::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::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::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::router::impl::simple_matcher_t::m_method
http_method_id_t m_method
Definition: method_matcher.hpp:112
restinio::router::method_matcher_t::~method_matcher_t
virtual ~method_matcher_t()=default
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::add
dynamic_any_of_methods_matcher_t & add(http_method_id_t method)
Definition: method_matcher.hpp:494
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
http_headers.hpp
restinio::router::method_matcher_t::operator=
method_matcher_t & operator=(const method_matcher_t &)=default
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
const
#define const
Definition: zconf.h:230
restinio::router::dynamic_none_of_methods_matcher_t::empty
RESTINIO_NODISCARD bool empty() const noexcept
Definition: method_matcher.hpp:570
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::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::dynamic_none_of_methods_matcher_t::m_methods
std::vector< http_method_id_t > m_methods
Definition: method_matcher.hpp:538