RESTinio
easy_parser.hpp
Go to the documentation of this file.
1 /*
2  * RESTinio
3  */
4 
13 #pragma once
14 
17 
20 
21 #include <restinio/string_view.hpp>
23 
24 #include <restinio/exception.hpp>
25 #include <restinio/optional.hpp>
26 #include <restinio/expected.hpp>
27 
28 #include <iostream>
29 #include <limits>
30 #include <map>
31 #include <array>
32 #include <vector>
33 #include <cstring>
34 
35 namespace restinio
36 {
37 
38 namespace easy_parser
39 {
40 
42 
43 //
44 // error_reason_t
45 //
51 enum class error_reason_t
52 {
54  unexpected_character,
56  unexpected_eof,
58  no_appropriate_alternative,
60  pattern_not_found,
63  unconsumed_input,
65 
68  illegal_value_found,
71 
82 };
83 
84 //
85 // parse_error_t
86 //
93 {
95  std::size_t m_position;
98 
99 public:
102  std::size_t position,
103  error_reason_t reason ) noexcept
104  : m_position{ position }
105  , m_reason{ reason }
106  {}
107 
110  std::size_t
111  position() const noexcept { return m_position; }
112 
116  reason() const noexcept { return m_reason; }
117 };
118 
119 //
120 // nothing_t
121 //
128 struct nothing_t {};
129 
130 //
131 // result_value_wrapper
132 //
178 template< typename T >
180 {
181  using result_type = T;
183 
184  static void
186  {
187  to = std::move(what);
188  }
189 
191  static result_type &&
193  {
194  return std::move(v);
195  }
196 };
197 
198 //
199 // result_wrapper_for
200 //
243 template< typename T >
245 {
247 };
248 
249 template< typename T >
251 
252 template< typename T, typename... Args >
253 struct result_value_wrapper< std::vector< T, Args... > >
254 {
255  using result_type = std::vector< T, Args... >;
256  using value_type = typename result_type::value_type;
258 
259  static void
261  {
262  to = std::move(what);
263  }
264 
265  static void
267  {
268  to.push_back( std::move(what) );
269  }
270 
272  static result_type &&
274  {
275  return std::move(v);
276  }
277 };
278 
279 namespace impl
280 {
281 
282 //
283 // std_array_wrapper
284 //
297 template< typename T, std::size_t S >
299 {
300  std::array< T, S > m_array;
301  std::size_t m_index{ 0u };
302 };
303 
304 } /* namespace impl */
305 
306 template< typename T, std::size_t S >
307 struct result_value_wrapper< std::array< T, S > >
308 {
309  using result_type = std::array< T, S >;
310  using value_type = typename result_type::value_type;
312 
313  static void
315  {
316  to.m_array = std::move(what);
317  to.m_index = 0u;
318  }
319 
320  static void
322  {
323  if( to.m_index >= S )
324  throw exception_t(
325  "index in the result std::array is out of range, "
326  "index=" + std::to_string(to.m_index) +
327  ", size={}" + std::to_string(S) );
328 
329  to.m_array[ to.m_index ] = std::move(what);
330  ++to.m_index;
331  }
332 
334  static result_type &&
336  {
337  return std::move(v.m_array);
338  }
339 };
340 
347 template< typename T, std::size_t S >
348 struct result_wrapper_for< impl::std_array_wrapper<T, S> >
349 {
351 };
352 
353 template< typename Char, typename... Args >
354 struct result_value_wrapper< std::basic_string< Char, Args... > >
355 {
356  using result_type = std::basic_string< Char, Args... >;
357  using value_type = Char;
359 
360  static void
362  {
363  to = std::move(what);
364  }
365 
366  static void
368  {
369  to.push_back( what );
370  }
371 
385  static void
387  {
388  to.append( what );
389  }
390 
392  static result_type &&
394  {
395  return std::move(v);
396  }
397 };
398 
399 template< typename K, typename V, typename... Args >
400 struct result_value_wrapper< std::map< K, V, Args... > >
401 {
402  using result_type = std::map< K, V, Args... >;
403  // NOTE: we can't use container_type::value_type here
404  // because value_type for std::map is std::pair<const K, V>,
405  // not just std::pair<K, V>,
406  using value_type = std::pair<K, V>;
408 
409  static void
411  {
412  to = std::move(what);
413  }
414 
415  static void
417  {
418  to.emplace( std::move(what) );
419  }
420 
422  static result_type &&
424  {
425  return std::move(v);
426  }
427 };
428 
429 template<>
431 {
435 
436  static void
437  as_result( wrapped_type &, result_type && ) noexcept {}
438 
439  static void
440  to_container( wrapped_type &, value_type && ) noexcept {}
441 
443  static result_type &&
445  {
446  return std::move(v);
447  }
448 };
449 
455 constexpr std::size_t N = std::numeric_limits<std::size_t>::max();
456 
457 //
458 // digits_to_consume_t
459 //
467 {
468 public:
469  using underlying_int_t = std::int_fast8_t;
470 
472 
480 
481 public:
486  constexpr
488  : m_min{ total }
489  , m_max{ total }
490  {}
491 
496  constexpr
499  underlying_int_t max ) noexcept
500  : m_min{ min }
501  , m_max{ max }
502  {}
503 
506  constexpr auto
507  min() const noexcept { return m_min; }
508 
511  constexpr auto
512  max() const noexcept { return m_max; }
513 
516  constexpr static auto
517  unlimited_max() noexcept
518  {
519  return std::numeric_limits<underlying_int_t>::max();
520  }
521 
526  constexpr static auto
527  from_one_to_max() noexcept
528  {
529  return digits_to_consume_t{ 1, unlimited_max() };
530  }
531 };
532 
548 inline constexpr digits_to_consume_t
550 {
551  return { total };
552 }
553 
569 inline constexpr digits_to_consume_t
573 {
574  return { min, max };
575 }
576 
577 namespace impl
578 {
579 
580 //
581 // character_t
582 //
593 {
594  bool m_eof;
595  char m_ch;
596 };
597 
599 inline bool
600 operator==( const character_t & a, const character_t & b ) noexcept
601 {
602  return (a.m_eof == b.m_eof && a.m_ch == b.m_ch);
603 }
604 
606 inline bool
607 operator!=( const character_t & a, const character_t & b ) noexcept
608 {
609  return (a.m_eof != b.m_eof || a.m_ch != b.m_ch);
610 }
611 
617 constexpr char SP = ' ';
623 constexpr char HTAB = '\x09';
624 
625 //
626 // is_space
627 //
634 inline constexpr bool
635 is_space( const char ch ) noexcept
636 {
637  return ch == SP || ch == HTAB;
638 }
639 
640 //
641 // is_space_predicate_t
642 //
650 {
652  bool
653  operator()( const char actual ) const noexcept
654  {
655  return is_space(actual);
656  }
657 };
658 
659 //
660 // is_digit
661 //
668 inline constexpr bool
669 is_digit( const char ch ) noexcept
670 {
671  return (ch >= '0' && ch <= '9');
672 }
673 
674 //
675 // is_digit_predicate_t
676 //
683 {
685  bool
686  operator()( const char actual ) const noexcept
687  {
688  return is_digit( actual );
689  }
690 };
691 
692 //
693 // is_hexdigit
694 //
701 inline constexpr bool
702 is_hexdigit( const char ch ) noexcept
703 {
704  return (ch >= '0' && ch <= '9') ||
705  (ch >= 'A' && ch <= 'F') ||
706  (ch >= 'a' && ch <= 'f');
707 }
708 
709 //
710 // is_hexdigit_predicate_t
711 //
719 {
721  bool
722  operator()( const char actual ) const noexcept
723  {
724  return is_hexdigit( actual );
725  }
726 };
727 
728 //
729 // source_t
730 //
739 class source_t
740 {
744 
749  string_view_t::size_type m_index{};
750 
751 public:
753  using position_t = string_view_t::size_type;
754 
756  explicit source_t( string_view_t data ) noexcept : m_data{ data } {}
757 
759 
764  character_t
765  getch() noexcept
766  {
767  if( m_index < m_data.size() )
768  {
769  return {false, m_data[ m_index++ ]};
770  }
771  else
772  return {true, 0};
773  }
774 
776  void
777  putback() noexcept
778  {
779  if( m_index )
780  --m_index;
781  }
782 
785  position_t
787  {
788  return m_index;
789  }
790 
793  void
794  backto( position_t pos ) noexcept
795  {
796  if( pos <= m_data.size() )
797  m_index = pos;
798  }
799 
802  bool
803  eof() const noexcept
804  {
805  return m_index >= m_data.size();
806  }
807 
809 
818  string_view_t::size_type from,
822  string_view_t::size_type length = string_view_t::npos ) const noexcept
823  {
824  return m_data.substr( from, length );
825  }
826 
851  {
854  bool m_consumed{ false };
855 
856  public :
857  content_consumer_t() = delete;
860 
861  content_consumer_t( source_t & from ) noexcept
862  : m_from{ from }
863  , m_started_at{ from.current_position() }
864  {}
865 
867  {
868  if( !m_consumed )
870  }
871 
872  position_t
873  started_at() const noexcept
874  {
875  return m_started_at;
876  }
877 
879 
884  void
885  commit() noexcept
886  {
887  m_consumed = true;
888  }
889  };
890 };
891 
892 //
893 // entity_type_t
894 //
900 enum class entity_type_t
901 {
903  producer,
905  transformer,
908  consumer,
910  clause,
913 
917 };
918 
919 //
920 // producer_tag
921 //
943 template< typename Result_Type >
945 {
946  using result_type = Result_Type;
947  static constexpr entity_type_t entity_type = entity_type_t::producer;
948 };
949 
950 template< typename T, typename = meta::void_t<> >
951 struct is_producer : public std::false_type {};
952 
953 template< typename T >
954 struct is_producer< T, meta::void_t< decltype(T::entity_type) > >
955 {
956  static constexpr bool value = entity_type_t::producer == T::entity_type;
957 };
958 
969 template< typename T >
971 
972 //
973 // transformer_tag
974 //
997 template< typename Result_Type >
999 {
1000  using result_type = Result_Type;
1001  static constexpr entity_type_t entity_type = entity_type_t::transformer;
1002 };
1003 
1004 template< typename T, typename = meta::void_t<> >
1005 struct is_transformer : public std::false_type {};
1006 
1007 template< typename T >
1008 struct is_transformer< T, meta::void_t< decltype(T::entity_type) > >
1009 {
1010  static constexpr bool value = entity_type_t::transformer == T::entity_type;
1011 };
1012 
1023 template< typename T >
1025 
1026 //
1027 // transformer_invoker
1028 //
1046 template< typename Result_Type >
1048 {
1049  template< typename Transformer, typename Input_Type >
1051  static Result_Type
1053  source_t &,
1054  Transformer & transformer,
1056  {
1057  return transformer.transform( std::move(*input) );
1058  }
1059 };
1060 
1067 template< typename Result_Type >
1069 {
1070  template< typename Transformer, typename Input_Type >
1074  // source_t is necessary to get the position in the case of an error.
1075  source_t & source,
1076  Transformer & transformer,
1078  {
1079  auto result = transformer.transform( std::move(*input) );
1080  if( result )
1081  return *result;
1082  else
1083  return make_unexpected( parse_error_t{
1084  source.current_position(),
1085  result.error()
1086  } );
1087  }
1088 };
1089 
1090 //
1091 // is_appropriate_transformer_result_type
1092 //
1109 template< typename Result_Type >
1111 {
1112  static constexpr bool value = true;
1113 };
1114 
1115 template< typename Result_Type >
1117  expected_t< Result_Type, error_reason_t > >
1118 {
1119  static constexpr bool value = true;
1120 };
1121 
1122 template< typename Result_Type >
1124  expected_t< Result_Type, parse_error_t > >
1125 {
1126  static constexpr bool value = false;
1127 };
1128 
1129 //
1130 // transformed_value_producer_traits_checker
1131 //
1143 template< typename Producer, typename Transformer >
1145 {
1146  static_assert( is_producer_v<Producer>,
1147  "Producer should be a producer type" );
1148  static_assert( is_transformer_v<Transformer>,
1149  "Transformer should be a transformer type" );
1150 
1151  using producer_result_t = std::decay_t< decltype(
1152  std::declval<Producer &>().try_parse( std::declval<source_t &>() )
1153  ) >;
1154 
1155  using transformation_result_t = std::decay_t< decltype(
1156  std::declval<Transformer &>().transform(
1157  std::move(*(std::declval<producer_result_t>())) )
1158  ) >;
1159 
1160  using expected_result_t = typename Transformer::result_type;
1161 
1162  static constexpr bool is_valid_transformation_result_type =
1164 };
1165 
1166 //
1167 // transformed_value_producer_t
1168 //
1178 template< typename Producer, typename Transformer >
1180  : public producer_tag< typename Transformer::result_type >
1181 {
1183  Producer, Transformer >;
1184 
1185  static_assert(
1187  "transformation result should be either T or "
1188  "expected_t<T, error_reson_t>, not expected_t<T, parse_error_t>" );
1189 
1190  Producer m_producer;
1191  Transformer m_transformer;
1192 
1193 public :
1194  using result_type = typename Transformer::result_type;
1195 
1197  Producer && producer,
1198  Transformer && transformer )
1199  : m_producer{ std::move(producer) }
1200  , m_transformer{ std::move(transformer) }
1201  {}
1202 
1205  try_parse( source_t & source )
1206  {
1207  auto producer_result = m_producer.try_parse( source );
1208  if( producer_result )
1209  {
1210  using transformation_result_t =
1212 
1214  source,
1215  m_transformer,
1216  std::move(producer_result) );
1217  }
1218  else
1219  return make_unexpected( producer_result.error() );
1220  }
1221 };
1222 
1228 template< typename P, typename T >
1230 std::enable_if_t<
1231  is_producer_v<P> & is_transformer_v<T>,
1232  transformed_value_producer_t< P, T > >
1234  P producer,
1235  T transformer )
1236 {
1237  using transformator_type = transformed_value_producer_t< P, T >;
1238 
1239  return transformator_type{ std::move(producer), std::move(transformer) };
1240 }
1241 
1242 //
1243 // transformer_proxy_tag
1244 //
1267 {
1269 };
1270 
1271 template< typename T, typename = meta::void_t<> >
1272 struct is_transformer_proxy : public std::false_type {};
1273 
1274 template< typename T >
1275 struct is_transformer_proxy< T, meta::void_t< decltype(T::entity_type) > >
1276 {
1277  static constexpr bool value = entity_type_t::transformer_proxy == T::entity_type;
1278 };
1279 
1289 template< typename T >
1291 
1298 template<
1299  typename P,
1300  typename T,
1301  typename S = std::enable_if_t<
1302  is_producer_v<P> & is_transformer_proxy_v<T>,
1303  void > >
1305 auto
1307  P producer,
1308  T transformer_proxy )
1309 {
1310  auto real_transformer = transformer_proxy.template make_transformer<
1311  typename P::result_type >();
1312 
1313  using transformator_type = std::decay_t< decltype(real_transformer) >;
1314 
1316 
1317  return producer_type{ std::move(producer), std::move(real_transformer) };
1318 }
1319 
1320 //
1321 // consumer_tag
1322 //
1343 {
1344  static constexpr entity_type_t entity_type = entity_type_t::consumer;
1345 };
1346 
1347 template< typename T, typename = meta::void_t<> >
1348 struct is_consumer : public std::false_type {};
1349 
1350 template< typename T >
1351 struct is_consumer< T, meta::void_t< decltype(T::entity_type) > >
1352 {
1353  static constexpr bool value = entity_type_t::consumer == T::entity_type;
1354 };
1355 
1366 template< typename T >
1368 
1369 //
1370 // clause_tag
1371 //
1393 {
1394  static constexpr entity_type_t entity_type = entity_type_t::clause;
1395 };
1396 
1397 template< typename T, typename = meta::void_t<> >
1398 struct is_clause : public std::false_type {};
1399 
1400 template< typename T >
1401 struct is_clause< T, meta::void_t<
1402  decltype(std::decay_t<T>::entity_type) > >
1403 {
1404  using real_type = std::decay_t<T>;
1405 
1406  static constexpr bool value = entity_type_t::clause == real_type::entity_type;
1407 };
1408 
1419 template< typename T >
1421 
1422 //
1423 // tuple_of_entities_t
1424 //
1455 template< typename... Entities >
1457  meta::transform_t< std::decay, meta::type_list<Entities...> >,
1458  std::tuple >;
1459 
1460 //
1461 // consume_value_clause_t
1462 //
1472 template< typename P, typename C >
1474 {
1475  static_assert( is_producer_v<P>, "P should be a producer type" );
1476  static_assert( is_consumer_v<C>, "C should be a consumer type" );
1477 
1480 
1481 public :
1482  consume_value_clause_t( P && producer, C && consumer )
1483  : m_producer{ std::move(producer) }
1484  , m_consumer{ std::move(consumer) }
1485  {}
1486 
1487  template< typename Target_Type >
1490  try_process( source_t & from, Target_Type & target )
1491  {
1492  auto parse_result = m_producer.try_parse( from );
1493  if( parse_result )
1494  {
1495  m_consumer.consume( target, std::move(*parse_result) );
1496  return nullopt;
1497  }
1498  else
1499  return parse_result.error();
1500  }
1501 };
1502 
1508 template< typename P, typename C >
1510 std::enable_if_t<
1511  is_producer_v<P> && is_consumer_v<C>,
1512  consume_value_clause_t< P, C > >
1513 operator>>( P producer, C consumer )
1514 {
1515  return { std::move(producer), std::move(consumer) };
1516 }
1517 
1518 //
1519 // top_level_clause_t
1520 //
1531 template< typename Producer >
1533 {
1534  static_assert( is_producer_v<Producer>,
1535  "Producer should be a producer type" );
1536 
1537  Producer m_producer;
1538 
1539 public :
1540  top_level_clause_t( Producer && producer )
1541  : m_producer{ std::move(producer) }
1542  {}
1543 
1545  auto
1547  {
1548  return m_producer.try_parse( from );
1549  }
1550 };
1551 
1552 //
1553 // ensure_no_remaining_content
1554 //
1567  source_t & from )
1568 {
1569  while( !from.eof() )
1570  {
1571  if( !is_space( from.getch().m_ch ) )
1572  {
1573  from.putback(); // Otherwise current_position() will be wrong.
1574  return parse_error_t{
1575  from.current_position(),
1576  error_reason_t::unconsumed_input
1577  };
1578  }
1579  }
1580 
1581  return nullopt;
1582 }
1583 
1584 //
1585 // remove_trailing_spaces
1586 //
1593 inline string_view_t
1595 {
1596  auto s = from.size();
1597  for(; s && is_space( from[ (s-1u) ] ); --s) {}
1598 
1599  return from.substr( 0u, s );
1600 }
1601 
1602 //
1603 // alternatives_clause_t
1604 //
1633 template<
1634  typename Subitems_Tuple >
1636 {
1637  Subitems_Tuple m_subitems;
1638 
1639 public :
1641  Subitems_Tuple && subitems )
1642  : m_subitems{ std::move(subitems) }
1643  {}
1644 
1645  template< typename Target_Type >
1648  try_process( source_t & from, Target_Type & target )
1649  {
1650  const auto starting_pos = from.current_position();
1651 
1652  optional_t< parse_error_t > actual_parse_error;
1653  const bool success = restinio::utils::tuple_algorithms::any_of(
1654  m_subitems,
1655  [&from, &target, &actual_parse_error]( auto && one_producer ) {
1656  source_t::content_consumer_t consumer{ from };
1657  Target_Type tmp_value{ target };
1658 
1659  actual_parse_error = one_producer.try_process( from, tmp_value );
1660  if( !actual_parse_error )
1661  {
1662  target = std::move(tmp_value);
1663  consumer.commit();
1664 
1665  return true;
1666  }
1667  else {
1668  // Since v.0.6.7 we should check for
1669  // force_only_this_alternative_failed error.
1670  // In the case of that error enumeration of alternatives
1671  // should be stopped.
1673  actual_parse_error->reason();
1674  }
1675  } );
1676 
1677  if( !success || actual_parse_error )
1678  return parse_error_t{
1679  starting_pos,
1680  error_reason_t::no_appropriate_alternative
1681  };
1682  else
1683  return nullopt;
1684  }
1685 };
1686 
1687 //
1688 // maybe_clause_t
1689 //
1714 template<
1715  typename Subitems_Tuple >
1717 {
1718  Subitems_Tuple m_subitems;
1719 
1720 public :
1722  Subitems_Tuple && subitems )
1723  : m_subitems{ std::move(subitems) }
1724  {}
1725 
1726  template< typename Target_Type >
1729  try_process( source_t & from, Target_Type & target )
1730  {
1731  source_t::content_consumer_t consumer{ from };
1732  Target_Type tmp_value{ target };
1733 
1734  const bool success = restinio::utils::tuple_algorithms::all_of(
1735  m_subitems,
1736  [&from, &tmp_value]( auto && one_producer ) {
1737  return !one_producer.try_process( from, tmp_value );
1738  } );
1739 
1740  if( success )
1741  {
1742  target = std::move(tmp_value);
1743  consumer.commit();
1744  }
1745 
1746  // maybe_clause always returns success even if nothing consumed.
1747  return nullopt;
1748  }
1749 };
1750 
1751 //
1752 // not_clause_t
1753 //
1777 template<
1778  typename Subitems_Tuple >
1779 class not_clause_t : public clause_tag
1780 {
1781  Subitems_Tuple m_subitems;
1782 
1783 public :
1785  Subitems_Tuple && subitems )
1786  : m_subitems{ std::move(subitems) }
1787  {}
1788 
1789  template< typename Target_Type >
1792  try_process( source_t & from, Target_Type & )
1793  {
1794  // NOTE: will always return the current position back.
1795  source_t::content_consumer_t consumer{ from };
1796 
1797  Target_Type dummy_value;
1798 
1799  const auto success = !restinio::utils::tuple_algorithms::all_of(
1800  m_subitems,
1801  [&from, &dummy_value]( auto && one_producer ) {
1802  return !one_producer.try_process( from, dummy_value );
1803  } );
1804 
1805  // This is contra-intuitive but: we return pattern_not_found in
1806  // the case when pattern is actually found in the input.
1807  if( !success )
1808  return parse_error_t{
1809  consumer.started_at(),
1810  //FIXME: maybe a more appropriate error_reason can
1811  //be used here?
1812  error_reason_t::pattern_not_found
1813  };
1814  else
1815  return nullopt;
1816  }
1817 };
1818 
1819 //
1820 // and_clause_t
1821 //
1845 template<
1846  typename Subitems_Tuple >
1847 class and_clause_t : public clause_tag
1848 {
1849  Subitems_Tuple m_subitems;
1850 
1851 public :
1853  Subitems_Tuple && subitems )
1854  : m_subitems{ std::move(subitems) }
1855  {}
1856 
1857  template< typename Target_Type >
1860  try_process( source_t & from, Target_Type & )
1861  {
1862  // NOTE: will always return the current position back.
1863  source_t::content_consumer_t consumer{ from };
1864 
1865  Target_Type dummy_value;
1866 
1867  const bool success = restinio::utils::tuple_algorithms::all_of(
1868  m_subitems,
1869  [&from, &dummy_value]( auto && one_producer ) {
1870  return !one_producer.try_process( from, dummy_value );
1871  } );
1872 
1873  if( !success )
1874  return parse_error_t{
1875  consumer.started_at(),
1876  error_reason_t::pattern_not_found
1877  };
1878  else
1879  return nullopt;
1880  }
1881 };
1882 
1883 //
1884 // sequence_clause_t
1885 //
1906 template<
1907  typename Subitems_Tuple >
1909 {
1910  Subitems_Tuple m_subitems;
1911 
1912 public :
1914  Subitems_Tuple && subitems )
1915  : m_subitems{ std::move(subitems) }
1916  {}
1917 
1918  template< typename Target_Type >
1921  try_process( source_t & from, Target_Type & target )
1922  {
1923  source_t::content_consumer_t consumer{ from };
1924  Target_Type tmp_value{ target };
1925 
1926  // We should store actual parse error from subitems to return it.
1928 
1929  const bool success = restinio::utils::tuple_algorithms::all_of(
1930  m_subitems,
1931  [&from, &tmp_value, &result]( auto && one_producer ) {
1932  result = one_producer.try_process( from, tmp_value );
1933  return !result;
1934  } );
1935 
1936  if( success )
1937  {
1938  target = std::move(tmp_value);
1939  consumer.commit();
1940  }
1941 
1942  return result;
1943  }
1944 };
1945 
1946 //
1947 // forced_alternative_clause_t
1948 //
1959 template<
1960  typename Subitems_Tuple >
1961 class forced_alternative_clause_t : public sequence_clause_t< Subitems_Tuple >
1962 {
1964 
1965 public :
1966  using base_type_t::base_type_t;
1967 
1968  template< typename Target_Type >
1971  try_process( source_t & from, Target_Type & target )
1972  {
1973  const auto starting_pos = from.current_position();
1974 
1975  if( base_type_t::try_process( from, target ) )
1976  {
1977  // The forced clause is not parsed correctly.
1978  // So the special error code should be returned in that case.
1979  return parse_error_t{
1980  starting_pos,
1982  };
1983  }
1984  else
1985  return nullopt;
1986  }
1987 };
1988 
1989 //
1990 // produce_t
1991 //
2006 template<
2007  typename Target_Type,
2008  typename Subitems_Tuple >
2009 class produce_t : public producer_tag< Target_Type >
2010 {
2012 
2013  Subitems_Tuple m_subitems;
2014 
2015 public :
2017  Subitems_Tuple && subitems )
2018  : m_subitems{ std::move(subitems) }
2019  {}
2020 
2024  {
2025  typename value_wrapper_t::wrapped_type tmp_value{};
2027 
2028  const bool success = restinio::utils::tuple_algorithms::all_of(
2029  m_subitems,
2030  [&from, &tmp_value, &error]( auto && one_clause ) {
2031  error = one_clause.try_process( from, tmp_value );
2032  return !error;
2033  } );
2034 
2035  if( success )
2036  return value_wrapper_t::unwrap_value( tmp_value );
2037  else
2038  return make_unexpected( *error );
2039  }
2040 };
2041 
2042 //
2043 // repeat_clause_t
2044 //
2058 template<
2059  typename Subitems_Tuple >
2061 {
2062  std::size_t m_min_occurences;
2063  std::size_t m_max_occurences;
2064 
2065  Subitems_Tuple m_subitems;
2066 
2067 public :
2069  std::size_t min_occurences,
2070  std::size_t max_occurences,
2071  Subitems_Tuple && subitems )
2072  : m_min_occurences{ min_occurences }
2073  , m_max_occurences{ max_occurences }
2074  , m_subitems{ std::move(subitems) }
2075  {}
2076 
2077  template< typename Target_Type >
2079  optional_t< parse_error_t >
2080  try_process( source_t & from, Target_Type & dest )
2081  {
2082  source_t::content_consumer_t whole_consumer{ from };
2083 
2084  std::size_t count{};
2085  bool failure_detected{ false };
2086  for(; !failure_detected && count != m_max_occurences; )
2087  {
2088  source_t::content_consumer_t item_consumer{ from };
2089 
2090  failure_detected = !restinio::utils::tuple_algorithms::all_of(
2091  m_subitems,
2092  [&from, &dest]( auto && one_clause ) {
2093  return !one_clause.try_process( from, dest );
2094  } );
2095 
2096  if( !failure_detected )
2097  {
2098  // Another item successfully parsed and should be stored.
2099  item_consumer.commit();
2100  ++count;
2101  }
2102  }
2103 
2104  if( count >= m_min_occurences )
2105  {
2106  whole_consumer.commit();
2107  return nullopt;
2108  }
2109 
2110  return parse_error_t{
2111  from.current_position(),
2112  error_reason_t::pattern_not_found
2113  };
2114  }
2115 };
2116 
2117 //
2118 // symbol_producer_template_t
2119 //
2129 template< typename Predicate >
2131  : public producer_tag< char >
2132  , protected Predicate
2133 {
2134 public:
2135  template< typename... Args >
2136  symbol_producer_template_t( Args &&... args )
2137  : Predicate{ std::forward<Args>(args)... }
2138  {}
2139 
2142  try_parse( source_t & from ) const noexcept
2143  {
2144  const auto ch = from.getch();
2145  if( !ch.m_eof )
2146  {
2147  // A call to predicate.
2148  if( (*this)(ch.m_ch) )
2149  return ch.m_ch;
2150  else
2151  {
2152  from.putback();
2153  return make_unexpected( parse_error_t{
2154  from.current_position(),
2155  error_reason_t::unexpected_character
2156  } );
2157  }
2158  }
2159  else
2160  return make_unexpected( parse_error_t{
2161  from.current_position(),
2162  error_reason_t::unexpected_eof
2163  } );
2164  }
2165 };
2166 
2167 //
2168 // any_symbol_predicate_t
2169 //
2179 {
2181  constexpr bool
2182  operator()( const char ) const noexcept
2183  {
2184  return true;
2185  }
2186 };
2187 
2188 //
2189 // particular_symbol_predicate_t
2190 //
2198 {
2200 
2202  bool
2203  operator()( const char actual ) const noexcept
2204  {
2205  return m_expected == actual;
2206  }
2207 };
2208 
2209 //
2210 // not_particular_symbol_predicate_t
2211 //
2219 {
2221 
2223  bool
2224  operator()( const char actual ) const noexcept
2225  {
2226  return m_sentinel != actual;
2227  }
2228 };
2229 
2230 //
2231 // caseless_particular_symbol_predicate_t
2232 //
2240 {
2242 
2245  {}
2246 
2248  bool
2249  operator()( const char actual ) const noexcept
2250  {
2251  return m_expected == restinio::impl::to_lower_case(actual);
2252  }
2253 };
2254 
2255 //
2256 // symbol_from_range_predicate_t
2257 //
2267 {
2268  char m_left;
2269  char m_right;
2270 
2272  bool
2273  operator()( const char actual ) const noexcept
2274  {
2275  return ( actual >= m_left && actual <= m_right );
2276  }
2277 };
2278 
2279 //
2280 // symbol_producer_t
2281 //
2291  : public symbol_producer_template_t< particular_symbol_predicate_t >
2292 {
2293  using base_type_t =
2295 
2296 public:
2297  symbol_producer_t( char expected )
2299  {}
2300 };
2301 
2302 //
2303 // any_symbol_if_not_producer_t
2304 //
2314  : public symbol_producer_template_t< not_particular_symbol_predicate_t >
2315 {
2316  using base_type_t =
2318 
2319 public:
2322  {}
2323 };
2324 
2325 //
2326 // caseless_symbol_producer_t
2327 //
2340  : public symbol_producer_template_t< caseless_particular_symbol_predicate_t >
2341 {
2342  using base_type_t =
2344 
2345 public:
2348  {}
2349 };
2350 
2351 //
2352 // symbol_from_range_producer_t
2353 //
2363  : public symbol_producer_template_t< symbol_from_range_predicate_t >
2364 {
2365  using base_type_t =
2367 
2368 public:
2369  symbol_from_range_producer_t( char left, char right )
2370  : base_type_t{ symbol_from_range_predicate_t{left, right} }
2371  {}
2372 };
2373 
2374 //
2375 // digit_producer_t
2376 //
2386  : public symbol_producer_template_t< is_digit_predicate_t >
2387 {
2388 public:
2390 };
2391 
2392 //
2393 // hexdigit_producer_t
2394 //
2404  : public symbol_producer_template_t< is_hexdigit_predicate_t >
2405 {
2406 public:
2408 };
2409 
2410 //
2411 // try_parse_digits_with_digits_limit
2412 //
2434 template< typename T, typename Value_Accumulator >
2438  source_t & from,
2439  digits_to_consume_t digits_limit,
2440  Value_Accumulator acc ) noexcept
2441 {
2442  source_t::content_consumer_t consumer{ from };
2443 
2444  digits_to_consume_t::underlying_int_t symbols_processed{};
2445 
2446  for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
2447  {
2448  if( is_digit(ch.m_ch) )
2449  {
2450  acc.next_digit( static_cast<T>(ch.m_ch - '0') );
2451 
2452  if( acc.overflow_detected() )
2453  return make_unexpected( parse_error_t{
2454  consumer.started_at(),
2455  error_reason_t::illegal_value_found
2456  } );
2457 
2458  ++symbols_processed;
2459  if( symbols_processed == digits_limit.max() )
2460  break;
2461  }
2462  else
2463  {
2464  from.putback();
2465  break;
2466  }
2467  }
2468 
2469  if( symbols_processed < digits_limit.min() )
2470  // Not all required digits are extracted.
2471  return make_unexpected( parse_error_t{
2472  from.current_position(),
2473  error_reason_t::pattern_not_found
2474  } );
2475  else
2476  {
2477  consumer.commit();
2478  return acc.value();
2479  }
2480 }
2481 
2482 //
2483 // try_parse_hexdigits_with_digits_limit
2484 //
2498 template< typename T, typename Value_Accumulator >
2502  source_t & from,
2503  digits_to_consume_t digits_limit,
2504  Value_Accumulator acc ) noexcept
2505 {
2506  const auto ch_to_digit = []( char ch ) -> std::pair<bool, T> {
2507  if( ch >= '0' && ch <= '9' )
2508  return std::make_pair( true, static_cast<T>(ch - '0') );
2509  else if( ch >= 'A' && ch <= 'F' )
2510  return std::make_pair( true, static_cast<T>(10 + (ch - 'A')) );
2511  else if( ch >= 'a' && ch <= 'f' )
2512  return std::make_pair( true, static_cast<T>(10 + (ch - 'a')) );
2513  else
2514  return std::make_pair( false, static_cast<T>(0) );
2515  };
2516 
2517  source_t::content_consumer_t consumer{ from };
2518 
2519  digits_to_consume_t::underlying_int_t symbols_processed{};
2520 
2521  for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
2522  {
2523  const auto d = ch_to_digit( ch.m_ch );
2524  if( d.first )
2525  {
2526  acc.next_digit( d.second );
2527 
2528  if( acc.overflow_detected() )
2529  return make_unexpected( parse_error_t{
2530  consumer.started_at(),
2531  error_reason_t::illegal_value_found
2532  } );
2533 
2534  ++symbols_processed;
2535  if( symbols_processed == digits_limit.max() )
2536  break;
2537  }
2538  else
2539  {
2540  from.putback();
2541  break;
2542  }
2543  }
2544 
2545  if( symbols_processed < digits_limit.min() )
2546  // Not all required digits are extracted.
2547  return make_unexpected( parse_error_t{
2548  from.current_position(),
2549  error_reason_t::pattern_not_found
2550  } );
2551  else
2552  {
2553  consumer.commit();
2554  return acc.value();
2555  }
2556 }
2557 
2558 //
2559 // non_negative_decimal_number_producer_t
2560 //
2569 template< typename T >
2571 {
2572 public:
2575  try_parse( source_t & from ) const noexcept
2576  {
2577  return try_parse_digits_with_digits_limit< T >(
2578  from,
2581  }
2582 };
2583 
2584 //
2585 // non_negative_decimal_number_producer_with_digits_limit_t
2586 //
2597 template< typename T >
2600 {
2602 
2603 public:
2605  digits_to_consume_t digits_limit )
2606  : m_digits_limit{ digits_limit }
2607  {}
2608 
2611  try_parse( source_t & from ) const noexcept
2612  {
2613  return try_parse_digits_with_digits_limit< T >(
2614  from,
2617  }
2618 };
2619 
2620 //
2621 // hexadecimal_number_producer_t
2622 //
2631 template< typename T >
2633 {
2634  static_assert( std::is_unsigned<T>::value,
2635  "T is expected to be unsigned type" );
2636 
2637 public:
2640  try_parse( source_t & from ) const noexcept
2641  {
2642  return try_parse_hexdigits_with_digits_limit< T >(
2643  from,
2646  }
2647 };
2648 
2649 //
2650 // hexadecimal_number_producer_with_digits_limit_t
2651 //
2662 template< typename T >
2664  : public hexadecimal_number_producer_t< T >
2665 {
2667 
2668 public:
2670  digits_to_consume_t digits_limit )
2671  : m_digits_limit{ digits_limit }
2672  {}
2673 
2676  try_parse( source_t & from ) const noexcept
2677  {
2678  return try_parse_hexdigits_with_digits_limit< T >(
2679  from,
2682  }
2683 };
2684 
2685 //
2686 // decimal_number_producer_t
2687 //
2696 template< typename T >
2698 {
2699  static_assert( std::is_signed<T>::value,
2700  "decimal_number_producer_t can be used only for signed types" );
2701 
2702 public:
2704 
2707  try_parse( source_t & from ) const noexcept
2708  {
2709  return try_parse_impl( from,
2710  []() noexcept {
2712  } );
2713  }
2714 
2715 protected:
2716  template< typename Digits_Limit_Maker >
2720  source_t & from,
2721  Digits_Limit_Maker && digits_limit_maker ) const noexcept
2722  {
2723  source_t::content_consumer_t consumer{ from };
2724 
2725  auto sign_ch = from.getch();
2726  if( !sign_ch.m_eof )
2727  {
2728  const auto r = try_parse_with_this_first_symbol(
2729  from,
2730  sign_ch.m_ch,
2731  std::forward<Digits_Limit_Maker>(digits_limit_maker) );
2732 
2733  if( r )
2734  consumer.commit();
2735 
2736  return r;
2737  }
2738  else
2739  return make_unexpected( parse_error_t{
2740  from.current_position(),
2741  error_reason_t::pattern_not_found
2742  } );
2743  }
2744 
2745 private:
2746  template< typename Digits_Limit_Maker >
2748  static try_parse_result_type
2750  source_t & from,
2751  char first_symbol,
2752  Digits_Limit_Maker && digits_limit_maker ) noexcept
2753  {
2756 
2757  if( '-' == first_symbol )
2758  {
2759  const auto r = try_parse_digits_with_digits_limit< T >(
2760  from,
2761  digits_limit_maker(),
2762  overflow_controlled_integer_accumulator_t<
2763  T,
2764  10,
2765  check_negative_extremum >{} );
2766  if( r )
2767  return static_cast< T >( -(*r) ); // This static_cast is required
2768  // for clang compiler that warns that if type of *r is `short`,
2769  // then -(*r) will have type `int`.
2770  else
2771  return r;
2772  }
2773  else if( '+' == first_symbol )
2774  {
2775  return try_parse_digits_with_digits_limit< T >(
2776  from,
2777  digits_limit_maker(),
2778  overflow_controlled_integer_accumulator_t< T, 10 >{} );
2779  }
2780  else if( is_digit(first_symbol) )
2781  {
2782  from.putback();
2783  return try_parse_digits_with_digits_limit< T >(
2784  from,
2785  digits_limit_maker(),
2786  overflow_controlled_integer_accumulator_t< T, 10 >{} );
2787  }
2788 
2789  return make_unexpected( parse_error_t{
2790  from.current_position(),
2791  error_reason_t::pattern_not_found
2792  } );
2793  }
2794 };
2795 
2796 //
2797 // decimal_number_producer_with_digits_limit_t
2798 //
2809 template< typename T >
2811  : public decimal_number_producer_t< T >
2812 {
2814 
2815 public:
2817  digits_to_consume_t digits_limit )
2818  : m_digits_limit{ digits_limit }
2819  {}
2820 
2822  auto
2823  try_parse( source_t & from ) const noexcept
2824  {
2825  return this->try_parse_impl(
2826  from,
2827  [this]() noexcept { return m_digits_limit; } );
2828  }
2829 };
2830 
2831 //
2832 // any_value_skipper_t
2833 //
2843 {
2844  template< typename Target_Type, typename Value >
2845  void
2846  consume( Target_Type &, Value && ) const noexcept {}
2847 };
2848 
2849 //
2850 // as_result_consumer_t
2851 //
2870 {
2871  template< typename Target_Type, typename Value >
2872  void
2873  consume( Target_Type & dest, Value && src ) const
2874  {
2876  dest, std::forward<Value>(src) );
2877  }
2878 };
2879 
2880 //
2881 // just_result_consumer_t
2882 //
2890 template< typename Result_Type >
2892 {
2893  Result_Type m_result;
2894 
2895  // NOTE: this helper method is necessary for MSVC++ compiler.
2896  // It's because MSVC++ can't compile expression:
2897  //
2898  // as_result(dest, Result_Type{m_result})
2899  //
2900  // in consume() method for trivial types like size_t.
2901  Result_Type
2903  noexcept(noexcept(Result_Type{m_result}))
2904  {
2905  return m_result;
2906  }
2907 
2908 public :
2909  template< typename Result_Arg >
2910  just_result_consumer_t( Result_Arg && result )
2911  noexcept(noexcept(Result_Type{std::forward<Result_Arg>(result)}))
2912  : m_result{ std::forward<Result_Arg>(result) }
2913  {}
2914 
2915  template< typename Target_Type, typename Value >
2916  void
2917  consume( Target_Type & dest, Value && ) const
2918  {
2920  dest,
2921  // NOTE: use a copy of m_result.
2922  make_copy_of_result() );
2923  }
2924 };
2925 
2926 //
2927 // custom_consumer_t
2928 //
2938 template< typename C >
2940 {
2942 
2943 public :
2944  custom_consumer_t( C && consumer ) : m_consumer{std::move(consumer)} {}
2945 
2946  template< typename Target_Type, typename Value >
2947  void
2948  consume( Target_Type & dest, Value && src ) const
2949  noexcept(noexcept(m_consumer(dest, std::forward<Value>(src))))
2950  {
2951  m_consumer( dest, std::forward<Value>(src) );
2952  }
2953 };
2954 
2955 //
2956 // field_setter_consumer_t
2957 //
2967 template< typename F, typename C >
2969 {
2970  using pointer_t = F C::*;
2971 
2973 
2974 public :
2975  field_setter_consumer_t( pointer_t ptr ) noexcept : m_ptr{ptr} {}
2976 
2977  // NOTE: it seems that this method won't be compiled if
2978  // result_value_wrapper::result_type differs from
2979  // result_value_wrapper::wrapped_type.
2980  //
2981  // This is not a problem for the current version.
2982  // But this moment would require more attention in the future.
2983  void
2984  consume( C & to, F && value ) const
2985  noexcept(noexcept(to.*m_ptr = std::move(value)))
2986  {
2987  to.*m_ptr = std::move(value);
2988  }
2989 };
2990 
2997 template< typename P, typename F, typename C >
2999 std::enable_if_t<
3000  is_producer_v<P>,
3001  consume_value_clause_t< P, field_setter_consumer_t<F,C> > >
3002 operator>>( P producer, F C::*member_ptr )
3003 {
3004  return {
3005  std::move(producer),
3006  field_setter_consumer_t<F,C>{ member_ptr }
3007  };
3008 }
3009 
3010 //
3011 // tuple_item_consumer_t
3012 //
3019 template< std::size_t Index >
3021 {
3022  // NOTE: it seems that this method won't be compiled if
3023  // result_value_wrapper::result_type differs from
3024  // result_value_wrapper::wrapped_type.
3025  //
3026  // This is not a problem for the current version.
3027  // But this moment would require more attention in the future.
3028  template< typename Target_Type, typename Value >
3029  void
3030  consume( Target_Type && to, Value && value )
3031  {
3032  std::get<Index>(std::forward<Target_Type>(to)) =
3033  std::forward<Value>(value);
3034  }
3035 };
3036 
3037 //
3038 // to_lower_transformer_t
3039 //
3040 template< typename Input_Type >
3042 
3049 template<>
3050 struct to_lower_transformer_t< std::string >
3051  : public transformer_tag< std::string >
3052 {
3053  using input_type = std::string;
3054 
3056  result_type
3057  transform( input_type && input ) const noexcept
3058  {
3059  result_type result{ std::move(input) };
3060  std::transform( result.begin(), result.end(), result.begin(),
3061  []( unsigned char ch ) -> char {
3062  return restinio::impl::to_lower_case(ch);
3063  } );
3064 
3065  return result;
3066  }
3067 };
3068 
3075 template<>
3077  : public transformer_tag< char >
3078 {
3079  using input_type = char;
3080 
3082  result_type
3083  transform( input_type && input ) const noexcept
3084  {
3085  return restinio::impl::to_lower_case(input);
3086  }
3087 };
3088 
3095 template< std::size_t S >
3096 struct to_lower_transformer_t< std::array< char, S > >
3097  : public transformer_tag< std::array< char, S > >
3098 {
3099  using input_type = std::array< char, S >;
3101 
3103  typename base_type::result_type
3104  transform( input_type && input ) const noexcept
3105  {
3106  typename base_type::result_type result;
3107  std::transform( input.begin(), input.end(), result.begin(),
3108  []( unsigned char ch ) -> char {
3109  return restinio::impl::to_lower_case(ch);
3110  } );
3111 
3112  return result;
3113  }
3114 };
3115 
3116 //
3117 // to_lower_transformer_proxy_t
3118 //
3125 {
3126  template< typename Input_Type >
3128  auto
3130  {
3132  }
3133 };
3134 
3135 //
3136 // just_value_transformer_t
3137 //
3144 template< typename T >
3146 {
3148 
3149 public :
3150  just_value_transformer_t( T v ) noexcept(noexcept(T{std::move(v)}))
3151  : m_value{ std::move(v) }
3152  {}
3153 
3154  template< typename Input >
3156  T
3157  transform( Input && ) const noexcept(noexcept(T{m_value}))
3158  {
3159  return m_value;
3160  }
3161 };
3162 
3163 //
3164 // convert_transformer_t
3165 //
3172 template< typename Output_Type, typename Converter >
3173 class convert_transformer_t : public transformer_tag< Output_Type >
3174 {
3175  Converter m_converter;
3176 
3177 public :
3178  template< typename Convert_Arg >
3179  convert_transformer_t( Convert_Arg && converter )
3180  noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
3181  : m_converter{ std::forward<Convert_Arg>(converter) }
3182  {}
3183 
3192  template< typename Input >
3194  auto
3195  transform( Input && input ) const
3196  noexcept(noexcept(m_converter(std::forward<Input>(input))))
3197  {
3198  using actual_result_t = std::decay_t< decltype(
3199  m_converter(std::forward<Input>(input))
3200  ) >;
3201 
3202  static_assert(
3204  "the return value of converter should be either Output_Type or "
3205  "expected_t<Output_Type, error_reason_t>" );
3206 
3207  return m_converter(std::forward<Input>(input));
3208  }
3209 };
3210 
3211 //
3212 // conversion_result_type_detector
3213 //
3224 template< typename Result_Type >
3226 {
3227  using type = Result_Type;
3228 };
3229 
3230 template< typename Result_Type >
3232 {
3233  using type = Result_Type;
3234 };
3235 
3241 template< typename Result_Type >
3244 
3245 //
3246 // convert_transformer_proxy_t
3247 //
3261 template< typename Converter >
3263 {
3264  template< typename Input_Type >
3266  std::decay_t< decltype(
3267  std::declval<Converter &>()(std::declval<Input_Type&&>())
3268  ) >
3269  >;
3270 
3271  Converter m_converter;
3272 
3273 public :
3274  template< typename Convert_Arg >
3275  convert_transformer_proxy_t( Convert_Arg && converter )
3276  noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
3277  : m_converter{ std::forward<Convert_Arg>(converter) }
3278  {}
3279 
3280  template< typename Input_Type >
3282  auto
3284  noexcept(noexcept(Converter{m_converter}))
3285  {
3286  using output_t = output<Input_Type>;
3287 
3289  }
3290 
3291  template< typename Input_Type >
3293  auto
3295  noexcept(noexcept(Converter{std::move(m_converter)}))
3296  {
3297  using output_t = output<Input_Type>;
3298 
3301  };
3302  }
3303 };
3304 
3305 //
3306 // try_parse_exact_fragment
3307 //
3308 
3309 // Requires that begin is not equal to end.
3310 template< typename It >
3312 expected_t< bool, parse_error_t >
3313 try_parse_exact_fragment( source_t & from, It begin, It end )
3314 {
3315  assert( begin != end );
3316 
3317  source_t::content_consumer_t consumer{ from };
3318 
3319  for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
3320  {
3321  if( ch.m_ch != *begin )
3322  return make_unexpected( parse_error_t{
3323  consumer.started_at(),
3324  error_reason_t::pattern_not_found
3325  } );
3326  if( ++begin == end )
3327  break;
3328  }
3329 
3330  if( begin != end )
3331  return make_unexpected( parse_error_t{
3332  consumer.started_at(),
3333  error_reason_t::unexpected_eof
3334  } );
3335 
3336  consumer.commit();
3337 
3338  return true;
3339 }
3340 
3341 //
3342 // exact_fixed_size_fragment_producer_t
3343 //
3353 template< std::size_t Size >
3355  : public producer_tag< bool >
3356 {
3357  static_assert( 1u < Size, "Size is expected to greater that 1" );
3358 
3359  // NOTE: there is no space for last zero-byte.
3360  std::array< char, Size-1u > m_fragment;
3361 
3362 public:
3363  exact_fixed_size_fragment_producer_t( const char (&f)[Size] )
3364  {
3365  // NOTE: last zero-byte is discarded.
3366  std::copy( &f[ 0 ], &f[ m_fragment.size() ], m_fragment.data() );
3367  }
3368 
3372  {
3373  return try_parse_exact_fragment( from,
3374  m_fragment.begin(), m_fragment.end() );
3375  }
3376 };
3377 
3378 //
3379 // exact_fragment_producer_t
3380 //
3388  : public producer_tag< bool >
3389 {
3390  std::string m_fragment;
3391 
3392 public:
3393  exact_fragment_producer_t( std::string fragment )
3394  : m_fragment{ std::move(fragment) }
3395  {
3396  if( m_fragment.empty() )
3397  throw exception_t( "'fragment' value for exact_fragment_producer_t "
3398  "can't be empty!" );
3399  }
3400 
3404  {
3405  return try_parse_exact_fragment( from,
3406  m_fragment.begin(), m_fragment.end() );
3407  }
3408 };
3409 
3410 //
3411 // try_parse_caseless_exact_fragment
3412 //
3413 
3414 // Requires that begin is not equal to end.
3415 // It assumes that content in [begin, end) is already in lower case.
3416 template< typename It >
3419 try_parse_caseless_exact_fragment( source_t & from, It begin, It end )
3420 {
3421  assert( begin != end );
3422 
3423  source_t::content_consumer_t consumer{ from };
3424 
3425  for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
3426  {
3427  if( restinio::impl::to_lower_case(ch.m_ch) != *begin )
3428  return make_unexpected( parse_error_t{
3429  consumer.started_at(),
3430  error_reason_t::pattern_not_found
3431  } );
3432  if( ++begin == end )
3433  break;
3434  }
3435 
3436  if( begin != end )
3437  return make_unexpected( parse_error_t{
3438  consumer.started_at(),
3439  error_reason_t::unexpected_eof
3440  } );
3441 
3442  consumer.commit();
3443 
3444  return true;
3445 }
3446 
3447 //
3448 // caseless_exact_fixed_size_fragment_producer_t
3449 //
3461 template< std::size_t Size >
3463  : public producer_tag< bool >
3464 {
3465  static_assert( 1u < Size, "Size is expected to greater that 1" );
3466 
3467  // NOTE: there is no space for last zero-byte.
3468  std::array< char, Size-1u > m_fragment;
3469 
3470 public:
3472  {
3473  // Content should be converted to lower-case.
3474  // NOTE: last zero-byte is discarded.
3476  &f[ 0 ], &f[ m_fragment.size() ],
3477  m_fragment.data(),
3478  []( const char src ) {
3479  return restinio::impl::to_lower_case( src );
3480  } );
3481  }
3482 
3486  {
3487  return try_parse_caseless_exact_fragment( from,
3488  m_fragment.begin(), m_fragment.end() );
3489  }
3490 };
3491 
3492 //
3493 // caseless_exact_fragment_producer_t
3494 //
3504  : public producer_tag< bool >
3505 {
3506  std::string m_fragment;
3507 
3508 public:
3509  caseless_exact_fragment_producer_t( std::string fragment )
3510  : m_fragment{ std::move(fragment) }
3511  {
3512  if( m_fragment.empty() )
3513  throw exception_t( "'fragment' value for exact_fragment_producer_t "
3514  "can't be empty!" );
3515 
3516  // Content should be converted to lower-case.
3517  for( auto & ch : m_fragment )
3518  ch = restinio::impl::to_lower_case( ch );
3519  }
3520 
3524  {
3525  return try_parse_caseless_exact_fragment( from,
3526  m_fragment.begin(), m_fragment.end() );
3527  }
3528 };
3529 
3530 } /* namespace impl */
3531 
3532 //
3533 // produce
3534 //
3549 template<
3550  typename Target_Type,
3551  typename... Clauses >
3553 auto
3554 produce( Clauses &&... clauses )
3555 {
3556  static_assert( 0 != sizeof...(clauses),
3557  "list of clauses can't be empty" );
3558  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3559  "all arguments for produce() should be clauses" );
3560 
3561  using producer_type_t = impl::produce_t<
3562  Target_Type,
3563  impl::tuple_of_entities_t<Clauses...> >;
3564 
3565  return producer_type_t{
3566  std::make_tuple(std::forward<Clauses>(clauses)...)
3567  };
3568 }
3569 
3570 //
3571 // alternatives
3572 //
3592 template< typename... Clauses >
3594 auto
3595 alternatives( Clauses &&... clauses )
3596 {
3597  static_assert( 0 != sizeof...(clauses),
3598  "list of clauses can't be empty" );
3599  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3600  "all arguments for alternatives() should be clauses" );
3601 
3602  using clause_type_t = impl::alternatives_clause_t<
3603  impl::tuple_of_entities_t< Clauses... > >;
3604 
3605  return clause_type_t{
3606  std::make_tuple(std::forward<Clauses>(clauses)...)
3607  };
3608 }
3609 
3610 //
3611 // maybe
3612 //
3631 template< typename... Clauses >
3633 auto
3634 maybe( Clauses &&... clauses )
3635 {
3636  static_assert( 0 != sizeof...(clauses),
3637  "list of clauses can't be empty" );
3638  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3639  "all arguments for maybe() should be clauses" );
3640 
3641  using clause_type_t = impl::maybe_clause_t<
3642  impl::tuple_of_entities_t<Clauses...> >;
3643 
3644  return clause_type_t{
3645  std::make_tuple(std::forward<Clauses>(clauses)...)
3646  };
3647 }
3648 
3649 //
3650 // not_clause
3651 //
3673 template< typename... Clauses >
3675 auto
3676 not_clause( Clauses &&... clauses )
3677 {
3678  static_assert( 0 != sizeof...(clauses),
3679  "list of clauses can't be empty" );
3680  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3681  "all arguments for not_clause() should be clauses" );
3682 
3683  using clause_type_t = impl::not_clause_t<
3684  impl::tuple_of_entities_t<Clauses...> >;
3685 
3686  return clause_type_t{
3687  std::make_tuple(std::forward<Clauses>(clauses)...)
3688  };
3689 }
3690 
3691 //
3692 // and_clause
3693 //
3715 template< typename... Clauses >
3717 auto
3718 and_clause( Clauses &&... clauses )
3719 {
3720  static_assert( 0 != sizeof...(clauses),
3721  "list of clauses can't be empty" );
3722  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3723  "all arguments for sequence() should be clauses" );
3724 
3725  using clause_type_t = impl::and_clause_t<
3726  impl::tuple_of_entities_t<Clauses...> >;
3727 
3728  return clause_type_t{
3729  std::make_tuple(std::forward<Clauses>(clauses)...)
3730  };
3731 }
3732 
3733 //
3734 // sequence
3735 //
3755 template< typename... Clauses >
3757 auto
3758 sequence( Clauses &&... clauses )
3759 {
3760  static_assert( 0 != sizeof...(clauses),
3761  "list of clauses can't be empty" );
3762  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3763  "all arguments for sequence() should be clauses" );
3764 
3765  using clause_type_t = impl::sequence_clause_t<
3766  impl::tuple_of_entities_t< Clauses... > >;
3767 
3768  return clause_type_t{
3769  std::make_tuple(std::forward<Clauses>(clauses)...)
3770  };
3771 }
3772 
3773 //
3774 // force_only_this_alternative
3775 //
3818 template< typename... Clauses >
3820 auto
3821 force_only_this_alternative( Clauses &&... clauses )
3822 {
3823  static_assert( 0 != sizeof...(clauses),
3824  "list of clauses can't be empty" );
3825  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3826  "all arguments for force_only_this_alternative() should "
3827  "be clauses" );
3828 
3829  using clause_type_t = impl::forced_alternative_clause_t<
3830  impl::tuple_of_entities_t< Clauses... > >;
3831 
3832  return clause_type_t{
3833  std::make_tuple(std::forward<Clauses>(clauses)...)
3834  };
3835 }
3836 
3837 //
3838 // repeat
3839 //
3872 template<
3873  typename... Clauses >
3875 auto
3878  std::size_t min_occurences,
3880 
3885  std::size_t max_occurences,
3887  Clauses &&... clauses )
3888 {
3889  static_assert( 0 != sizeof...(clauses),
3890  "list of clauses can't be empty" );
3891  static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3892  "all arguments for repeat() should be clauses" );
3893 
3894  using producer_type_t = impl::repeat_clause_t<
3895  impl::tuple_of_entities_t<Clauses...> >;
3896 
3897  return producer_type_t{
3898  min_occurences,
3899  max_occurences,
3900  std::make_tuple(std::forward<Clauses>(clauses)...)
3901  };
3902 }
3903 
3904 //
3905 // skip
3906 //
3921 inline auto
3922 skip() noexcept { return impl::any_value_skipper_t{}; }
3923 
3924 //
3925 // any_symbol_p
3926 //
3936 inline auto
3937 any_symbol_p() noexcept
3938 {
3940 }
3941 
3942 //
3943 // symbol_p
3944 //
3954 inline auto
3955 symbol_p( char expected ) noexcept
3956 {
3957  return impl::symbol_producer_t{expected};
3958 }
3959 
3960 //
3961 // any_symbol_if_not_p
3962 //
3972 inline auto
3973 any_symbol_if_not_p( char sentinel ) noexcept
3974 {
3975  return impl::any_symbol_if_not_producer_t{sentinel};
3976 }
3977 
3978 //
3979 // caseless_symbol_p
3980 //
3992 inline auto
3993 caseless_symbol_p( char expected ) noexcept
3994 {
3995  return impl::caseless_symbol_producer_t{expected};
3996 }
3997 
3998 //
3999 // symbol_from_range_p
4000 //
4010 inline auto
4011 symbol_from_range_p( char left, char right ) noexcept
4012 {
4013  return impl::symbol_from_range_producer_t{left, right};
4014 }
4015 
4016 //
4017 // symbol
4018 //
4031 inline auto
4032 symbol( char expected ) noexcept
4033 {
4034  return symbol_p(expected) >> skip();
4035 }
4036 
4037 //
4038 // caseless_symbol
4039 //
4054 inline auto
4055 caseless_symbol( char expected ) noexcept
4056 {
4057  return caseless_symbol_p(expected) >> skip();
4058 }
4059 
4060 //
4061 // symbol_from_range
4062 //
4075 inline auto
4076 symbol_from_range( char left, char right ) noexcept
4077 {
4078  return symbol_from_range_p(left, right) >> skip();
4079 }
4080 
4081 //
4082 // space_p
4083 //
4093 inline auto
4094 space_p() noexcept
4095 {
4097 }
4098 
4099 //
4100 // space
4101 //
4114 inline auto
4115 space() noexcept
4116 {
4117  return space_p() >> skip();
4118 }
4119 
4120 //
4121 // digit_p
4122 //
4132 inline auto
4133 digit_p() noexcept
4134 {
4135  return impl::digit_producer_t{};
4136 }
4137 
4138 //
4139 // digit
4140 //
4153 inline auto
4154 digit() noexcept
4155 {
4156  return digit_p() >> skip();
4157 }
4158 
4159 //
4160 // hexdigit_p
4161 //
4171 inline auto
4172 hexdigit_p() noexcept
4173 {
4174  return impl::hexdigit_producer_t{};
4175 }
4176 
4177 //
4178 // hexdigit
4179 //
4192 inline auto
4193 hexdigit() noexcept
4194 {
4195  return hexdigit_p() >> skip();
4196 }
4197 
4198 //
4199 // non_negative_decimal_number_p
4200 //
4215 template< typename T >
4217 inline auto
4219 {
4221 }
4222 
4223 //
4224 // non_negative_decimal_number_p
4225 //
4254 template< typename T >
4256 inline auto
4258 {
4260  digits_limit
4261  };
4262 }
4263 
4264 //FIXME: remove in v.0.7.0!
4265 //
4266 // positive_decimal_number_p
4267 //
4276 template< typename T >
4277 [[deprecated]] RESTINIO_NODISCARD
4278 inline auto
4280 {
4281  return non_negative_decimal_number_p<T>();
4282 }
4283 
4284 //
4285 // hexadecimal_number_p
4286 //
4304 template< typename T >
4306 inline auto
4308 {
4310 }
4311 
4312 //
4313 // hexadecimal_number_p
4314 //
4346 template< typename T >
4348 inline auto
4350 {
4352  digits_limit
4353  };
4354 }
4355 
4356 //
4357 // decimal_number_p
4358 //
4384 template< typename T >
4386 inline auto
4388 {
4389  static_assert( std::is_signed<T>::value,
4390  "decimal_number_p() can be used only for signed numeric types" );
4391 
4393 }
4394 
4395 //
4396 // decimal_number_p
4397 //
4437 template< typename T >
4439 inline auto
4440 decimal_number_p( digits_to_consume_t digits_limit ) noexcept
4441 {
4442  static_assert( std::is_signed<T>::value,
4443  "decimal_number_p() can be used only for signed numeric types" );
4444 
4446  digits_limit
4447  };
4448 }
4449 
4450 //
4451 // as_result
4452 //
4469 inline auto
4470 as_result() noexcept { return impl::as_result_consumer_t{}; }
4471 
4472 //
4473 // custom_consumer
4474 //
4513 template< typename F >
4515 auto
4516 custom_consumer( F consumer )
4517 {
4518  using actual_consumer_t = impl::custom_consumer_t< F >;
4519 
4520  return actual_consumer_t{ std::move(consumer) };
4521 }
4522 
4523 namespace impl
4524 {
4525 
4526 //
4527 // to_container_consumer_t
4528 //
4541 {
4542  template< typename Container, typename Item >
4543  void
4544  consume( Container & to, Item && item )
4545  {
4546  using container_adaptor_type = result_wrapper_for_t<Container>;
4548  }
4549 };
4550 
4551 } /* namespace impl */
4552 
4553 //
4554 // to_container
4555 //
4582 inline auto
4584 {
4586 }
4587 
4588 //
4589 // to_lower
4590 //
4609 inline auto
4611 
4612 //
4613 // just
4614 //
4632 template< typename T >
4634 auto
4635 just( T value ) noexcept(noexcept(impl::just_value_transformer_t<T>{value}))
4636 {
4637  return impl::just_value_transformer_t<T>{value};
4638 }
4639 
4640 //
4641 // just_result
4642 //
4661 template< typename T >
4663 auto
4664 just_result( T value )
4665  noexcept(noexcept(impl::just_result_consumer_t<T>{value}))
4666 {
4667  return impl::just_result_consumer_t<T>{value};
4668 }
4669 
4670 //
4671 // convert
4672 //
4734 template< typename Converter >
4736 auto
4737 convert( Converter && converter )
4738 {
4739  using converter_type = std::decay_t<Converter>;
4740 
4741  using transformer_proxy_type = impl::convert_transformer_proxy_t<
4742  converter_type >;
4743 
4744  return transformer_proxy_type{ std::forward<Converter>(converter) };
4745 }
4746 
4747 //
4748 // exact_p
4749 //
4767 inline auto
4769 {
4771  std::string{ fragment.data(), fragment.size() }
4772  };
4773 }
4774 
4809 template< std::size_t Size >
4811 auto
4812 exact_p( const char (&fragment)[Size] )
4813 {
4815 }
4816 
4817 //
4818 // exact
4819 //
4832 inline auto
4834 {
4836  std::string{ fragment.data(), fragment.size() }
4837  } >> skip();
4838 }
4839 
4868 template< std::size_t Size >
4870 auto
4871 exact( const char (&fragment)[Size] )
4872 {
4874 }
4875 
4876 //
4877 // caseless_exact_p
4878 //
4896 inline auto
4898 {
4900  std::string{ fragment.data(), fragment.size() }
4901  };
4902 }
4903 
4938 template< std::size_t Size >
4940 auto
4941 caseless_exact_p( const char (&fragment)[Size] )
4942 {
4944 }
4945 
4946 //
4947 // caseless_exact
4948 //
4961 inline auto
4963 {
4965  std::string{ fragment.data(), fragment.size() }
4966  } >> skip();
4967 }
4968 
4997 template< std::size_t Size >
4999 auto
5000 caseless_exact( const char (&fragment)[Size] )
5001 {
5003 }
5004 
5005 //
5006 // try_parse
5007 //
5039 template< typename Producer >
5043  string_view_t from,
5044  Producer producer )
5045 {
5046  static_assert( impl::is_producer_v<Producer>,
5047  "Producer should be a value producer type" );
5048 
5049  from = impl::remove_trailing_spaces( from );
5050  impl::source_t source{ from };
5051 
5052  auto result = impl::top_level_clause_t< Producer >{ std::move(producer) }
5053  .try_process( source );
5054 
5055  if( result )
5056  {
5057  // We should ensure that all content has been consumed.
5058  const auto all_content_check =
5060  if( all_content_check )
5061  return make_unexpected( *all_content_check );
5062  }
5063 
5064  return result;
5065 }
5066 
5067 //
5068 // make_error_description
5069 //
5102 inline std::string
5104  const parse_error_t & error,
5105  string_view_t from )
5106 {
5107  const auto append_quote = [&]( std::string & dest ) {
5108  constexpr std::size_t max_quote_size = 16u;
5109  if( error.position() > 0u )
5110  {
5111  // How many chars we can get from right of error position?
5112  const auto prefix_size = error.position() > max_quote_size ?
5113  max_quote_size : error.position();
5114 
5115  dest.append( 1u, '"' );
5116  dest.append(
5117  &from[ error.position() ] - prefix_size,
5118  prefix_size );
5119  dest.append( "\" >>> " );
5120  }
5121 
5122  const char problematic_symbol = error.position() < from.size() ?
5123  from[ error.position() ] : '?';
5124  dest.append( 1u, '\'' );
5125  if( problematic_symbol >= '\x00' && problematic_symbol < ' ' )
5126  {
5127  constexpr char hex_digits[] = "0123456789abcdef";
5128 
5129  dest.append( "\\x" );
5130  dest.append( 1u, hex_digits[
5131  static_cast<unsigned char>(problematic_symbol) >> 4 ] );
5132  dest.append( 1u, hex_digits[
5133  static_cast<unsigned char>(problematic_symbol) & 0xfu ] );
5134  }
5135  else
5136  dest.append( 1u, problematic_symbol );
5137 
5138  dest.append( 1u, '\'' );
5139 
5140  if( error.position() + 1u < from.size() )
5141  {
5142  // How many chars we can get from the right of error position?
5143  const auto suffix_size =
5144  error.position() + 1u + max_quote_size < from.size() ?
5145  max_quote_size : from.size() - error.position() - 1u;
5146 
5147  dest.append( " <<< \"" );
5148  dest.append( &from[ error.position() + 1u ], suffix_size );
5149  dest.append( 1u, '"' );
5150  }
5151  };
5152 
5153  std::string result;
5154 
5155  const auto basic_reaction = [&](const char * msg) {
5156  result += msg;
5157  result += " at ";
5158  result += std::to_string( error.position() );
5159  result += ": ";
5160  append_quote( result );
5161  };
5162 
5163  switch( error.reason() )
5164  {
5165  case error_reason_t::unexpected_character:
5166  basic_reaction( "unexpected character" );
5167  break;
5168 
5169  case error_reason_t::unexpected_eof:
5170  result += "unexpected EOF at ";
5171  result += std::to_string( error.position() );
5172  break;
5173 
5174  case error_reason_t::no_appropriate_alternative:
5175  basic_reaction( "appropriate alternative can't found" );
5176  break;
5177 
5178  case error_reason_t::pattern_not_found:
5179  basic_reaction( "expected pattern is not found" );
5180  break;
5181 
5182  case error_reason_t::unconsumed_input:
5183  basic_reaction( "unconsumed input found" );
5184  break;
5185 
5186  case error_reason_t::illegal_value_found:
5187  basic_reaction( "some illegal value found" );
5188  break;
5189 
5191  basic_reaction( "forced selection alternative failed" );
5192  break;
5193  }
5194 
5195  return result;
5196 }
5197 
5198 } /* namespace easy_parser */
5199 
5200 } /* namespace restinio */
5201 
restinio::easy_parser::digits_to_consume_t::digits_to_consume_t
constexpr digits_to_consume_t(underlying_int_t total) noexcept
Definition: easy_parser.hpp:487
restinio::easy_parser::impl::to_lower_transformer_proxy_t
A proxy for the creation of an appropriate to_lower_transformer.
Definition: easy_parser.hpp:3125
restinio::easy_parser::digits_to_consume_t::underlying_int_t
std::int_fast8_t underlying_int_t
Definition: easy_parser.hpp:469
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::easy_parser::impl::custom_consumer_t::consume
void consume(Target_Type &dest, Value &&src) const noexcept(noexcept(m_consumer(dest, std::forward< Value >(src))))
Definition: easy_parser.hpp:2948
restinio::utils::metaprogramming::type_list
The basic building block: a type for representation of a type list.
Definition: metaprogramming.hpp:54
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::result_type
std::map< K, V, Args... > result_type
Definition: easy_parser.hpp:402
restinio::easy_parser::impl::custom_consumer_t
A template for consumers that are released by lambda/functional objects.
Definition: easy_parser.hpp:2940
restinio::easy_parser::result_value_wrapper< nothing_t >::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:444
restinio::easy_parser::parse_error_t::position
RESTINIO_NODISCARD std::size_t position() const noexcept
Get the position in the input stream where error was detected.
Definition: easy_parser.hpp:111
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
restinio::easy_parser::impl::source_t::current_position
RESTINIO_NODISCARD position_t current_position() const noexcept
Get the current position in the stream.
Definition: easy_parser.hpp:786
restinio::easy_parser::impl::to_lower_transformer_t< std::string >::transform
RESTINIO_NODISCARD result_type transform(input_type &&input) const noexcept
Definition: easy_parser.hpp:3057
restinio::easy_parser::impl::maybe_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1718
restinio::easy_parser::error_reason_t::unexpected_character
@ unexpected_character
Unexpected character is found in the input.
restinio::easy_parser::impl::convert_transformer_t::m_converter
Converter m_converter
Definition: easy_parser.hpp:3175
restinio::easy_parser::impl::particular_symbol_predicate_t::m_expected
char m_expected
Definition: easy_parser.hpp:2199
restinio::utils::metaprogramming::rename_t
typename impl::rename< From, To >::type rename_t
Allows to pass all template arguments from one type to another.
Definition: metaprogramming.hpp:203
restinio::easy_parser::impl::std_array_wrapper::m_array
std::array< T, S > m_array
Definition: easy_parser.hpp:300
restinio::easy_parser::impl::conversion_result_type_detector::type
Result_Type type
Definition: easy_parser.hpp:3227
restinio::easy_parser::symbol
RESTINIO_NODISCARD auto symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
Definition: easy_parser.hpp:4032
restinio::easy_parser::impl::caseless_particular_symbol_predicate_t::caseless_particular_symbol_predicate_t
caseless_particular_symbol_predicate_t(char v) noexcept
Definition: easy_parser.hpp:2243
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::as_result
static void as_result(wrapped_type &to, result_type &&what)
Definition: easy_parser.hpp:410
restinio::easy_parser::impl::alternatives_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
Definition: easy_parser.hpp:1648
restinio::easy_parser::produce
RESTINIO_NODISCARD auto produce(Clauses &&... clauses)
A factory function to create a producer that creates an instance of the target type by using specifie...
Definition: easy_parser.hpp:3554
restinio::easy_parser::impl::is_digit_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:686
restinio::easy_parser::impl::is_digit_predicate_t
A predicate for cases where char to be expected to be a decimal digit.
Definition: easy_parser.hpp:683
restinio::easy_parser::impl::forced_alternative_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
Definition: easy_parser.hpp:1971
restinio::easy_parser::impl::symbol_producer_template_t
A template for producer of charachers that satisfy some predicate.
Definition: easy_parser.hpp:2133
restinio::easy_parser::result_value_wrapper::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:192
restinio::easy_parser::digits_to_consume_t
Limits for number of digits to be extracted during parsing of decimal numbers.
Definition: easy_parser.hpp:467
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::value_type
std::pair< K, V > value_type
Definition: easy_parser.hpp:406
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t(const content_consumer_t &)=delete
restinio::easy_parser::impl::convert_transformer_proxy_t::output
conversion_result_type_detector_t< std::decay_t< decltype(std::declval< Converter & >()(std::declval< Input_Type && >())) > > output
Definition: easy_parser.hpp:3269
restinio::easy_parser::impl::particular_symbol_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2203
restinio::impl::to_lower_case
RESTINIO_NODISCARD char to_lower_case(char ch)
Definition: to_lower_lut.hpp:39
restinio::easy_parser::impl::character_t
One character extracted from the input stream.
Definition: easy_parser.hpp:593
restinio::easy_parser::impl::to_lower_transformer_t< char >::input_type
char input_type
Definition: easy_parser.hpp:3079
restinio::easy_parser::impl::operator==
RESTINIO_NODISCARD bool operator==(const character_t &a, const character_t &b) noexcept
Definition: easy_parser.hpp:600
restinio::easy_parser::digits_to_consume_t::from_one_to_max
constexpr static RESTINIO_NODISCARD auto from_one_to_max() noexcept
Definition: easy_parser.hpp:527
restinio::easy_parser::impl::clause_tag
A special base class to be used with clauses.
Definition: easy_parser.hpp:1393
restinio::easy_parser::impl::try_parse_hexdigits_with_digits_limit
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse_hexdigits_with_digits_limit(source_t &from, digits_to_consume_t digits_limit, Value_Accumulator acc) noexcept
Helper function for parsing integers in hexadecimal form.
Definition: easy_parser.hpp:2501
restinio::easy_parser::impl::transformer_tag< char >::result_type
char result_type
Definition: easy_parser.hpp:1000
restinio::easy_parser::result_value_wrapper
A template with specializations for different kind of result values and for type nothing.
Definition: easy_parser.hpp:180
restinio::easy_parser::impl::hexadecimal_number_producer_with_digits_limit_t
A producer for the case when a number in hexadecimal form is expected in the input stream.
Definition: easy_parser.hpp:2665
restinio::utils::metaprogramming::transform_t
typename impl::transform< Transform_F, From, type_list<> >::type transform_t
Applies a specified meta-function to every item from a specified type-list and return a new type-list...
Definition: metaprogramming.hpp:263
restinio::easy_parser::impl::source_t::source_t
source_t(string_view_t data) noexcept
Initializing constructor.
Definition: easy_parser.hpp:756
restinio::easy_parser::digit
RESTINIO_NODISCARD auto digit() noexcept
A factory function to create a clause that expects a decimal digit, extracts it and then skips it.
Definition: easy_parser.hpp:4154
restinio::easy_parser::impl::not_particular_symbol_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2224
string_view.hpp
restinio::easy_parser::impl::any_symbol_predicate_t::operator()
constexpr RESTINIO_NODISCARD bool operator()(const char) const noexcept
Definition: easy_parser.hpp:2182
restinio::easy_parser::impl::consume_value_clause_t::consume_value_clause_t
consume_value_clause_t(P &&producer, C &&consumer)
Definition: easy_parser.hpp:1482
restinio::easy_parser::impl::producer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:947
restinio::easy_parser::impl::is_producer_v
constexpr bool is_producer_v
A meta-value to check whether T is a producer type.
Definition: easy_parser.hpp:970
restinio::easy_parser::impl::symbol_producer_t::symbol_producer_t
symbol_producer_t(char expected)
Definition: easy_parser.hpp:2297
restinio::easy_parser::impl::caseless_exact_fragment_producer_t::m_fragment
std::string m_fragment
Definition: easy_parser.hpp:3506
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:257
restinio::easy_parser::impl::decimal_number_producer_t::try_parse
RESTINIO_NODISCARD try_parse_result_type try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2707
restinio::easy_parser::N
constexpr std::size_t N
A special marker that means infinite repetitions.
Definition: easy_parser.hpp:455
restinio::easy_parser::caseless_symbol
RESTINIO_NODISCARD auto caseless_symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
Definition: easy_parser.hpp:4055
restinio::easy_parser::impl::to_lower_transformer_t< std::array< char, S > >::input_type
std::array< char, S > input_type
Definition: easy_parser.hpp:3099
restinio::easy_parser::impl::to_lower_transformer_t< char >::transform
RESTINIO_NODISCARD result_type transform(input_type &&input) const noexcept
Definition: easy_parser.hpp:3083
restinio::easy_parser::impl::field_setter_consumer_t::pointer_t
F C::* pointer_t
Definition: easy_parser.hpp:2970
restinio::easy_parser::result_value_wrapper::result_type
T result_type
Definition: easy_parser.hpp:181
restinio::easy_parser::impl::any_value_skipper_t
A special consumer that simply throws any value away.
Definition: easy_parser.hpp:2843
restinio::easy_parser::impl::transformer_invoker
A helper template for calling transformation function.
Definition: easy_parser.hpp:1048
restinio::easy_parser::impl::convert_transformer_proxy_t
A proxy for the creation of convert_transformer instances for a specific value producers.
Definition: easy_parser.hpp:3263
restinio::easy_parser::parse_error_t::m_reason
error_reason_t m_reason
The reason of the error.
Definition: easy_parser.hpp:97
restinio::easy_parser::impl::just_value_transformer_t::just_value_transformer_t
just_value_transformer_t(T v) noexcept(noexcept(T{std::move(v)}))
Definition: easy_parser.hpp:3150
restinio::easy_parser::not_clause
RESTINIO_NODISCARD auto not_clause(Clauses &&... clauses)
A factory function to create a not_clause.
Definition: easy_parser.hpp:3676
restinio::easy_parser::digit_p
RESTINIO_NODISCARD auto digit_p() noexcept
A factory function to create a digit_producer.
Definition: easy_parser.hpp:4133
restinio::easy_parser::impl::source_t::getch
RESTINIO_NODISCARD character_t getch() noexcept
Get the next character from the input stream.
Definition: easy_parser.hpp:765
restinio::easy_parser::impl::transformer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1001
restinio::easy_parser::parse_error_t
Information about parsing error.
Definition: easy_parser.hpp:93
to_lower_lut.hpp
restinio::easy_parser::impl::hexdigit_producer_t
A producer for the case when a hexadecimal digit is expected in the input stream.
Definition: easy_parser.hpp:2405
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::to_container
static void to_container(wrapped_type &to, value_type &&what)
Definition: easy_parser.hpp:266
restinio::easy_parser::result_value_wrapper< std::array< T, S > >::to_container
static void to_container(wrapped_type &to, value_type &&what)
Definition: easy_parser.hpp:321
restinio::easy_parser::just
RESTINIO_NODISCARD auto just(T value) noexcept(noexcept(impl::just_value_transformer_t< T >{value}))
A special transformer that replaces the produced value by a value specified by a user.
Definition: easy_parser.hpp:4635
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:273
restinio::easy_parser::digits_to_consume_t::m_max
underlying_int_t m_max
Maximal number of digits to consume.
Definition: easy_parser.hpp:479
restinio::easy_parser::impl::and_clause_t
A template for implementation of clause that checks the presence of some entity in the input stream.
Definition: easy_parser.hpp:1848
restinio::easy_parser::impl::caseless_symbol_producer_t
A producer for the case when a particual character is expected in the input stream.
Definition: easy_parser.hpp:2341
restinio::easy_parser::impl::source_t::content_consumer_t::m_started_at
const position_t m_started_at
Definition: easy_parser.hpp:853
restinio::easy_parser::impl::alternatives_clause_t
A template for implementation of clause that selects one of alternative clauses.
Definition: easy_parser.hpp:1636
restinio::easy_parser::impl::consume_value_clause_t::m_producer
P m_producer
Definition: easy_parser.hpp:1475
restinio::easy_parser::hexdigit
RESTINIO_NODISCARD auto hexdigit() noexcept
A factory function to create a clause that expects a hexadecimal digit, extracts it and then skips it...
Definition: easy_parser.hpp:4193
restinio::easy_parser::impl::sequence_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1910
overflow_controlled_integer_accumulator.hpp
Helper for parsing integer values.
restinio::easy_parser::symbol_from_range
RESTINIO_NODISCARD auto symbol_from_range(char left, char right) noexcept
A factory function to create a clause that expects a symbol from specified range, extracts it and the...
Definition: easy_parser.hpp:4076
restinio::string_view_t
nonstd::string_view string_view_t
Definition: string_view.hpp:19
restinio::easy_parser::impl::is_consumer_v
constexpr bool is_consumer_v
A meta-value to check whether T is a consumer type.
Definition: easy_parser.hpp:1367
restinio::easy_parser::impl::exact_fixed_size_fragment_producer_t
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
Definition: easy_parser.hpp:3356
restinio::easy_parser::impl::is_clause
Definition: easy_parser.hpp:1398
restinio::easy_parser::impl::not_clause_t
A template for implementation of clause that checks absence of some entity in the input stream.
Definition: easy_parser.hpp:1780
restinio::easy_parser::impl::not_particular_symbol_predicate_t::m_sentinel
char m_sentinel
Definition: easy_parser.hpp:2220
restinio::easy_parser::impl::std_array_wrapper
A special wrapper for std::array type to be used inside a producer during the parsing.
Definition: easy_parser.hpp:299
restinio::easy_parser::result_value_wrapper< std::array< T, S > >
Definition: easy_parser.hpp:308
restinio::easy_parser::impl::symbol_from_range_predicate_t::m_left
char m_left
Definition: easy_parser.hpp:2268
restinio::easy_parser::impl::non_negative_decimal_number_producer_with_digits_limit_t
A producer for the case when a non-negative decimal number is expected in the input stream.
Definition: easy_parser.hpp:2600
restinio::easy_parser::any_symbol_p
RESTINIO_NODISCARD auto any_symbol_p() noexcept
A factory function to create an any_symbol_producer.
Definition: easy_parser.hpp:3937
restinio::easy_parser::impl::source_t::content_consumer_t::commit
void commit() noexcept
Consume all acquired content.
Definition: easy_parser.hpp:885
restinio::easy_parser::digits_to_consume_t::digits_to_consume_t
constexpr digits_to_consume_t(underlying_int_t min, underlying_int_t max) noexcept
Definition: easy_parser.hpp:497
restinio::easy_parser::impl::sequence_clause_t
A template for implementation of clause that checks and handles presence of sequence of entities in t...
Definition: easy_parser.hpp:1909
restinio::easy_parser::impl::hexdigit_producer_t::hexdigit_producer_t
hexdigit_producer_t()
Definition: easy_parser.hpp:2407
restinio::utils::metaprogramming
Definition: metaprogramming.hpp:24
restinio::easy_parser::result_value_wrapper< std::array< T, S > >::value_type
typename result_type::value_type value_type
Definition: easy_parser.hpp:310
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::result_type
std::vector< T, Args... > result_type
Definition: easy_parser.hpp:255
restinio::easy_parser::impl::is_hexdigit_predicate_t
A predicate for cases where char to be expected to be a hexadecimal digit.
Definition: easy_parser.hpp:719
restinio::easy_parser::impl::convert_transformer_t::transform
RESTINIO_NODISCARD auto transform(Input &&input) const noexcept(noexcept(m_converter(std::forward< Input >(input))))
Performs the transformation by calling the converter.
Definition: easy_parser.hpp:3195
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:393
restinio::easy_parser::impl::any_symbol_if_not_producer_t
A producer for the case when any character except the specific sentinel character is expected in the ...
Definition: easy_parser.hpp:2315
restinio::easy_parser::impl::consume_value_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
Definition: easy_parser.hpp:1490
restinio::easy_parser::parse_error_t::reason
RESTINIO_NODISCARD error_reason_t reason() const noexcept
Get the reason of the error.
Definition: easy_parser.hpp:116
restinio::easy_parser::impl::transformed_value_producer_traits_checker::producer_result_t
std::decay_t< decltype(std::declval< Producer & >().try_parse(std::declval< source_t & >())) > producer_result_t
Definition: easy_parser.hpp:1153
restinio::easy_parser::impl::repeat_clause_t::m_max_occurences
std::size_t m_max_occurences
Definition: easy_parser.hpp:2063
restinio::easy_parser::impl::is_clause< T, meta::void_t< decltype(std::decay_t< T >::entity_type) > >::real_type
std::decay_t< T > real_type
Definition: easy_parser.hpp:1404
restinio::easy_parser::impl::caseless_exact_fragment_producer_t::try_parse
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
Definition: easy_parser.hpp:3523
restinio::easy_parser::impl::try_parse_digits_with_digits_limit
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse_digits_with_digits_limit(source_t &from, digits_to_consume_t digits_limit, Value_Accumulator acc) noexcept
Helper function for parsing integers with respect to the number of digits to be consumed.
Definition: easy_parser.hpp:2437
restinio::easy_parser::make_error_description
RESTINIO_NODISCARD std::string make_error_description(const parse_error_t &error, string_view_t from)
Make textual description of error returned by try_parse function.
Definition: easy_parser.hpp:5103
restinio::easy_parser::impl::symbol_from_range_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2273
restinio::easy_parser::impl::decimal_number_producer_t::try_parse_with_this_first_symbol
static RESTINIO_NODISCARD try_parse_result_type try_parse_with_this_first_symbol(source_t &from, char first_symbol, Digits_Limit_Maker &&digits_limit_maker) noexcept
Definition: easy_parser.hpp:2749
restinio::easy_parser::impl::symbol_from_range_producer_t::symbol_from_range_producer_t
symbol_from_range_producer_t(char left, char right)
Definition: easy_parser.hpp:2369
restinio::easy_parser::impl::transformed_value_producer_traits_checker::transformation_result_t
std::decay_t< decltype(std::declval< Transformer & >().transform(std::move(*(std::declval< producer_result_t >())))) > transformation_result_t
Definition: easy_parser.hpp:1158
restinio::easy_parser::impl::maybe_clause_t
A template for implementation of clause that checks and handles presence of optional entity in the in...
Definition: easy_parser.hpp:1717
restinio::easy_parser::impl::as_result_consumer_t::consume
void consume(Target_Type &dest, Value &&src) const
Definition: easy_parser.hpp:2873
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t()=delete
restinio::easy_parser::symbol_from_range_p
RESTINIO_NODISCARD auto symbol_from_range_p(char left, char right) noexcept
A factory function to create a symbol_from_range_producer.
Definition: easy_parser.hpp:4011
restinio::easy_parser::result_value_wrapper::as_result
static void as_result(wrapped_type &to, result_type &&what)
Definition: easy_parser.hpp:185
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::to_container
static void to_container(wrapped_type &to, wrapped_type &&what)
Special overload for the case when std::string should be added to another std::string.
Definition: easy_parser.hpp:386
restinio::easy_parser::impl::custom_consumer_t::custom_consumer_t
custom_consumer_t(C &&consumer)
Definition: easy_parser.hpp:2944
restinio::easy_parser::impl::repeat_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:2065
restinio::easy_parser::impl::transformer_invoker::invoke
static RESTINIO_NODISCARD Result_Type invoke(source_t &, Transformer &transformer, expected_t< Input_Type, parse_error_t > &&input)
Definition: easy_parser.hpp:1052
restinio::easy_parser::any_symbol_if_not_p
RESTINIO_NODISCARD auto any_symbol_if_not_p(char sentinel) noexcept
A factory function to create a any_symbol_if_not_producer.
Definition: easy_parser.hpp:3973
restinio::easy_parser::impl::to_lower_transformer_t< std::array< char, S > >::transform
RESTINIO_NODISCARD base_type::result_type transform(input_type &&input) const noexcept
Definition: easy_parser.hpp:3104
restinio::easy_parser::impl::just_result_consumer_t::make_copy_of_result
Result_Type make_copy_of_result() const noexcept(noexcept(Result_Type{m_result}))
Definition: easy_parser.hpp:2902
restinio::easy_parser::impl::decimal_number_producer_t::try_parse_result_type
expected_t< T, parse_error_t > try_parse_result_type
Definition: easy_parser.hpp:2703
restinio::easy_parser::impl::is_digit
constexpr RESTINIO_NODISCARD bool is_digit(const char ch) noexcept
Is a character a decimal digit?
Definition: easy_parser.hpp:669
restinio::easy_parser::impl::maybe_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
Definition: easy_parser.hpp:1729
restinio::easy_parser::impl::std_array_wrapper::m_index
std::size_t m_index
Definition: easy_parser.hpp:301
restinio::easy_parser::force_only_this_alternative
RESTINIO_NODISCARD auto force_only_this_alternative(Clauses &&... clauses)
An alternative that should be parsed correctly or the parsing of the whole alternatives clause should...
Definition: easy_parser.hpp:3821
restinio::easy_parser::result_value_wrapper::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:182
restinio::easy_parser::impl::caseless_particular_symbol_predicate_t
A predicate for cases where the case-insensitive match of expected and actual symbols is required.
Definition: easy_parser.hpp:2240
restinio::easy_parser::impl::is_space_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:653
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t(source_t &from) noexcept
Definition: easy_parser.hpp:861
restinio::easy_parser::impl::top_level_clause_t::m_producer
Producer m_producer
Definition: easy_parser.hpp:1535
restinio::easy_parser::impl::source_t::m_data
const string_view_t m_data
The content to be used as "input stream".
Definition: easy_parser.hpp:742
restinio::easy_parser::impl::character_t::m_ch
char m_ch
Definition: easy_parser.hpp:595
restinio::easy_parser::as_result
RESTINIO_NODISCARD auto as_result() noexcept
A factory function to create a as_result_consumer.
Definition: easy_parser.hpp:4470
restinio::easy_parser::digits_to_consume_t::max
constexpr RESTINIO_NODISCARD auto max() const noexcept
Get the maximum value.
Definition: easy_parser.hpp:512
restinio::easy_parser::impl::consumer_tag
A special base class to be used with consumers.
Definition: easy_parser.hpp:1343
restinio::easy_parser::impl::symbol_from_range_producer_t
A producer for the case when a symbol should belong to specified range.
Definition: easy_parser.hpp:2364
restinio::easy_parser::impl::entity_type_t
entity_type_t
A marker for distinguish different kind of entities in parser.
Definition: easy_parser.hpp:901
restinio::easy_parser::impl::to_container_consumer_t
A template for a consumer that stories values into a container.
Definition: easy_parser.hpp:4541
restinio::easy_parser::symbol_p
RESTINIO_NODISCARD auto symbol_p(char expected) noexcept
A factory function to create a symbol_producer.
Definition: easy_parser.hpp:3955
restinio::easy_parser::impl::sequence_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
Definition: easy_parser.hpp:1921
restinio::easy_parser::space_p
RESTINIO_NODISCARD auto space_p() noexcept
A factory function to create a space_producer.
Definition: easy_parser.hpp:4094
restinio::transforms::zlib::transform
std::string transform(string_view_t input, const params_t &params)
Do a specified zlib transformation.
Definition: zlib.hpp:878
restinio::easy_parser::impl::field_setter_consumer_t::m_ptr
pointer_t m_ptr
Definition: easy_parser.hpp:2972
restinio::easy_parser::impl::as_result_consumer_t
A consumer for the case when the current value should be returned as the result for the producer at o...
Definition: easy_parser.hpp:2870
restinio::easy_parser::result_wrapper_for
A metafunction for detection of actual result_value_wrapper type for T.
Definition: easy_parser.hpp:245
restinio::easy_parser::impl::transformer_tag
A special base class to be used with transformers.
Definition: easy_parser.hpp:999
restinio::easy_parser::positive_decimal_number_producer
RESTINIO_NODISCARD auto positive_decimal_number_producer() noexcept
A factory function to create a producer for non-negative decimal numbers.
Definition: easy_parser.hpp:4279
restinio::utils::tuple_algorithms::all_of
RESTINIO_NODISCARD bool all_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:103
restinio::easy_parser::impl::symbol_producer_t
A producer for the case when a particual character is expected in the input stream.
Definition: easy_parser.hpp:2292
restinio::easy_parser::impl::caseless_particular_symbol_predicate_t::m_expected
char m_expected
Definition: easy_parser.hpp:2241
restinio::easy_parser::impl::entity_type_t::producer
@ producer
Entity is a producer of values.
restinio::easy_parser::impl::produce_t::try_parse
RESTINIO_NODISCARD expected_t< Target_Type, parse_error_t > try_parse(source_t &from)
Definition: easy_parser.hpp:2023
restinio::easy_parser::impl::produce_t
A template for producing a value of specific type of a sequence of entities from the input stream.
Definition: easy_parser.hpp:2010
restinio::easy_parser::impl::consume_value_clause_t::m_consumer
C m_consumer
Definition: easy_parser.hpp:1479
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::as_result
static void as_result(wrapped_type &to, result_type &&what)
Definition: easy_parser.hpp:260
restinio::easy_parser::impl::custom_consumer_t::m_consumer
C m_consumer
Definition: easy_parser.hpp:2941
restinio::easy_parser::caseless_exact_p
RESTINIO_NODISCARD auto caseless_exact_p(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment_producer.
Definition: easy_parser.hpp:4897
restinio::easy_parser::impl::operator>>
RESTINIO_NODISCARD std::enable_if_t< is_producer_v< P > &is_transformer_v< T >, transformed_value_producer_t< P, T > > operator>>(P producer, T transformer)
A special operator to connect a value producer with value transformer.
Definition: easy_parser.hpp:1233
restinio::easy_parser::impl::non_negative_decimal_number_producer_t
A producer for the case when a non-negative decimal number is expected in the input stream.
Definition: easy_parser.hpp:2571
restinio::easy_parser::impl::alternatives_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1637
restinio::easy_parser::impl::is_transformer_v
constexpr bool is_transformer_v
A meta-value to check whether T is a transformer type.
Definition: easy_parser.hpp:1024
restinio::easy_parser::try_parse
RESTINIO_NODISCARD expected_t< typename Producer::result_type, parse_error_t > try_parse(string_view_t from, Producer producer)
Perform the parsing of the specified content by using specified value producer.
Definition: easy_parser.hpp:5042
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::to_container
static void to_container(wrapped_type &to, value_type &&what)
Definition: easy_parser.hpp:416
restinio::easy_parser::impl::to_lower_transformer_t
Definition: easy_parser.hpp:3041
restinio::easy_parser::impl::forced_alternative_clause_t
An alternative that should be parsed correctly or the parsing of the whole alternatives clause should...
Definition: easy_parser.hpp:1962
restinio::easy_parser::impl::transformer_proxy_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1268
restinio::easy_parser::impl::caseless_particular_symbol_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2249
restinio::easy_parser::impl::source_t::content_consumer_t::started_at
position_t started_at() const noexcept
Definition: easy_parser.hpp:873
restinio::easy_parser::result_value_wrapper< std::vector< T, Args... > >::value_type
typename result_type::value_type value_type
Definition: easy_parser.hpp:256
restinio::easy_parser::impl::SP
constexpr char SP
A constant for SPACE value.
Definition: easy_parser.hpp:617
restinio::easy_parser::impl::is_producer
Definition: easy_parser.hpp:951
nonstd::optional_lite::optional
class optional
Definition: optional.hpp:839
restinio::easy_parser::impl::source_t::m_index
string_view_t::size_type m_index
The current position in the input stream.
Definition: easy_parser.hpp:749
restinio::easy_parser::impl::caseless_symbol_producer_t::caseless_symbol_producer_t
caseless_symbol_producer_t(char expected)
Definition: easy_parser.hpp:2346
restinio::easy_parser::impl::just_result_consumer_t::m_result
Result_Type m_result
Definition: easy_parser.hpp:2893
restinio::easy_parser::impl::exact_fixed_size_fragment_producer_t::try_parse
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
Definition: easy_parser.hpp:3371
restinio::easy_parser::non_negative_decimal_number_p
RESTINIO_NODISCARD auto non_negative_decimal_number_p() noexcept
A factory function to create a non_negative_decimal_number_producer.
Definition: easy_parser.hpp:4218
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::to_container
static void to_container(wrapped_type &to, value_type &&what)
Definition: easy_parser.hpp:367
restinio::easy_parser::impl::is_clause_v
constexpr bool is_clause_v
A meta-value to check whether T is a consumer type.
Definition: easy_parser.hpp:1420
restinio::easy_parser::impl::to_lower_transformer_proxy_t::make_transformer
RESTINIO_NODISCARD auto make_transformer() const noexcept
Definition: easy_parser.hpp:3129
restinio::easy_parser::impl::is_space
constexpr RESTINIO_NODISCARD bool is_space(const char ch) noexcept
If a character a space character?
Definition: easy_parser.hpp:635
restinio::easy_parser::impl::and_clause_t::and_clause_t
and_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1852
restinio::easy_parser::impl::ensure_no_remaining_content
RESTINIO_NODISCARD optional_t< parse_error_t > ensure_no_remaining_content(source_t &from)
A special function to check that there is no more actual data in the input stream except whitespaces.
Definition: easy_parser.hpp:1566
restinio::easy_parser::impl::symbol_from_range_predicate_t
A predicate for cases where a symbol should belong to specified range.
Definition: easy_parser.hpp:2267
restinio::easy_parser::impl::source_t::content_consumer_t
A helper class to automatically return acquired content back to the input stream.
Definition: easy_parser.hpp:851
restinio::easy_parser::impl::transformed_value_producer_traits_checker::is_valid_transformation_result_type
static constexpr bool is_valid_transformation_result_type
Definition: easy_parser.hpp:1162
restinio::easy_parser::impl::hexadecimal_number_producer_with_digits_limit_t::try_parse
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2676
restinio::utils::metaprogramming::void_t
typename make_void< Ts... >::type void_t
Definition: metaprogramming.hpp:28
nonstd::optional_lite::nullopt
const nullopt_t nullopt((nullopt_t::init()))
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:358
restinio::expected_t
nonstd::expected< T, E > expected_t
Definition: expected.hpp:22
restinio::easy_parser::impl::non_negative_decimal_number_producer_with_digits_limit_t::try_parse
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2611
restinio::easy_parser::impl::to_lower_transformer_t< std::string >::input_type
std::string input_type
Definition: easy_parser.hpp:3053
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::result_type
std::basic_string< Char, Args... > result_type
Definition: easy_parser.hpp:356
restinio::impl::check_negative_extremum
Definition: overflow_controlled_integer_accumulator.hpp:33
restinio::easy_parser::impl::decimal_number_producer_with_digits_limit_t
A producer for the case when a signed decimal number is expected in the input stream.
Definition: easy_parser.hpp:2812
tuple_algorithms.hpp
Various meta-functions for operating the content of a tuple.
restinio::easy_parser::impl::digit_producer_t::digit_producer_t
digit_producer_t()
Definition: easy_parser.hpp:2389
restinio::easy_parser::impl::transformed_value_producer_t::m_producer
Producer m_producer
Definition: easy_parser.hpp:1188
restinio::easy_parser::hexdigit_p
RESTINIO_NODISCARD auto hexdigit_p() noexcept
A factory function to create a hexdigit_producer.
Definition: easy_parser.hpp:4172
restinio::easy_parser::impl::exact_fixed_size_fragment_producer_t::m_fragment
std::array< char, Size-1u > m_fragment
Definition: easy_parser.hpp:3357
restinio::easy_parser::impl::transformer_invoker< expected_t< Result_Type, error_reason_t > >::invoke
static RESTINIO_NODISCARD expected_t< Result_Type, parse_error_t > invoke(source_t &source, Transformer &transformer, expected_t< Input_Type, parse_error_t > &&input)
Definition: easy_parser.hpp:1073
restinio::easy_parser::impl::convert_transformer_t
A transformator that uses a user supplied function/functor for conversion a value from one type to an...
Definition: easy_parser.hpp:3174
restinio::easy_parser::impl::top_level_clause_t::top_level_clause_t
top_level_clause_t(Producer &&producer)
Definition: easy_parser.hpp:1540
restinio::easy_parser::impl::conversion_result_type_detector_t
typename conversion_result_type_detector< Result_Type >::type conversion_result_type_detector_t
Definition: easy_parser.hpp:3243
restinio::easy_parser::impl::source_t::position_t
string_view_t::size_type position_t
Type to be used as the index inside the input stream.
Definition: easy_parser.hpp:753
restinio::easy_parser::impl::producer_tag
A special base class to be used with producers.
Definition: easy_parser.hpp:945
restinio::easy_parser::impl::source_t::fragment
RESTINIO_NODISCARD string_view_t fragment(string_view_t::size_type from, string_view_t::size_type length=string_view_t::npos) const noexcept
Return a fragment from the input stream.
Definition: easy_parser.hpp:816
restinio::easy_parser::impl::source_t::backto
void backto(position_t pos) noexcept
Return the current position in the input stream at the specified position.
Definition: easy_parser.hpp:794
restinio::easy_parser::to_container
RESTINIO_NODISCARD auto to_container()
A factory function to create a to_container_consumer.
Definition: easy_parser.hpp:4583
restinio::easy_parser::impl::hexadecimal_number_producer_t
A producer for the case when a number in hexadecimal form is expected in the input stream.
Definition: easy_parser.hpp:2633
restinio::easy_parser::impl::caseless_exact_fixed_size_fragment_producer_t::caseless_exact_fixed_size_fragment_producer_t
caseless_exact_fixed_size_fragment_producer_t(const char(&f)[Size])
Definition: easy_parser.hpp:3471
restinio::easy_parser::impl::any_value_skipper_t::consume
void consume(Target_Type &, Value &&) const noexcept
Definition: easy_parser.hpp:2846
restinio::easy_parser::impl::caseless_exact_fixed_size_fragment_producer_t
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
Definition: easy_parser.hpp:3464
restinio::easy_parser::impl::convert_transformer_proxy_t::convert_transformer_proxy_t
convert_transformer_proxy_t(Convert_Arg &&converter) noexcept(noexcept(Converter{std::forward< Convert_Arg >(converter)}))
Definition: easy_parser.hpp:3275
restinio::easy_parser::impl::operator!=
RESTINIO_NODISCARD bool operator!=(const character_t &a, const character_t &b) noexcept
Definition: easy_parser.hpp:607
restinio::easy_parser::impl::source_t::content_consumer_t::m_consumed
bool m_consumed
Definition: easy_parser.hpp:854
restinio::easy_parser::impl::character_t::m_eof
bool m_eof
Definition: easy_parser.hpp:594
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:407
restinio::easy_parser::impl::convert_transformer_t::convert_transformer_t
convert_transformer_t(Convert_Arg &&converter) noexcept(noexcept(Converter{std::forward< Convert_Arg >(converter)}))
Definition: easy_parser.hpp:3179
restinio::easy_parser::exact
RESTINIO_NODISCARD auto exact(string_view_t fragment)
A factory function that creates an instance of exact_fragment clause.
Definition: easy_parser.hpp:4833
restinio::easy_parser::impl::symbol_producer_template_t::symbol_producer_template_t
symbol_producer_template_t(Args &&... args)
Definition: easy_parser.hpp:2136
restinio::easy_parser::impl::field_setter_consumer_t::consume
void consume(C &to, F &&value) const noexcept(noexcept(to.*m_ptr=std::move(value)))
Definition: easy_parser.hpp:2984
restinio::easy_parser::impl::try_parse_exact_fragment
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse_exact_fragment(source_t &from, It begin, It end)
Definition: easy_parser.hpp:3313
restinio::easy_parser::digits_to_consume_t::min
constexpr RESTINIO_NODISCARD auto min() const noexcept
Get the minimal value.
Definition: easy_parser.hpp:507
restinio::easy_parser::impl::convert_transformer_proxy_t::make_transformer
RESTINIO_NODISCARD auto make_transformer() const &noexcept(noexcept(Converter{m_converter}))
Definition: easy_parser.hpp:3283
restinio
Definition: asio_include.hpp:21
restinio::easy_parser::impl::caseless_exact_fragment_producer_t
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
Definition: easy_parser.hpp:3505
restinio::easy_parser::impl::convert_transformer_proxy_t::make_transformer
RESTINIO_NODISCARD auto make_transformer() &&noexcept(noexcept(Converter{std::move(m_converter)}))
Definition: easy_parser.hpp:3294
restinio::easy_parser::impl::source_t::content_consumer_t::~content_consumer_t
~content_consumer_t() noexcept
Definition: easy_parser.hpp:866
restinio::easy_parser::impl::repeat_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &dest)
Definition: easy_parser.hpp:2080
restinio::easy_parser::impl::is_hexdigit
constexpr RESTINIO_NODISCARD bool is_hexdigit(const char ch) noexcept
Is a character a hexadecimal digit?
Definition: easy_parser.hpp:702
restinio::easy_parser::result_value_wrapper< std::array< T, S > >::as_result
static void as_result(wrapped_type &to, result_type &&what)
Definition: easy_parser.hpp:314
restinio::easy_parser::impl::not_clause_t::not_clause_t
not_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1784
restinio::easy_parser::impl::exact_fragment_producer_t::m_fragment
std::string m_fragment
Definition: easy_parser.hpp:3390
restinio::easy_parser::impl::tuple_of_entities_t
meta::rename_t< meta::transform_t< std::decay, meta::type_list< Entities... > >, std::tuple > tuple_of_entities_t
A helper meta-function to create an actual type of tuple with clauses/producers.
Definition: easy_parser.hpp:1458
restinio::easy_parser::result_wrapper_for_t
typename result_wrapper_for< T >::type result_wrapper_for_t
Definition: easy_parser.hpp:250
restinio::easy_parser::digits_to_consume_t::unlimited_max
constexpr static RESTINIO_NODISCARD auto unlimited_max() noexcept
Get the value that means that maximum is not limited.
Definition: easy_parser.hpp:517
restinio::easy_parser::result_value_wrapper< std::map< K, V, Args... > >::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:423
restinio::easy_parser::space
RESTINIO_NODISCARD auto space() noexcept
A factory function to create a clause that expects a space, extracts it and then skips it.
Definition: easy_parser.hpp:4115
restinio::easy_parser::impl::is_transformer
Definition: easy_parser.hpp:1005
restinio::easy_parser::impl::transformed_value_producer_t
A template of producer that gets a value from another producer, transforms it and produces transforme...
Definition: easy_parser.hpp:1181
restinio::easy_parser::impl::top_level_clause_t
A special class to be used as the top level clause in parser.
Definition: easy_parser.hpp:1533
restinio::easy_parser::impl::just_result_consumer_t::consume
void consume(Target_Type &dest, Value &&) const
Definition: easy_parser.hpp:2917
restinio::easy_parser::convert
RESTINIO_NODISCARD auto convert(Converter &&converter)
A factory function to create convert_transformer.
Definition: easy_parser.hpp:4737
restinio::easy_parser::to_lower
RESTINIO_NODISCARD auto to_lower() noexcept
A factory function to create a to_lower_transformer.
Definition: easy_parser.hpp:4610
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::value_type
Char value_type
Definition: easy_parser.hpp:357
restinio::easy_parser::result_value_wrapper< std::basic_string< Char, Args... > >::as_result
static void as_result(wrapped_type &to, result_type &&what)
Definition: easy_parser.hpp:361
exception.hpp
restinio::easy_parser::impl::transformer_proxy_tag
A special base class to be used with transformer-proxies.
Definition: easy_parser.hpp:1267
restinio::easy_parser::impl::conversion_result_type_detector
A helper template for the detection of type to be produced as conversion procedure.
Definition: easy_parser.hpp:3226
restinio::easy_parser::impl::repeat_clause_t::m_min_occurences
std::size_t m_min_occurences
Definition: easy_parser.hpp:2062
restinio::easy_parser::impl::exact_fixed_size_fragment_producer_t::exact_fixed_size_fragment_producer_t
exact_fixed_size_fragment_producer_t(const char(&f)[Size])
Definition: easy_parser.hpp:3363
restinio::impl::overflow_controlled_integer_accumulator_t
Helper class for accumulating integer value during parsing it from string (with check for overflow).
Definition: overflow_controlled_integer_accumulator.hpp:136
restinio::easy_parser::impl::exact_fragment_producer_t::try_parse
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
Definition: easy_parser.hpp:3403
restinio::easy_parser::impl::transformed_value_producer_traits_checker::expected_result_t
typename Transformer::result_type expected_result_t
Definition: easy_parser.hpp:1160
restinio::easy_parser::parse_error_t::m_position
std::size_t m_position
Position in the input stream.
Definition: easy_parser.hpp:95
metaprogramming.hpp
Various tools for C++ metaprogramming.
restinio::easy_parser::result_value_wrapper< nothing_t >::to_container
static void to_container(wrapped_type &, value_type &&) noexcept
Definition: easy_parser.hpp:440
restinio::easy_parser::impl::produce_t::produce_t
produce_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:2016
restinio::easy_parser::impl::not_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1781
restinio::easy_parser::error_reason_t
error_reason_t
Reason of parsing error.
Definition: easy_parser.hpp:52
restinio::easy_parser::impl::consumer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1344
restinio::easy_parser::impl::convert_transformer_proxy_t::m_converter
Converter m_converter
Definition: easy_parser.hpp:3271
restinio::easy_parser::impl::source_t::content_consumer_t::m_from
source_t & m_from
Definition: easy_parser.hpp:852
restinio::easy_parser::impl::HTAB
constexpr char HTAB
A constant for Horizontal Tab value.
Definition: easy_parser.hpp:623
restinio::easy_parser::impl::consume_value_clause_t
A template for a clause that binds a value producer with value consumer.
Definition: easy_parser.hpp:1474
restinio::utils::tuple_algorithms::any_of
RESTINIO_NODISCARD bool any_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:117
restinio::easy_parser::impl::digit_producer_t
A producer for the case when a decimal digit is expected in the input stream.
Definition: easy_parser.hpp:2387
restinio::easy_parser::impl::hexadecimal_number_producer_with_digits_limit_t::m_digits_limit
digits_to_consume_t m_digits_limit
Definition: easy_parser.hpp:2666
restinio::easy_parser::alternatives
RESTINIO_NODISCARD auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
Definition: easy_parser.hpp:3595
compiler_features.hpp
Detection of compiler version and absence of various features.
restinio::easy_parser::exact_p
RESTINIO_NODISCARD auto exact_p(string_view_t fragment)
A factory function that creates an instance of exact_fragment_producer.
Definition: easy_parser.hpp:4768
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t(content_consumer_t &&)=delete
restinio::easy_parser::impl::caseless_exact_fixed_size_fragment_producer_t::m_fragment
std::array< char, Size-1u > m_fragment
Definition: easy_parser.hpp:3465
restinio::easy_parser::impl::to_container_consumer_t::consume
void consume(Container &to, Item &&item)
Definition: easy_parser.hpp:4544
restinio::easy_parser::impl::hexadecimal_number_producer_t::try_parse
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2640
restinio::easy_parser::hexadecimal_number_p
RESTINIO_NODISCARD auto hexadecimal_number_p() noexcept
A factory function to create a hexadecimal_number_producer.
Definition: easy_parser.hpp:4307
restinio::easy_parser::result_value_wrapper< std::array< T, S > >::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:335
restinio::easy_parser::impl::repeat_clause_t
A template for handling repetition of clauses.
Definition: easy_parser.hpp:2061
restinio::easy_parser::impl::tuple_item_consumer_t::consume
void consume(Target_Type &&to, Value &&value)
Definition: easy_parser.hpp:3030
restinio::easy_parser::impl::top_level_clause_t::try_process
RESTINIO_NODISCARD auto try_process(source_t &from)
Definition: easy_parser.hpp:1546
restinio::easy_parser::impl::is_transformer_proxy
Definition: easy_parser.hpp:1272
restinio::easy_parser::impl::field_setter_consumer_t::field_setter_consumer_t
field_setter_consumer_t(pointer_t ptr) noexcept
Definition: easy_parser.hpp:2975
restinio::easy_parser::impl::symbol_from_range_predicate_t::m_right
char m_right
Definition: easy_parser.hpp:2269
restinio::easy_parser::impl::not_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &)
Definition: easy_parser.hpp:1792
restinio::easy_parser::impl::maybe_clause_t::maybe_clause_t
maybe_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1721
expected.hpp
restinio::easy_parser::impl::hexadecimal_number_producer_with_digits_limit_t::hexadecimal_number_producer_with_digits_limit_t
hexadecimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
Definition: easy_parser.hpp:2669
restinio::easy_parser::impl::sequence_clause_t::sequence_clause_t
sequence_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1913
restinio::easy_parser::just_result
RESTINIO_NODISCARD auto just_result(T value) noexcept(noexcept(impl::just_result_consumer_t< T >{value}))
A special consumer that replaces the produced value by a value specified by a user and sets that user...
Definition: easy_parser.hpp:4664
restinio::easy_parser::impl::is_consumer
Definition: easy_parser.hpp:1348
restinio::easy_parser::impl::is_transformer_proxy_v
constexpr bool is_transformer_proxy_v
A meta-value to check whether T is a transformer-proxy type.
Definition: easy_parser.hpp:1290
restinio::easy_parser::impl::just_result_consumer_t::just_result_consumer_t
just_result_consumer_t(Result_Arg &&result) noexcept(noexcept(Result_Type{std::forward< Result_Arg >(result)}))
Definition: easy_parser.hpp:2910
restinio::easy_parser::parse_error_t::parse_error_t
parse_error_t(std::size_t position, error_reason_t reason) noexcept
Initializing constructor.
Definition: easy_parser.hpp:101
restinio::easy_parser::nothing_t
A special type to be used in the case where there is no need to store produced value.
Definition: easy_parser.hpp:128
restinio::easy_parser::impl::non_negative_decimal_number_producer_with_digits_limit_t::m_digits_limit
digits_to_consume_t m_digits_limit
Definition: easy_parser.hpp:2601
restinio::easy_parser::impl::clause_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1394
restinio::easy_parser::impl::source_t
The class that implements "input stream".
Definition: easy_parser.hpp:740
restinio::easy_parser::digits_to_consume_t::m_min
underlying_int_t m_min
Minimal number of digits to consume.
Definition: easy_parser.hpp:477
restinio::easy_parser::impl::caseless_exact_fixed_size_fragment_producer_t::try_parse
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
Definition: easy_parser.hpp:3485
restinio::easy_parser::impl::just_value_transformer_t::m_value
T m_value
Definition: easy_parser.hpp:3147
restinio::easy_parser::impl::caseless_exact_fragment_producer_t::caseless_exact_fragment_producer_t
caseless_exact_fragment_producer_t(std::string fragment)
Definition: easy_parser.hpp:3509
restinio::easy_parser::impl::transformed_value_producer_t::transformed_value_producer_t
transformed_value_producer_t(Producer &&producer, Transformer &&transformer)
Definition: easy_parser.hpp:1196
restinio::easy_parser::impl::is_appropriate_transformer_result_type
A metafunction that checks is Result_Type can be used as the result of transformation method.
Definition: easy_parser.hpp:1111
restinio::easy_parser::result_value_wrapper< nothing_t >::as_result
static void as_result(wrapped_type &, result_type &&) noexcept
Definition: easy_parser.hpp:437
restinio::easy_parser::impl::producer_tag< Target_Type >::result_type
Target_Type result_type
Definition: easy_parser.hpp:946
restinio::easy_parser::impl::produce_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:2013
restinio::easy_parser::impl::exact_fragment_producer_t::exact_fragment_producer_t
exact_fragment_producer_t(std::string fragment)
Definition: easy_parser.hpp:3393
restinio::easy_parser::impl::is_appropriate_transformer_result_type::value
static constexpr bool value
Definition: easy_parser.hpp:1112
restinio::easy_parser::impl::source_t::putback
void putback() noexcept
Return one character back to the input stream.
Definition: easy_parser.hpp:777
restinio::easy_parser::impl::just_value_transformer_t::transform
RESTINIO_NODISCARD T transform(Input &&) const noexcept(noexcept(T{m_value}))
Definition: easy_parser.hpp:3157
restinio::easy_parser::decimal_number_p
RESTINIO_NODISCARD auto decimal_number_p() noexcept
A factory function to create a decimal_number_producer.
Definition: easy_parser.hpp:4387
restinio::easy_parser::caseless_exact
RESTINIO_NODISCARD auto caseless_exact(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment clause.
Definition: easy_parser.hpp:4962
restinio::easy_parser::impl::alternatives_clause_t::alternatives_clause_t
alternatives_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1640
restinio::easy_parser::impl::exact_fragment_producer_t
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
Definition: easy_parser.hpp:3389
restinio::easy_parser::impl::particular_symbol_predicate_t
A predicate for cases where exact match of expected and actual symbols is required.
Definition: easy_parser.hpp:2198
restinio::easy_parser::impl::try_parse_caseless_exact_fragment
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse_caseless_exact_fragment(source_t &from, It begin, It end)
Definition: easy_parser.hpp:3419
restinio::easy_parser::impl::remove_trailing_spaces
RESTINIO_NODISCARD string_view_t remove_trailing_spaces(string_view_t from) noexcept
Helper function for removal of trailing spaces from a string-view.
Definition: easy_parser.hpp:1594
restinio::easy_parser::impl::is_hexdigit_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:722
restinio::easy_parser::impl::any_symbol_if_not_producer_t::any_symbol_if_not_producer_t
any_symbol_if_not_producer_t(char sentinel)
Definition: easy_parser.hpp:2320
restinio::easy_parser::expected_digits
constexpr RESTINIO_NODISCARD digits_to_consume_t expected_digits(digits_to_consume_t::underlying_int_t total) noexcept
Create a limit for number of digits to be extracted.
Definition: easy_parser.hpp:549
restinio::easy_parser::impl::transformed_value_producer_t::try_parse
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &source)
Definition: easy_parser.hpp:1205
restinio::easy_parser::and_clause
RESTINIO_NODISCARD auto and_clause(Clauses &&... clauses)
A factory function to create an and_clause.
Definition: easy_parser.hpp:3718
restinio::easy_parser::impl::just_value_transformer_t
A transformer that skips incoming value and returns a value specified by a user.
Definition: easy_parser.hpp:3146
restinio::easy_parser::impl::field_setter_consumer_t
A template for consumers that store a value to the specified field of a target object.
Definition: easy_parser.hpp:2969
restinio::easy_parser::result_value_wrapper< std::array< T, S > >::result_type
std::array< T, S > result_type
Definition: easy_parser.hpp:309
restinio::easy_parser::impl::repeat_clause_t::repeat_clause_t
repeat_clause_t(std::size_t min_occurences, std::size_t max_occurences, Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:2068
restinio::easy_parser
Definition: easy_parser.hpp:39
restinio::easy_parser::caseless_symbol_p
RESTINIO_NODISCARD auto caseless_symbol_p(char expected) noexcept
A factory function to create a caseless_symbol_producer.
Definition: easy_parser.hpp:3993
restinio::easy_parser::custom_consumer
RESTINIO_NODISCARD auto custom_consumer(F consumer)
A factory function to create a custom_consumer.
Definition: easy_parser.hpp:4516
restinio::easy_parser::sequence
RESTINIO_NODISCARD auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
Definition: easy_parser.hpp:3758
restinio::easy_parser::impl::decimal_number_producer_t
A producer for the case when a signed decimal number is expected in the input stream.
Definition: easy_parser.hpp:2698
restinio::easy_parser::impl::transformed_value_producer_t::m_transformer
Transformer m_transformer
Definition: easy_parser.hpp:1191
restinio::easy_parser::impl::is_space_predicate_t
A preducate for symbol_producer_template that checks that a symbol is a space.
Definition: easy_parser.hpp:650
nonstd::sv_lite::to_string
std::basic_string< CharT, Traits > to_string(basic_string_view< CharT, Traits > v)
Definition: string_view.hpp:1144
restinio::easy_parser::impl::not_particular_symbol_predicate_t
A predicate for cases where mismatch with a particular symbol is required.
Definition: easy_parser.hpp:2219
restinio::easy_parser::impl::decimal_number_producer_with_digits_limit_t::decimal_number_producer_with_digits_limit_t
decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
Definition: easy_parser.hpp:2816
restinio::easy_parser::impl::transformed_value_producer_traits_checker
A helper template for checking a possibility to connect a producer with a transformer.
Definition: easy_parser.hpp:1145
restinio::easy_parser::impl::decimal_number_producer_with_digits_limit_t::try_parse
RESTINIO_NODISCARD auto try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2823
restinio::easy_parser::impl::decimal_number_producer_t::try_parse_impl
RESTINIO_NODISCARD try_parse_result_type try_parse_impl(source_t &from, Digits_Limit_Maker &&digits_limit_maker) const noexcept
Definition: easy_parser.hpp:2719
restinio::easy_parser::impl::tuple_item_consumer_t
A consumer that stores a result value at the specified index in the result tuple.
Definition: easy_parser.hpp:3021
restinio::easy_parser::impl::non_negative_decimal_number_producer_t::try_parse
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2575
restinio::easy_parser::impl::conversion_result_type_detector< expected_t< Result_Type, error_reason_t > >::type
Result_Type type
Definition: easy_parser.hpp:3233
const
#define const
Definition: zconf.h:230
restinio::easy_parser::impl::any_symbol_predicate_t
A predicate that allows extraction of any symbol.
Definition: easy_parser.hpp:2179
restinio::easy_parser::impl::and_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1849
restinio::easy_parser::impl::just_result_consumer_t
A consumer for the case when a specific value should be used as the result instead of the value produ...
Definition: easy_parser.hpp:2892
restinio::easy_parser::impl::and_clause_t::try_process
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &)
Definition: easy_parser.hpp:1860
restinio::easy_parser::impl::symbol_producer_template_t::try_parse
RESTINIO_NODISCARD expected_t< char, parse_error_t > try_parse(source_t &from) const noexcept
Definition: easy_parser.hpp:2142
restinio::easy_parser::impl::transformed_value_producer_t::result_type
typename Transformer::result_type result_type
Definition: easy_parser.hpp:1194
restinio::easy_parser::repeat
RESTINIO_NODISCARD auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
Definition: easy_parser.hpp:3876
restinio::easy_parser::impl::source_t::eof
RESTINIO_NODISCARD bool eof() const noexcept
Is EOF has been reached?
Definition: easy_parser.hpp:803
restinio::easy_parser::skip
RESTINIO_NODISCARD auto skip() noexcept
A factory function to create a skip_consumer.
Definition: easy_parser.hpp:3922
restinio::easy_parser::maybe
RESTINIO_NODISCARD auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
Definition: easy_parser.hpp:3634
optional.hpp
restinio::easy_parser::impl::decimal_number_producer_with_digits_limit_t::m_digits_limit
digits_to_consume_t m_digits_limit
Definition: easy_parser.hpp:2813
restinio::easy_parser::impl::non_negative_decimal_number_producer_with_digits_limit_t::non_negative_decimal_number_producer_with_digits_limit_t
non_negative_decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
Definition: easy_parser.hpp:2604