RESTinio
basics.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
12#pragma once
13
15
17
18#include <restinio/expected.hpp>
19
20#include <algorithm>
21
22namespace restinio
23{
24
25namespace http_field_parsers
26{
27
28using namespace restinio::easy_parser;
29
31
32namespace qvalue_details
33{
34
36using underlying_uint_t = std::uint_least16_t;
37
39constexpr underlying_uint_t maximum = 1000u;
41constexpr underlying_uint_t zero = 0u;
42
43// A part of workaround for problem with static constexpr members
44// detected after release of v.0.6.1.
45enum class extremum_min_t { v };
46enum class extremum_max_t { v };
47
51{
53
54public :
55 explicit constexpr
56 trusted( underlying_uint_t value ) noexcept : m_value{ value } {}
57
58 constexpr auto get() const noexcept { return m_value; }
59};
60
64{
66
67public :
68 explicit
70 {
71 if( m_value > maximum )
72 throw exception_t( "invalid value for "
73 "http_field_parser::rfc::qvalue_t" );
74 }
75
76 auto get() const noexcept { return m_value; }
77};
78
79} /* namespace qvalue_details */
80
81//
82// qvalue_t
83//
136{
137public :
144
153
154private :
155 // Note: with the terminal 0-symbol.
156 using underlying_char_array_t = std::array<char, 6>;
157
159
162 {
165 {
166 std::strcpy( &result[0], "1.000" );
167 }
168 else
169 {
170 result[0] = '0';
171 result[1] = '.';
172
173 result[2] = '0' + static_cast<char>(m_value / 100u);
174 const auto d2 = m_value % 100u;
175 result[3] = '0' + static_cast<char>(d2 / 10u);
176 const auto d3 = d2 % 10u;
177 result[4] = '0' + static_cast<char>(d3);
178 result[5] = 0;
179 }
180
181 return result;
182 }
183
184public :
185
186 constexpr qvalue_t() = default;
187
188 qvalue_t( untrusted val ) noexcept
189 : m_value{ val.get() }
190 {}
191
192 constexpr qvalue_t( trusted val ) noexcept
193 : m_value{ val.get() }
194 {}
195
198 {}
199
202 {}
203
204 constexpr auto as_uint() const noexcept { return m_value; }
205
206 auto as_string() const
207 {
208 return std::string{ &make_char_array().front() };
209 }
210
211 friend std::ostream &
212 operator<<( std::ostream & to, const qvalue_t & what )
213 {
214 return (to << &what.make_char_array().front());
215 }
216};
217
219inline bool
220operator==( const qvalue_t & a, const qvalue_t & b ) noexcept
221{
222 return a.as_uint() == b.as_uint();
223}
224
226inline bool
227operator!=( const qvalue_t & a, const qvalue_t & b ) noexcept
228{
229 return a.as_uint() != b.as_uint();
230}
231
233inline bool
234operator<( const qvalue_t & a, const qvalue_t & b ) noexcept
235{
236 return a.as_uint() < b.as_uint();
237}
238
240inline bool
241operator<=( const qvalue_t & a, const qvalue_t & b ) noexcept
242{
243 return a.as_uint() <= b.as_uint();
244}
245
246namespace impl
247{
248
249using namespace restinio::easy_parser::impl;
250
251//
252// is_alpha
253//
262inline constexpr bool
263is_alpha( const char ch ) noexcept
264{
265 return (ch >= '\x41' && ch <= '\x5A') ||
266 (ch >= '\x61' && ch <= '\x7A');
267}
268
269//
270// is_alpha_predicate_t
271//
279{
281 bool
282 operator()( const char actual ) const noexcept
283 {
284 return is_alpha(actual);
285 }
286};
287
288//
289// is_alphanum_predicate_t
290//
298{
300 bool
301 operator()( const char actual ) const noexcept
302 {
303 return is_alpha(actual) || is_digit(actual);
304 }
305};
306
307//
308// is_vchar
309//
318inline constexpr bool
319is_vchar( const char ch ) noexcept
320{
321 return (ch >= '\x21' && ch <= '\x7E');
322}
323
324//
325// is_vchar_predicate_t
326//
334{
336 bool
337 operator()( const char actual ) const noexcept
338 {
339 return is_vchar(actual);
340 }
341};
342
343//
344// is_obs_text
345//
354inline constexpr bool
355is_obs_text( const char ch ) noexcept
356{
357 constexpr unsigned short left = 0x80u;
358 constexpr unsigned short right = 0xFFu;
359
360 const unsigned short t = static_cast<unsigned short>(
361 static_cast<unsigned char>(ch));
362
363 return (t >= left && t <= right);
364}
365
366//
367// is_qdtext
368//
377inline constexpr bool
378is_qdtext( const char ch ) noexcept
379{
380 return ch == SP ||
381 ch == HTAB ||
382 ch == '!' ||
383 (ch >= '\x23' && ch <= '\x5B') ||
384 (ch >= '\x5D' && ch <= '\x7E') ||
385 is_obs_text( ch );
386}
387
388//
389// is_ctext
390//
399inline constexpr bool
400is_ctext( const char ch ) noexcept
401{
402 return ch == SP ||
403 ch == HTAB ||
404 (ch >= '\x21' && ch <= '\x27') ||
405 (ch >= '\x2A' && ch <= '\x5B') ||
406 (ch >= '\x5D' && ch <= '\x7E') ||
407 is_obs_text( ch );
408}
409
410//
411// is_ctext_predicate_t
412//
420{
422 bool
423 operator()( const char actual ) const noexcept
424 {
425 return is_ctext(actual);
426 }
427};
428
429//
430// is_token_char_predicate_t
431//
437{
439 static constexpr bool
440 is_token_char( const char ch ) noexcept
441 {
442 return is_alpha(ch) || is_digit(ch) ||
443 ch == '!' ||
444 ch == '#' ||
445 ch == '$' ||
446 ch == '%' ||
447 ch == '&' ||
448 ch == '\'' ||
449 ch == '*' ||
450 ch == '+' ||
451 ch == '-' ||
452 ch == '.' ||
453 ch == '^' ||
454 ch == '_' ||
455 ch == '`' ||
456 ch == '|' ||
457 ch == '~';
458 }
459
461 bool
462 operator()( const char actual ) const noexcept
463 {
464 return is_token_char(actual);
465 }
466};
467
468//
469// ows_producer_t
470//
481class ows_producer_t : public producer_tag< restinio::optional_t<char> >
482{
483public :
487 source_t & from ) const noexcept
488 {
489 std::size_t extracted_spaces{};
490 character_t ch;
491 for( ch = from.getch();
492 !ch.m_eof && is_space(ch.m_ch);
493 ch = from.getch() )
494 {
495 ++extracted_spaces;
496 }
497
498 if( !ch.m_eof )
499 // The first non-space char should be returned back.
500 from.putback();
501
502 if( extracted_spaces > 0u )
503 return result_type{ ' ' };
504
505 return result_type{ nullopt };
506 }
507};
508
509//
510// token_producer_t
511//
522class token_producer_t : public producer_tag< std::string >
523{
526 try_parse_value( source_t & from, std::string & accumulator )
527 {
528 error_reason_t reason = error_reason_t::pattern_not_found;
529
530 do
531 {
532 const auto ch = from.getch();
533 if( ch.m_eof )
534 {
535 reason = error_reason_t::unexpected_eof;
536 break;
537 }
538
539 if( !is_token_char(ch.m_ch) )
540 {
541 from.putback();
542 reason = error_reason_t::unexpected_character;
543 break;
544 }
545
546 accumulator += ch.m_ch;
547 }
548 while( true );
549
550 if( accumulator.empty() )
551 {
552 return parse_error_t{ from.current_position(), reason };
553 }
554
555 return nullopt;
556 }
557
559 static constexpr bool
560 is_token_char( const char ch ) noexcept
561 {
563 }
564
565public :
568 try_parse( source_t & from ) const
569 {
570 std::string value;
571 const auto try_result = try_parse_value( from, value );
572 if( !try_result )
573 return { std::move(value) };
574 else
575 return make_unexpected( *try_result );
576 }
577};
578
579//
580// quoted_string_producer_t
581//
592class quoted_string_producer_t : public producer_tag< std::string >
593{
596 try_parse_value( source_t & from, std::string & accumulator )
597 {
598 error_reason_t reason = error_reason_t::pattern_not_found;
599
600 bool second_quote_extracted{ false };
601 do
602 {
603 const auto ch = from.getch();
604 if( ch.m_eof )
605 {
606 reason = error_reason_t::unexpected_eof;
607 break;
608 }
609
610 if( '"' == ch.m_ch )
611 second_quote_extracted = true;
612 else if( '\\' == ch.m_ch )
613 {
614 const auto next = from.getch();
615 if( next.m_eof )
616 {
617 reason = error_reason_t::unexpected_eof;
618 break;
619 }
620 else if( SP == next.m_ch || HTAB == next.m_ch ||
621 is_vchar( next.m_ch ) ||
622 is_obs_text( next.m_ch ) )
623 {
624 accumulator += next.m_ch;
625 }
626 else
627 {
628 reason = error_reason_t::unexpected_character;
629 from.putback();
630 break;
631 }
632 }
633 else if( is_qdtext( ch.m_ch ) )
634 accumulator += ch.m_ch;
635 else
636 {
637 reason = error_reason_t::unexpected_character;
638 from.putback();
639 break;
640 }
641 }
642 while( !second_quote_extracted );
643
644 if( !second_quote_extracted )
645 return parse_error_t{ from.current_position(), reason };
646 else
647 return nullopt;
648 }
649
650public :
653 try_parse( source_t & from ) const
654 {
656
657 const auto ch = from.getch();
658 if( !ch.m_eof )
659 {
660 if( '"' == ch.m_ch )
661 {
662 std::string value;
663 const auto try_result = try_parse_value( from, value );
664 if( !try_result )
665 {
666 consumer.commit();
667 return { std::move(value) };
668 }
669 else
670 return make_unexpected( *try_result );
671 }
672 else
673 {
674 return make_unexpected( parse_error_t{
675 consumer.started_at(),
676 error_reason_t::unexpected_character
677 } );
678 }
679 }
680 else
681 return make_unexpected( parse_error_t{
682 consumer.started_at(),
683 error_reason_t::unexpected_eof
684 } );
685 }
686};
687
688//
689// quoted_pair_producer_t
690//
702{
703public :
706 try_parse( source_t & from ) const
707 {
709
710 error_reason_t reason = error_reason_t::unexpected_eof;
711
712 const auto ch = from.getch();
713 if( !ch.m_eof )
714 {
715 if( '\\' == ch.m_ch )
716 {
717 const auto next = from.getch();
718 if( !next.m_eof )
719 {
720 if( SP == next.m_ch || HTAB == next.m_ch ||
721 is_vchar( next.m_ch ) ||
722 is_obs_text( next.m_ch ) )
723 {
724 consumer.commit();
725 return next.m_ch;
726 }
727
728 reason = error_reason_t::unexpected_character;
729 }
730 }
731 else
732 reason = error_reason_t::unexpected_character;
733 }
734
735 return make_unexpected( parse_error_t{
736 from.current_position(),
737 reason
738 } );
739 }
740};
741
742//
743// comment_producer_t
744//
762class comment_producer_t : public producer_tag< std::string >
763{
764public :
767 try_parse( source_t & from ) const; // NOTE: implementation below.
768};
769
770} /* namespace impl */
771
772//
773// alpha_symbol_producer
774//
787inline auto
789{
792}
793
794//
795// alphanum_symbol_producer
796//
809inline auto
811{
814}
815
816//
817// vchar_symbol_producer
818//
831inline auto
833{
836}
837
838//
839// ctext_symbol_producer
840//
853inline auto
855{
858}
859
860//
861// comment_producer
862//
879inline auto
881{
883}
884
885//
886// ows_producer
887//
908inline auto
909ows_p() noexcept { return impl::ows_producer_t{}; }
910
911//
912// ows
913//
938inline auto
939ows() noexcept { return ows_p() >> skip(); }
940
941//
942// token_symbol_producer
943//
956inline auto
958{
961}
962
963//
964// token_producer
965//
984inline auto
985token_p() noexcept { return impl::token_producer_t{}; }
986
987//
988// quoted_string_producer
989//
1011inline auto
1013{
1015}
1016
1017//
1018// quoted_pair_producer
1019//
1037inline auto
1039{
1041}
1042
1043//
1044// expected_token_p
1045//
1072inline auto
1074{
1075 return produce< bool >(
1076 exact_p( token ) >> as_result(),
1077 not_clause( token_symbol_p() >> skip() ) );
1078}
1079
1080//
1081// expected_caseless_token_p
1082//
1111inline auto
1113{
1114 return produce< bool >(
1115 caseless_exact_p( token ) >> as_result(),
1116 not_clause( token_symbol_p() >> skip() ) );
1117}
1118
1119namespace impl
1120{
1121
1122//
1123// comment_producer_t implementation
1124//
1128{
1129 return produce< std::string >(
1130 sequence(
1131 symbol('('),
1132 repeat(0, N,
1137 []( std::string & dest, std::string && what ) {
1138 dest += what;
1139 } )
1140 ) ),
1141 symbol(')') )
1142 ).try_parse( from );
1143}
1144
1145//
1146// qvalue_producer_t
1147//
1163 : public producer_tag< qvalue_t >
1164{
1165 // This type has to be used as type parameter for produce().
1167 {
1169 };
1170
1174 {
1176
1177 public :
1179 : m_multiplier{ m }
1180 {}
1181
1182 void
1184 {
1185 dest.m_value += m_multiplier *
1186 static_cast< qvalue_t::underlying_uint_t >(digit - '0');
1187 }
1188 };
1189
1190public :
1193 try_parse( source_t & from ) const noexcept
1194 {
1195 const auto parse_result = produce< zero_initialized_unit_t >(
1197 sequence(
1198 symbol('0'),
1199 maybe(
1200 symbol('.'),
1201 maybe( digit_p() >> digit_consumer_t{100},
1202 maybe( digit_p() >> digit_consumer_t{10},
1203 maybe( digit_p() >> digit_consumer_t{1} )
1204 )
1205 )
1206 )
1207 ),
1208 sequence(
1209 symbol_p('1') >> digit_consumer_t{1000},
1210 maybe(
1211 symbol('.'),
1212 maybe( symbol('0'),
1213 maybe( symbol('0'),
1214 maybe( symbol('0') )
1215 )
1216 )
1217 )
1218 )
1219 )
1220 ).try_parse( from );
1221
1222 if( parse_result )
1223 return qvalue_t{ qvalue_t::trusted{ parse_result->m_value } };
1224 else
1225 return make_unexpected( parse_result.error() );
1226 }
1227};
1228
1229} /* namespace impl */
1230
1231//
1232// qvalue_producer
1233//
1249inline auto
1250qvalue_p() noexcept
1251{
1252 return impl::qvalue_producer_t{};
1253}
1254
1255//
1256// weight_producer
1257//
1276inline auto
1277weight_p() noexcept
1278{
1279 return produce< qvalue_t >(
1280 ows(),
1281 symbol(';'),
1282 ows(),
1283 caseless_symbol('q'),
1284 symbol('='),
1285 qvalue_p() >> as_result()
1286 );
1287}
1288
1289namespace impl
1290{
1291
1292//
1293// non_empty_comma_separated_list_producer_t
1294//
1313template<
1314 typename Container,
1315 typename Element_Producer >
1317 : public producer_tag< Container >
1318{
1319 static_assert( impl::is_producer_v<Element_Producer>,
1320 "Element_Producer should be a value producer type" );
1321
1322 Element_Producer m_element;
1323
1324public :
1326
1328 Element_Producer && element )
1329 : m_element{ std::move(element) }
1330 {}
1331
1335 {
1336 Container tmp_value;
1337
1338 const auto appender = to_container();
1339
1340 const auto process_result = sequence(
1341 repeat( 0, N, symbol(','), ows() ),
1342 m_element >> appender,
1343 repeat( 0, N,
1344 ows(), symbol(','),
1345 maybe( ows(), m_element >> appender )
1346 )
1347 ).try_process( from, tmp_value );
1348
1349 if( !process_result )
1350 return { std::move(tmp_value) };
1351 else
1352 return make_unexpected( *process_result );
1353 }
1354};
1355
1356//
1357// maybe_empty_comma_separated_list_producer_t
1358//
1377template<
1378 typename Container,
1379 typename Element_Producer >
1381 : public producer_tag< Container >
1382{
1383 static_assert( impl::is_producer_v<Element_Producer>,
1384 "Element_Producer should be a value producer type" );
1385
1386 Element_Producer m_element;
1387
1388public :
1390
1392 Element_Producer && element )
1393 : m_element{ std::move(element) }
1394 {}
1395
1399 {
1400 Container tmp_value;
1401
1402 const auto appender = to_container();
1403
1404 const auto process_result = maybe(
1405 alternatives( symbol(','), m_element >> appender ),
1406 repeat( 0, N,
1407 ows(), symbol(','),
1408 maybe( ows(), m_element >> appender )
1409 )
1410 ).try_process( from, tmp_value );
1411
1412 if( !process_result )
1413 return { std::move(tmp_value) };
1414 else
1415 return make_unexpected( *process_result );
1416 }
1417};
1418
1419} /* namespace impl */
1420
1421//
1422// non_empty_comma_separated_list_producer
1423//
1452template<
1453 typename Container,
1454 typename Element_Producer >
1456auto
1457non_empty_comma_separated_list_p( Element_Producer element )
1458{
1459 static_assert( impl::is_producer_v<Element_Producer>,
1460 "Element_Producer should be a value producer type" );
1461
1463 Container,
1464 Element_Producer >{ std::move(element) };
1465}
1466
1467//
1468// maybe_empty_comma_separated_list_producer
1469//
1498template<
1499 typename Container,
1500 typename Element_Producer >
1502auto
1503maybe_empty_comma_separated_list_p( Element_Producer element )
1504{
1505 static_assert( impl::is_producer_v<Element_Producer>,
1506 "Element_Producer should be a value producer type" );
1507
1509 Container,
1510 Element_Producer >{ std::move(element) };
1511}
1512
1513//
1514// parameter_with_mandatory_value_t
1515//
1521using parameter_with_mandatory_value_t = std::pair< std::string, std::string >;
1522
1523//
1524// parameter_with_mandatory_value_container_t
1525//
1532 std::vector< parameter_with_mandatory_value_t >;
1533
1534//
1535// not_found_t
1536//
1542struct not_found_t {};
1543
1544//
1545// find_first
1546//
1570 string_view_t what )
1571{
1572 const auto it = std::find_if( where.begin(), where.end(),
1573 [&what]( const auto & pair ) {
1574 return restinio::impl::is_equal_caseless( pair.first, what );
1575 } );
1576 if( it != where.end() )
1577 return string_view_t{ it->second };
1578 else
1579 return make_unexpected( not_found_t{} );
1580}
1581
1582namespace impl
1583{
1584
1585namespace params_with_value_producer_details
1586{
1587
1588//
1589// make_parser
1590//
1598inline auto
1600{
1601 return produce< parameter_with_mandatory_value_container_t >(
1602 repeat( 0, N,
1603 produce< parameter_with_mandatory_value_t >(
1604 ows(),
1605 symbol(';'),
1606 ows(),
1607 token_p() >> to_lower()
1608 >> &parameter_with_mandatory_value_t::first,
1609 symbol('='),
1611 token_p()
1612 >> &parameter_with_mandatory_value_t::second,
1614 >> &parameter_with_mandatory_value_t::second
1615 )
1616 ) >> to_container()
1617 )
1618 );
1619}
1620
1621} /* namespace params_with_value_producer_details */
1622
1623//
1624// params_with_value_producer_t
1625//
1633 : public producer_tag< parameter_with_mandatory_value_container_t >
1634{
1635 using actual_producer_t = std::decay_t<
1637
1640
1641public :
1643
1645 auto
1647 {
1648 return m_producer.try_parse( from );
1649 }
1650};
1651
1652} /* namespace impl */
1653
1654//
1655// params_with_value_producer
1656//
1684inline impl::params_with_value_producer_t
1685params_with_value_p() { return {}; }
1686
1687//
1688// parameter_with_optional_value_t
1689//
1696 std::pair< std::string, restinio::optional_t<std::string> >;
1697
1698//
1699// parameter_with_optional_value_container_t
1700//
1707 std::vector< parameter_with_optional_value_t >;
1708
1709//
1710// find_first
1711//
1740 string_view_t what )
1741{
1742 const auto it = std::find_if( where.begin(), where.end(),
1743 [&what]( const auto & pair ) {
1744 return restinio::impl::is_equal_caseless( pair.first, what );
1745 } );
1746 if( it != where.end() )
1747 {
1748 const auto opt = it->second;
1749 if( opt )
1750 return string_view_t{ *opt };
1751 else
1753 }
1754 else
1755 return make_unexpected( not_found_t{} );
1756}
1757
1758namespace impl
1759{
1760
1761namespace params_with_opt_value_producer_details
1762{
1763
1764//
1765// make_parser
1766//
1774inline auto
1776{
1777 return produce< parameter_with_optional_value_container_t >(
1778 repeat( 0, N,
1779 produce< parameter_with_optional_value_t >(
1780 ows(),
1781 symbol(';'),
1782 ows(),
1783 token_p() >> to_lower()
1784 >> &parameter_with_optional_value_t::first,
1785 maybe(
1786 symbol('='),
1788 token_p()
1789 >> &parameter_with_optional_value_t::second,
1791 >> &parameter_with_optional_value_t::second
1792 )
1793 )
1794 ) >> to_container()
1795 )
1796 );
1797}
1798
1799} /* namespace params_with_opt_value_producer_details */
1800
1801//
1802// params_with_opt_value_producer_t
1803//
1811 : public producer_tag< parameter_with_optional_value_container_t >
1812{
1813 using actual_producer_t = std::decay_t<
1815
1818
1819public :
1821
1823 auto
1825 {
1826 return m_producer.try_parse( from );
1827 }
1828};
1829
1830} /* namespace impl */
1831
1832//
1833// params_with_opt_value_producer
1834//
1862inline impl::params_with_opt_value_producer_t
1864
1865} /* namespace http_field_parser */
1866
1867} /* namespace restinio */
1868
A helper class to automatically return acquired content back to the input stream.
The class that implements "input stream".
RESTINIO_NODISCARD character_t getch() noexcept
Get the next character from the input stream.
void putback() noexcept
Return one character back to the input stream.
RESTINIO_NODISCARD position_t current_position() const noexcept
Get the current position in the stream.
A template for producer of charachers that satisfy some predicate.
Information about parsing error.
Definition: easy_parser.hpp:93
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition: basics.hpp:1127
A template for a producer that handles possibly empty list of comma-separated values.
Definition: basics.hpp:1382
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from)
Definition: basics.hpp:1398
A template for a producer that handles non-empty list of comma-separated values.
Definition: basics.hpp:1318
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from)
Definition: basics.hpp:1334
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
Definition: basics.hpp:486
A type of producer that produces instances of parameter_with_optional_value_container.
Definition: basics.hpp:1812
std::decay_t< decltype(params_with_opt_value_producer_details::make_parser()) > actual_producer_t
Definition: basics.hpp:1814
A type of producer that produces instances of parameter_with_mandatory_value_container.
Definition: basics.hpp:1634
RESTINIO_NODISCARD auto try_parse(source_t &from)
Definition: basics.hpp:1646
std::decay_t< decltype(params_with_value_producer_details::make_parser()) > actual_producer_t
Definition: basics.hpp:1636
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition: basics.hpp:706
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition: basics.hpp:653
static RESTINIO_NODISCARD optional_t< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
Definition: basics.hpp:596
A helper class to be used to accumulate actual integer while when the next digit is extracted from th...
Definition: basics.hpp:1174
void consume(zero_initialized_unit_t &dest, char &&digit)
Definition: basics.hpp:1183
An implementation of producer of qvalue.
Definition: basics.hpp:1164
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
Definition: basics.hpp:1193
RESTINIO_NODISCARD expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition: basics.hpp:568
static RESTINIO_NODISCARD optional_t< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
Definition: basics.hpp:526
static RESTINIO_NODISCARD constexpr bool is_token_char(const char ch) noexcept
Definition: basics.hpp:560
A helper wrapper to indicate that value is already checked and shouldn't be checked again.
Definition: basics.hpp:51
constexpr trusted(underlying_uint_t value) noexcept
Definition: basics.hpp:56
A helper wrapper to indicate that value hasn't been checked yet and should be checked in the construc...
Definition: basics.hpp:64
A class for holding the parsed value of qvalue from RFC7231.
Definition: basics.hpp:136
constexpr qvalue_t(qvalue_details::extremum_min_t) noexcept
Definition: basics.hpp:196
constexpr auto as_uint() const noexcept
Definition: basics.hpp:204
std::array< char, 6 > underlying_char_array_t
Definition: basics.hpp:156
underlying_char_array_t make_char_array() const noexcept
Definition: basics.hpp:161
static constexpr qvalue_details::extremum_min_t zero
The indicator that tells that new qvalue object should have the minimal allowed value.
Definition: basics.hpp:151
constexpr qvalue_t(trusted val) noexcept
Definition: basics.hpp:192
qvalue_details::underlying_uint_t underlying_uint_t
The type of underlying small integer.
Definition: basics.hpp:139
constexpr qvalue_t(qvalue_details::extremum_max_t) noexcept
Definition: basics.hpp:200
qvalue_t(untrusted val) noexcept
Definition: basics.hpp:188
friend std::ostream & operator<<(std::ostream &to, const qvalue_t &what)
Definition: basics.hpp:212
static constexpr qvalue_details::extremum_max_t maximum
The indicator that tells that new qvalue object should have the maximal allowed value.
Definition: basics.hpp:147
#define RESTINIO_NODISCARD
An very small, simple and somewhat limited implementation of recursive-descent parser.
const nullopt_t nullopt((nullopt_t::init()))
constexpr char HTAB
A constant for Horizontal Tab value.
RESTINIO_NODISCARD constexpr bool is_space(const char ch) noexcept
If a character a space character?
constexpr char SP
A constant for SPACE value.
RESTINIO_NODISCARD constexpr bool is_digit(const char ch) noexcept
Is a character a decimal digit?
@ consumer
Entity is a consumer of values. It requires a value on the input and doesn't produces anything.
RESTINIO_NODISCARD auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
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...
RESTINIO_NODISCARD auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
error_reason_t
Reason of parsing error.
Definition: easy_parser.hpp:52
RESTINIO_NODISCARD auto digit() noexcept
A factory function to create a clause that expects a decimal digit, extracts it and then skips it.
RESTINIO_NODISCARD auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
RESTINIO_NODISCARD auto skip() noexcept
A factory function to create a skip_consumer.
RESTINIO_NODISCARD auto custom_consumer(F consumer)
A factory function to create a custom_consumer.
RESTINIO_NODISCARD auto digit_p() noexcept
A factory function to create a digit_producer.
RESTINIO_NODISCARD auto exact_p(string_view_t fragment)
A factory function that creates an instance of exact_fragment_producer.
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...
RESTINIO_NODISCARD auto as_result() noexcept
A factory function to create a as_result_consumer.
constexpr std::size_t N
A special marker that means infinite repetitions.
RESTINIO_NODISCARD auto to_container()
A factory function to create a to_container_consumer.
RESTINIO_NODISCARD auto symbol_p(char expected) noexcept
A factory function to create a symbol_producer.
RESTINIO_NODISCARD auto not_clause(Clauses &&... clauses)
A factory function to create a not_clause.
RESTINIO_NODISCARD auto caseless_exact_p(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment_producer.
RESTINIO_NODISCARD auto to_lower() noexcept
A factory function to create a to_lower_transformer.
RESTINIO_NODISCARD auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
RESTINIO_NODISCARD auto make_parser()
Helper function that creates an instance of producer of parameter_with_optional_value_container.
Definition: basics.hpp:1775
RESTINIO_NODISCARD auto make_parser()
Helper function that creates an instance of producer of parameter_with_mandatory_value_container.
Definition: basics.hpp:1599
RESTINIO_NODISCARD constexpr bool is_vchar(const char ch) noexcept
Is a character a VCHAR?
Definition: basics.hpp:319
RESTINIO_NODISCARD constexpr bool is_obs_text(const char ch) noexcept
Is a character an obs_text?
Definition: basics.hpp:355
RESTINIO_NODISCARD constexpr bool is_alpha(const char ch) noexcept
Is a character an ALPHA?
Definition: basics.hpp:263
RESTINIO_NODISCARD constexpr bool is_ctext(const char ch) noexcept
Is a character a ctext?
Definition: basics.hpp:400
RESTINIO_NODISCARD constexpr bool is_qdtext(const char ch) noexcept
Is a character a qdtext?
Definition: basics.hpp:378
constexpr underlying_uint_t zero
The minimal allowed value for a qvalue.
Definition: basics.hpp:41
std::uint_least16_t underlying_uint_t
A type to hold a qvalue.
Definition: basics.hpp:36
constexpr underlying_uint_t maximum
The maximal allowed value for a qvalue.
Definition: basics.hpp:39
RESTINIO_NODISCARD auto qvalue_p() noexcept
A factory function to create a qvalue_producer.
Definition: basics.hpp:1250
RESTINIO_NODISCARD auto maybe_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles possibly empty list of comma-separated values.
Definition: basics.hpp:1503
RESTINIO_NODISCARD auto non_empty_comma_separated_list_p(Element_Producer element)
A factory for a producer that handles non-empty list of comma-separated values.
Definition: basics.hpp:1457
RESTINIO_NODISCARD auto comment_p()
A factory for producer of comment token.
Definition: basics.hpp:880
RESTINIO_NODISCARD auto expected_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
Definition: basics.hpp:1073
RESTINIO_NODISCARD expected_t< string_view_t, not_found_t > find_first(const parameter_with_mandatory_value_container_t &where, string_view_t what)
A helper function to find the first occurence of a parameter with the specified value.
Definition: basics.hpp:1568
std::pair< std::string, restinio::optional_t< std::string > > parameter_with_optional_value_t
A type that describes a parameter with optional value.
Definition: basics.hpp:1696
RESTINIO_NODISCARD impl::params_with_value_producer_t params_with_value_p()
A factory of producer of parameter_with_mandatory_value_container.
Definition: basics.hpp:1685
std::vector< parameter_with_mandatory_value_t > parameter_with_mandatory_value_container_t
A type of container for parameters with mandatory values.
Definition: basics.hpp:1532
RESTINIO_NODISCARD auto alphanum_symbol_p()
A factory for producer of symbol that an ALPHA or DIGIT.
Definition: basics.hpp:810
RESTINIO_NODISCARD bool operator<(const qvalue_t &a, const qvalue_t &b) noexcept
Definition: basics.hpp:234
RESTINIO_NODISCARD auto vchar_symbol_p()
A factory for producer of VCHAR symbols.
Definition: basics.hpp:832
RESTINIO_NODISCARD auto alpha_symbol_p()
A factory for producer of ALPHA symbols.
Definition: basics.hpp:788
RESTINIO_NODISCARD bool operator==(const qvalue_t &a, const qvalue_t &b) noexcept
Definition: basics.hpp:220
RESTINIO_NODISCARD auto ows() noexcept
A factory function to create an OWS clause.
Definition: basics.hpp:939
RESTINIO_NODISCARD auto token_p() noexcept
A factory function to create a token_producer.
Definition: basics.hpp:985
RESTINIO_NODISCARD impl::params_with_opt_value_producer_t params_with_opt_value_p()
A factory of producer of parameter_with_optional_value_container.
Definition: basics.hpp:1863
RESTINIO_NODISCARD auto quoted_string_p() noexcept
A factory function to create a quoted_string_producer.
Definition: basics.hpp:1012
RESTINIO_NODISCARD bool operator!=(const qvalue_t &a, const qvalue_t &b) noexcept
Definition: basics.hpp:227
RESTINIO_NODISCARD bool operator<=(const qvalue_t &a, const qvalue_t &b) noexcept
Definition: basics.hpp:241
RESTINIO_NODISCARD auto expected_caseless_token_p(string_view_t token)
A factory function to create a producer that expect a token with specific value.
Definition: basics.hpp:1112
std::pair< std::string, std::string > parameter_with_mandatory_value_t
A type that describes a parameter with mandatory value.
Definition: basics.hpp:1521
RESTINIO_NODISCARD auto quoted_pair_p() noexcept
A factory function to create a quoted_pair_producer.
Definition: basics.hpp:1038
std::vector< parameter_with_optional_value_t > parameter_with_optional_value_container_t
A type of container for parameters with optional values.
Definition: basics.hpp:1707
RESTINIO_NODISCARD auto ctext_symbol_p()
A factory for producer of ctext symbols.
Definition: basics.hpp:854
RESTINIO_NODISCARD auto weight_p() noexcept
A factory function to create a producer for weight parameter.
Definition: basics.hpp:1277
RESTINIO_NODISCARD auto token_symbol_p() noexcept
A factory for producer of symbols than can be used in tokens.
Definition: basics.hpp:957
RESTINIO_NODISCARD auto ows_p() noexcept
A factory function to create an ows_producer.
Definition: basics.hpp:909
nonstd::string_view string_view_t
Definition: string_view.hpp:19
nonstd::expected< T, E > expected_t
Definition: expected.hpp:22
STL namespace.
Helpers for caseless comparison of strings.
One character extracted from the input stream.
A special base class to be used with consumers.
A special base class to be used with producers.
A preducate for symbol_producer_template that checks that a symbol is an alpha.
Definition: basics.hpp:279
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: basics.hpp:282
A preducate for symbol_producer_template that checks that a symbol is an alpha or numeric.
Definition: basics.hpp:298
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: basics.hpp:301
A preducate for symbol_producer_template that checks that a symbol is a ctext.
Definition: basics.hpp:420
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: basics.hpp:423
A predicate for symbol_producer_template that checks that a symbol can be used inside a token.
Definition: basics.hpp:437
static RESTINIO_NODISCARD constexpr bool is_token_char(const char ch) noexcept
Definition: basics.hpp:440
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: basics.hpp:462
A preducate for symbol_producer_template that checks that a symbol is a VCHAR.
Definition: basics.hpp:334
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: basics.hpp:337
An empty type to be used as indicator of negative search result.
Definition: basics.hpp:1542
#define const
Definition: zconf.h:230