RESTinio
Loading...
Searching...
No Matches
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;
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
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 static constexpr char fixed_value[]{ "1.000" };
167 std::copy( std::begin(fixed_value), std::end(fixed_value),
168 std::begin(result) );
169 }
170 else
171 {
172 result[0] = '0';
173 result[1] = '.';
174
175 result[2] = '0' + static_cast<char>(m_value / 100u);
176 const auto d2 = m_value % 100u;
177 result[3] = '0' + static_cast<char>(d2 / 10u);
178 const auto d3 = d2 % 10u;
179 result[4] = '0' + static_cast<char>(d3);
180 result[5] = 0;
181 }
182
183 return result;
184 }
185
186public :
187
188 constexpr qvalue_t() = default;
189
191 : m_value{ val.get() }
192 {}
193
195 : m_value{ val.get() }
196 {}
197
201
205
206 constexpr auto as_uint() const noexcept { return m_value; }
207
208 auto as_string() const
209 {
210 return std::string{ &make_char_array().front() };
211 }
212
213 friend std::ostream &
214 operator<<( std::ostream & to, const qvalue_t & what )
215 {
216 return (to << &what.make_char_array().front());
217 }
218};
219
220[[nodiscard]]
221inline bool
222operator==( const qvalue_t & a, const qvalue_t & b ) noexcept
223{
224 return a.as_uint() == b.as_uint();
225}
226
227[[nodiscard]]
228inline bool
229operator!=( const qvalue_t & a, const qvalue_t & b ) noexcept
230{
231 return a.as_uint() != b.as_uint();
232}
233
234[[nodiscard]]
235inline bool
236operator<( const qvalue_t & a, const qvalue_t & b ) noexcept
237{
238 return a.as_uint() < b.as_uint();
239}
240
241[[nodiscard]]
242inline bool
243operator<=( const qvalue_t & a, const qvalue_t & b ) noexcept
244{
245 return a.as_uint() <= b.as_uint();
246}
247
248namespace impl
249{
250
251using namespace restinio::easy_parser::impl;
252
253//
254// is_alpha
255//
263[[nodiscard]]
264inline constexpr bool
265is_alpha( const char ch ) noexcept
266{
267 return (ch >= '\x41' && ch <= '\x5A') ||
268 (ch >= '\x61' && ch <= '\x7A');
269}
270
271//
272// is_alpha_predicate_t
273//
281{
282 [[nodiscard]]
283 bool
284 operator()( const char actual ) const noexcept
285 {
286 return is_alpha(actual);
287 }
288};
289
290//
291// is_alphanum_predicate_t
292//
300{
301 [[nodiscard]]
302 bool
303 operator()( const char actual ) const noexcept
304 {
305 return is_alpha(actual) || is_digit(actual);
306 }
307};
308
309//
310// is_vchar
311//
319[[nodiscard]]
320inline constexpr bool
321is_vchar( const char ch ) noexcept
322{
323 return (ch >= '\x21' && ch <= '\x7E');
324}
325
326//
327// is_vchar_predicate_t
328//
336{
337 [[nodiscard]]
338 bool
339 operator()( const char actual ) const noexcept
340 {
341 return is_vchar(actual);
342 }
343};
344
345//
346// is_obs_text
347//
355[[nodiscard]]
356inline constexpr bool
357is_obs_text( const char ch ) noexcept
358{
359 constexpr unsigned short left = 0x80u;
360 constexpr unsigned short right = 0xFFu;
361
362 const unsigned short t = static_cast<unsigned short>(
363 static_cast<unsigned char>(ch));
364
365 return (t >= left && t <= right);
366}
367
368//
369// is_qdtext
370//
378[[nodiscard]]
379inline constexpr bool
380is_qdtext( const char ch ) noexcept
381{
382 return ch == SP ||
383 ch == HTAB ||
384 ch == '!' ||
385 (ch >= '\x23' && ch <= '\x5B') ||
386 (ch >= '\x5D' && ch <= '\x7E') ||
387 is_obs_text( ch );
388}
389
390//
391// is_ctext
392//
400[[nodiscard]]
401inline constexpr bool
402is_ctext( const char ch ) noexcept
403{
404 return ch == SP ||
405 ch == HTAB ||
406 (ch >= '\x21' && ch <= '\x27') ||
407 (ch >= '\x2A' && ch <= '\x5B') ||
408 (ch >= '\x5D' && ch <= '\x7E') ||
409 is_obs_text( ch );
410}
411
412//
413// is_ctext_predicate_t
414//
422{
423 [[nodiscard]]
424 bool
425 operator()( const char actual ) const noexcept
426 {
427 return is_ctext(actual);
428 }
429};
430
431//
432// is_token_char_predicate_t
433//
439{
440 [[nodiscard]]
441 static constexpr bool
442 is_token_char( const char ch ) noexcept
443 {
444 return is_alpha(ch) || is_digit(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 ch == '|' ||
459 ch == '~';
460 }
461
462 [[nodiscard]]
463 bool
464 operator()( const char actual ) const noexcept
465 {
466 return is_token_char(actual);
467 }
468};
469
470//
471// ows_producer_t
472//
483class ows_producer_t : public producer_tag< std::optional<char> >
484{
485public :
486 [[nodiscard]]
489 source_t & from ) const noexcept
490 {
491 std::size_t extracted_spaces{};
493 for( ch = from.getch();
494 !ch.m_eof && is_space(ch.m_ch);
495 ch = from.getch() )
496 {
498 }
499
500 if( !ch.m_eof )
501 // The first non-space char should be returned back.
502 from.putback();
503
504 if( extracted_spaces > 0u )
505 return result_type{ ' ' };
506
507 return result_type{ std::nullopt };
508 }
509};
510
511//
512// token_producer_t
513//
524class token_producer_t : public producer_tag< std::string >
525{
526 [[nodiscard]]
527 static std::optional< parse_error_t >
529 {
530 error_reason_t reason = error_reason_t::pattern_not_found;
531
532 do
533 {
534 const auto ch = from.getch();
535 if( ch.m_eof )
536 {
537 reason = error_reason_t::unexpected_eof;
538 break;
539 }
540
541 if( !is_token_char(ch.m_ch) )
542 {
543 from.putback();
544 reason = error_reason_t::unexpected_character;
545 break;
546 }
547
548 accumulator += ch.m_ch;
549 }
550 while( true );
551
552 if( accumulator.empty() )
553 {
554 return parse_error_t{ from.current_position(), reason };
555 }
556
557 return std::nullopt;
558 }
559
560 [[nodiscard]]
561 static constexpr bool
562 is_token_char( const char ch ) noexcept
563 {
565 }
566
567public :
568 [[nodiscard]]
571 {
572 std::string value;
573 const auto try_result = try_parse_value( from, value );
574 if( !try_result )
575 return { std::move(value) };
576 else
577 return make_unexpected( *try_result );
578 }
579};
580
581//
582// quoted_string_producer_t
583//
594class quoted_string_producer_t : public producer_tag< std::string >
595{
596 [[nodiscard]]
597 static std::optional< parse_error_t >
599 {
600 error_reason_t reason = error_reason_t::pattern_not_found;
601
602 bool second_quote_extracted{ false };
603 do
604 {
605 const auto ch = from.getch();
606 if( ch.m_eof )
607 {
608 reason = error_reason_t::unexpected_eof;
609 break;
610 }
611
612 if( '"' == ch.m_ch )
614 else if( '\\' == ch.m_ch )
615 {
616 const auto next = from.getch();
617 if( next.m_eof )
618 {
619 reason = error_reason_t::unexpected_eof;
620 break;
621 }
622 else if( SP == next.m_ch || HTAB == next.m_ch ||
623 is_vchar( next.m_ch ) ||
624 is_obs_text( next.m_ch ) )
625 {
626 accumulator += next.m_ch;
627 }
628 else
629 {
630 reason = error_reason_t::unexpected_character;
631 from.putback();
632 break;
633 }
634 }
635 else if( is_qdtext( ch.m_ch ) )
636 accumulator += ch.m_ch;
637 else
638 {
639 reason = error_reason_t::unexpected_character;
640 from.putback();
641 break;
642 }
643 }
644 while( !second_quote_extracted );
645
647 return parse_error_t{ from.current_position(), reason };
648 else
649 return std::nullopt;
650 }
651
652public :
653 [[nodiscard]]
656 {
658
659 const auto ch = from.getch();
660 if( !ch.m_eof )
661 {
662 if( '"' == ch.m_ch )
663 {
664 std::string value;
665 const auto try_result = try_parse_value( from, value );
666 if( !try_result )
667 {
668 consumer.commit();
669 return { std::move(value) };
670 }
671 else
672 return make_unexpected( *try_result );
673 }
674 else
675 {
676 return make_unexpected( parse_error_t{
677 consumer.started_at(),
678 error_reason_t::unexpected_character
679 } );
680 }
681 }
682 else
683 return make_unexpected( parse_error_t{
684 consumer.started_at(),
685 error_reason_t::unexpected_eof
686 } );
687 }
688};
689
690//
691// quoted_pair_producer_t
692//
704{
705public :
706 [[nodiscard]]
709 {
711
712 error_reason_t reason = error_reason_t::unexpected_eof;
713
714 const auto ch = from.getch();
715 if( !ch.m_eof )
716 {
717 if( '\\' == ch.m_ch )
718 {
719 const auto next = from.getch();
720 if( !next.m_eof )
721 {
722 if( SP == next.m_ch || HTAB == next.m_ch ||
723 is_vchar( next.m_ch ) ||
724 is_obs_text( next.m_ch ) )
725 {
726 consumer.commit();
727 return next.m_ch;
728 }
729
730 reason = error_reason_t::unexpected_character;
731 }
732 }
733 else
734 reason = error_reason_t::unexpected_character;
735 }
736
737 return make_unexpected( parse_error_t{
738 from.current_position(),
739 reason
740 } );
741 }
742};
743
744//
745// comment_producer_t
746//
764class comment_producer_t : public producer_tag< std::string >
765{
766public :
767 [[nodiscard]]
769 try_parse( source_t & from ) const; // NOTE: implementation below.
770};
771
772} /* namespace impl */
773
774//
775// alpha_symbol_producer
776//
788[[nodiscard]]
789inline auto
795
796//
797// alphanum_symbol_producer
798//
810[[nodiscard]]
811inline auto
817
818//
819// vchar_symbol_producer
820//
832[[nodiscard]]
833inline auto
839
840//
841// ctext_symbol_producer
842//
854[[nodiscard]]
855inline auto
861
862//
863// comment_producer
864//
880[[nodiscard]]
881inline auto
883{
885}
886
887//
888// ows_producer
889//
909[[nodiscard]]
910inline auto
912
913//
914// ows
915//
939[[nodiscard]]
940inline auto
941ows() noexcept { return ows_p() >> skip(); }
942
943//
944// token_symbol_producer
945//
957[[nodiscard]]
958inline auto
964
965//
966// token_producer
967//
985[[nodiscard]]
986inline auto
988
989//
990// quoted_string_producer
991//
1012[[nodiscard]]
1013inline auto
1018
1019//
1020// quoted_pair_producer
1021//
1038[[nodiscard]]
1039inline auto
1044
1045//
1046// expected_token_p
1047//
1073[[nodiscard]]
1074inline auto
1076{
1077 return produce< bool >(
1078 exact_p( token ) >> as_result(),
1079 not_clause( token_symbol_p() >> skip() ) );
1080}
1081
1082//
1083// expected_caseless_token_p
1084//
1112[[nodiscard]]
1113inline auto
1115{
1116 return produce< bool >(
1117 caseless_exact_p( token ) >> as_result(),
1118 not_clause( token_symbol_p() >> skip() ) );
1119}
1120
1121namespace impl
1122{
1123
1124//
1125// comment_producer_t implementation
1126//
1127[[nodiscard]]
1129comment_producer_t::try_parse( source_t & from ) const
1130{
1132 sequence(
1133 symbol('('),
1134 repeat(0, N,
1139 []( std::string & dest, std::string && what ) {
1140 dest += what;
1141 } )
1142 ) ),
1143 symbol(')') )
1144 ).try_parse( from );
1145}
1146
1147//
1148// qvalue_producer_t
1149//
1165 : public producer_tag< qvalue_t >
1166{
1167 // This type has to be used as type parameter for produce().
1172
1176 {
1178
1179 public :
1183
1184 void
1186 {
1187 dest.m_value += m_multiplier *
1188 static_cast< qvalue_t::underlying_uint_t >(digit - '0');
1189 }
1190 };
1191
1192public :
1193 [[nodiscard]]
1195 try_parse( source_t & from ) const noexcept
1196 {
1199 sequence(
1200 symbol('0'),
1201 maybe(
1202 symbol('.'),
1203 maybe( digit_p() >> digit_consumer_t{100},
1204 maybe( digit_p() >> digit_consumer_t{10},
1205 maybe( digit_p() >> digit_consumer_t{1} )
1206 )
1207 )
1208 )
1209 ),
1210 sequence(
1211 symbol_p('1') >> digit_consumer_t{1000},
1212 maybe(
1213 symbol('.'),
1214 maybe( symbol('0'),
1215 maybe( symbol('0'),
1216 maybe( symbol('0') )
1217 )
1218 )
1219 )
1220 )
1221 )
1222 ).try_parse( from );
1223
1224 if( parse_result )
1226 else
1227 return make_unexpected( parse_result.error() );
1228 }
1229};
1230
1231} /* namespace impl */
1232
1233//
1234// qvalue_producer
1235//
1250[[nodiscard]]
1251inline auto
1253{
1254 return impl::qvalue_producer_t{};
1255}
1256
1257//
1258// weight_producer
1259//
1277[[nodiscard]]
1278inline auto
1280{
1281 return produce< qvalue_t >(
1282 ows(),
1283 symbol(';'),
1284 ows(),
1285 caseless_symbol('q'),
1286 symbol('='),
1287 qvalue_p() >> as_result()
1288 );
1289}
1290
1291namespace impl
1292{
1293
1294//
1295// non_empty_comma_separated_list_producer_t
1296//
1315template<
1316 typename Container,
1317 typename Element_Producer >
1319 : public producer_tag< Container >
1320{
1321 static_assert( impl::is_producer_v<Element_Producer>,
1322 "Element_Producer should be a value producer type" );
1323
1325
1326public :
1328
1333
1334 [[nodiscard]]
1337 {
1339
1340 const auto appender = to_container();
1341
1342 const auto process_result = sequence(
1343 repeat( 0, N, symbol(','), ows() ),
1344 m_element >> appender,
1345 repeat( 0, N,
1346 ows(), symbol(','),
1347 maybe( ows(), m_element >> appender )
1348 )
1349 ).try_process( from, tmp_value );
1350
1351 if( !process_result )
1352 return { std::move(tmp_value) };
1353 else
1354 return make_unexpected( *process_result );
1355 }
1356};
1357
1358//
1359// maybe_empty_comma_separated_list_producer_t
1360//
1379template<
1380 typename Container,
1381 typename Element_Producer >
1383 : public producer_tag< Container >
1384{
1385 static_assert( impl::is_producer_v<Element_Producer>,
1386 "Element_Producer should be a value producer type" );
1387
1389
1390public :
1392
1397
1398 [[nodiscard]]
1401 {
1403
1404 const auto appender = to_container();
1405
1406 const auto process_result = maybe(
1408 repeat( 0, N,
1409 ows(), symbol(','),
1410 maybe( ows(), m_element >> appender )
1411 )
1412 ).try_process( from, tmp_value );
1413
1414 if( !process_result )
1415 return { std::move(tmp_value) };
1416 else
1417 return make_unexpected( *process_result );
1418 }
1419};
1420
1421} /* namespace impl */
1422
1423//
1424// non_empty_comma_separated_list_producer
1425//
1454template<
1455 typename Container,
1456 typename Element_Producer >
1457[[nodiscard]]
1458auto
1460{
1461 static_assert( impl::is_producer_v<Element_Producer>,
1462 "Element_Producer should be a value producer type" );
1463
1465 Container,
1466 Element_Producer >{ std::move(element) };
1467}
1468
1469//
1470// maybe_empty_comma_separated_list_producer
1471//
1500template<
1501 typename Container,
1502 typename Element_Producer >
1503[[nodiscard]]
1504auto
1506{
1507 static_assert( impl::is_producer_v<Element_Producer>,
1508 "Element_Producer should be a value producer type" );
1509
1511 Container,
1512 Element_Producer >{ std::move(element) };
1513}
1514
1515//
1516// parameter_with_mandatory_value_t
1517//
1523using parameter_with_mandatory_value_t = std::pair< std::string, std::string >;
1524
1525//
1526// parameter_with_mandatory_value_container_t
1527//
1534 std::vector< parameter_with_mandatory_value_t >;
1535
1536//
1537// not_found_t
1538//
1544struct not_found_t {};
1545
1546//
1547// find_first
1548//
1568[[nodiscard]]
1573{
1574 const auto it = std::find_if( where.begin(), where.end(),
1575 [&what]( const auto & pair ) {
1576 return restinio::impl::is_equal_caseless( pair.first, what );
1577 } );
1578 if( it != where.end() )
1579 return string_view_t{ it->second };
1580 else
1581 return make_unexpected( not_found_t{} );
1582}
1583
1584namespace impl
1585{
1586
1587namespace params_with_value_producer_details
1588{
1589
1590//
1591// make_parser
1592//
1599[[nodiscard]]
1600inline auto
1602{
1604 repeat( 0, N,
1606 ows(),
1607 symbol(';'),
1608 ows(),
1609 token_p() >> to_lower()
1610 >> &parameter_with_mandatory_value_t::first,
1611 symbol('='),
1613 token_p()
1614 >> &parameter_with_mandatory_value_t::second,
1616 >> &parameter_with_mandatory_value_t::second
1617 )
1618 ) >> to_container()
1619 )
1620 );
1621}
1622
1623} /* namespace params_with_value_producer_details */
1624
1625//
1626// params_with_value_producer_t
1627//
1635 : public producer_tag< parameter_with_mandatory_value_container_t >
1636{
1637 using actual_producer_t = std::decay_t<
1639
1642
1643public :
1645
1646 [[nodiscard]]
1647 auto
1649 {
1650 return m_producer.try_parse( from );
1651 }
1652};
1653
1654} /* namespace impl */
1655
1656//
1657// params_with_value_producer
1658//
1685[[nodiscard]]
1686inline impl::params_with_value_producer_t
1687params_with_value_p() { return {}; }
1688
1689//
1690// parameter_with_optional_value_t
1691//
1698 std::pair< std::string, std::optional<std::string> >;
1699
1700//
1701// parameter_with_optional_value_container_t
1702//
1709 std::vector< parameter_with_optional_value_t >;
1710
1711//
1712// find_first
1713//
1738[[nodiscard]]
1743{
1744 const auto it = std::find_if( where.begin(), where.end(),
1745 [&what]( const auto & pair ) {
1746 return restinio::impl::is_equal_caseless( pair.first, what );
1747 } );
1748 if( it != where.end() )
1749 {
1750 const auto opt = it->second;
1751 if( opt )
1752 return string_view_t{ *opt };
1753 else
1754 return std::optional< string_view_t >{ std::nullopt };
1755 }
1756 else
1757 return make_unexpected( not_found_t{} );
1758}
1759
1760namespace impl
1761{
1762
1763namespace params_with_opt_value_producer_details
1764{
1765
1766//
1767// make_parser
1768//
1775[[nodiscard]]
1776inline auto
1778{
1780 repeat( 0, N,
1782 ows(),
1783 symbol(';'),
1784 ows(),
1785 token_p() >> to_lower()
1786 >> &parameter_with_optional_value_t::first,
1787 maybe(
1788 symbol('='),
1790 token_p()
1791 >> &parameter_with_optional_value_t::second,
1793 >> &parameter_with_optional_value_t::second
1794 )
1795 )
1796 ) >> to_container()
1797 )
1798 );
1799}
1800
1801} /* namespace params_with_opt_value_producer_details */
1802
1803//
1804// params_with_opt_value_producer_t
1805//
1813 : public producer_tag< parameter_with_optional_value_container_t >
1814{
1815 using actual_producer_t = std::decay_t<
1817
1820
1821public :
1823
1824 [[nodiscard]]
1825 auto
1827 {
1828 return m_producer.try_parse( from );
1829 }
1830};
1831
1832} /* namespace impl */
1833
1834//
1835// params_with_opt_value_producer
1836//
1863[[nodiscard]]
1864inline impl::params_with_opt_value_producer_t
1866
1867} /* namespace http_field_parser */
1868
1869} /* namespace restinio */
1870
A helper class to automatically return acquired content back to the input stream.
The class that implements "input stream".
A template for producer of charachers that satisfy some predicate.
Information about parsing error.
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition basics.hpp:1129
A template for a producer that handles possibly empty list of comma-separated values.
Definition basics.hpp:1384
expected_t< result_type, parse_error_t > try_parse(source_t &from)
Definition basics.hpp:1400
A template for a producer that handles non-empty list of comma-separated values.
Definition basics.hpp:1320
expected_t< result_type, parse_error_t > try_parse(source_t &from)
Definition basics.hpp:1336
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
Definition basics.hpp:488
A type of producer that produces instances of parameter_with_optional_value_container.
Definition basics.hpp:1814
std::decay_t< decltype(params_with_opt_value_producer_details::make_parser()) > actual_producer_t
Definition basics.hpp:1815
A type of producer that produces instances of parameter_with_mandatory_value_container.
Definition basics.hpp:1636
std::decay_t< decltype(params_with_value_producer_details::make_parser()) > actual_producer_t
Definition basics.hpp:1637
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition basics.hpp:708
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition basics.hpp:655
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
Definition basics.hpp:598
A helper class to be used to accumulate actual integer while when the next digit is extracted from th...
Definition basics.hpp:1176
void consume(zero_initialized_unit_t &dest, char &&digit)
Definition basics.hpp:1185
An implementation of producer of qvalue.
Definition basics.hpp:1166
expected_t< result_type, parse_error_t > try_parse(source_t &from) const noexcept
Definition basics.hpp:1195
expected_t< result_type, parse_error_t > try_parse(source_t &from) const
Definition basics.hpp:570
static std::optional< parse_error_t > try_parse_value(source_t &from, std::string &accumulator)
Definition basics.hpp:528
static constexpr bool is_token_char(const char ch) noexcept
Definition basics.hpp:562
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:198
constexpr auto as_uint() const noexcept
Definition basics.hpp:206
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:194
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:202
qvalue_t(untrusted val) noexcept
Definition basics.hpp:190
friend std::ostream & operator<<(std::ostream &to, const qvalue_t &what)
Definition basics.hpp:214
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
An very small, simple and somewhat limited implementation of recursive-descent parser.
constexpr char HTAB
A constant for Horizontal Tab value.
constexpr char SP
A constant for SPACE value.
@ consumer
Entity is a consumer of values. It requires a value on the input and doesn't produces anything.
constexpr bool is_space(const char ch) noexcept
If a character a space character?
constexpr bool is_digit(const char ch) noexcept
Is a character a decimal digit?
auto digit_p() noexcept
A factory function to create a digit_producer.
auto to_container()
A factory function to create a to_container_consumer.
auto symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
auto digit() noexcept
A factory function to create a clause that expects a decimal digit, extracts it and then skips it.
auto as_result() noexcept
A factory function to create a as_result_consumer.
auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
auto skip() noexcept
A factory function to create a skip_consumer.
error_reason_t
Reason of parsing error.
auto symbol_p(char expected) noexcept
A factory function to create a symbol_producer.
auto to_lower() noexcept
A factory function to create a to_lower_transformer.
auto caseless_symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
auto not_clause(Clauses &&... clauses)
A factory function to create a not_clause.
auto caseless_exact_p(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment_producer.
constexpr std::size_t N
A special marker that means infinite repetitions.
auto exact_p(string_view_t fragment)
A factory function that creates an instance of exact_fragment_producer.
auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
auto custom_consumer(F consumer)
A factory function to create a custom_consumer.
auto make_parser()
Helper function that creates an instance of producer of parameter_with_optional_value_container.
Definition basics.hpp:1777
auto make_parser()
Helper function that creates an instance of producer of parameter_with_mandatory_value_container.
Definition basics.hpp:1601
constexpr bool is_qdtext(const char ch) noexcept
Is a character a qdtext?
Definition basics.hpp:380
constexpr bool is_ctext(const char ch) noexcept
Is a character a ctext?
Definition basics.hpp:402
constexpr bool is_obs_text(const char ch) noexcept
Is a character an obs_text?
Definition basics.hpp:357
constexpr bool is_vchar(const char ch) noexcept
Is a character a VCHAR?
Definition basics.hpp:321
constexpr bool is_alpha(const char ch) noexcept
Is a character an ALPHA?
Definition basics.hpp:265
std::uint_least16_t underlying_uint_t
A type to hold a qvalue.
Definition basics.hpp:36
constexpr underlying_uint_t zero
The minimal allowed value for a qvalue.
Definition basics.hpp:41
constexpr underlying_uint_t maximum
The maximal allowed value for a qvalue.
Definition basics.hpp:39
impl::params_with_value_producer_t params_with_value_p()
A factory of producer of parameter_with_mandatory_value_container.
Definition basics.hpp:1687
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:1505
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:1570
auto vchar_symbol_p()
A factory for producer of VCHAR symbols.
Definition basics.hpp:834
auto qvalue_p() noexcept
A factory function to create a qvalue_producer.
Definition basics.hpp:1252
auto ows_p() noexcept
A factory function to create an ows_producer.
Definition basics.hpp:911
auto token_p() noexcept
A factory function to create a token_producer.
Definition basics.hpp:987
auto ctext_symbol_p()
A factory for producer of ctext symbols.
Definition basics.hpp:856
bool operator==(const qvalue_t &a, const qvalue_t &b) noexcept
Definition basics.hpp:222
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:1075
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:1459
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:1708
auto alpha_symbol_p()
A factory for producer of ALPHA symbols.
Definition basics.hpp:790
auto token_symbol_p() noexcept
A factory for producer of symbols than can be used in tokens.
Definition basics.hpp:959
bool operator!=(const qvalue_t &a, const qvalue_t &b) noexcept
Definition basics.hpp:229
std::pair< std::string, std::optional< std::string > > parameter_with_optional_value_t
A type that describes a parameter with optional value.
Definition basics.hpp:1697
auto alphanum_symbol_p()
A factory for producer of symbol that an ALPHA or DIGIT.
Definition basics.hpp:812
bool operator<=(const qvalue_t &a, const qvalue_t &b) noexcept
Definition basics.hpp:243
auto weight_p() noexcept
A factory function to create a producer for weight parameter.
Definition basics.hpp:1279
auto ows() noexcept
A factory function to create an OWS clause.
Definition basics.hpp:941
std::pair< std::string, std::string > parameter_with_mandatory_value_t
A type that describes a parameter with mandatory value.
Definition basics.hpp:1523
auto quoted_pair_p() noexcept
A factory function to create a quoted_pair_producer.
Definition basics.hpp:1040
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:1865
bool operator<(const qvalue_t &a, const qvalue_t &b) noexcept
Definition basics.hpp:236
auto quoted_string_p() noexcept
A factory function to create a quoted_string_producer.
Definition basics.hpp:1014
auto comment_p()
A factory for producer of comment token.
Definition basics.hpp:882
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:1114
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:1533
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
std::string_view string_view_t
nonstd::expected< T, E > expected_t
Definition expected.hpp:18
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:281
bool operator()(const char actual) const noexcept
Definition basics.hpp:284
A preducate for symbol_producer_template that checks that a symbol is an alpha or numeric.
Definition basics.hpp:300
bool operator()(const char actual) const noexcept
Definition basics.hpp:303
A preducate for symbol_producer_template that checks that a symbol is a ctext.
Definition basics.hpp:422
bool operator()(const char actual) const noexcept
Definition basics.hpp:425
A predicate for symbol_producer_template that checks that a symbol can be used inside a token.
Definition basics.hpp:439
static constexpr bool is_token_char(const char ch) noexcept
Definition basics.hpp:442
bool operator()(const char actual) const noexcept
Definition basics.hpp:464
A preducate for symbol_producer_template that checks that a symbol is a VCHAR.
Definition basics.hpp:336
bool operator()(const char actual) const noexcept
Definition basics.hpp:339
An empty type to be used as indicator of negative search result.
Definition basics.hpp:1544