RESTinio

easy_parser.hpp
Go to the documentation of this file.
1/*
2 * RESTinio
3 */
4
13#pragma once
14
15#include <restinio/impl/to_lower_lut.hpp>
16#include <restinio/impl/overflow_controlled_integer_accumulator.hpp>
17
18#include <restinio/utils/tuple_algorithms.hpp>
19#include <restinio/utils/metaprogramming.hpp>
20
21#include <restinio/string_view.hpp>
22#include <restinio/compiler_features.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
41 namespace meta = restinio::utils::metaprogramming;
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
81 force_only_this_alternative_failed
82};
83
84//
85// parse_error_t
86//
92 class parse_error_t
93{
95 std::size_t m_position;
97 error_reason_t m_reason;
98
99 public:
101 parse_error_t(
102 std::size_t position,
103 error_reason_t reason ) noexcept
104 : m_position{ position }
105 , m_reason{ reason }
106 {}
107
109 RESTINIO_NODISCARD
110 std::size_t
111 position() const noexcept { return m_position; }
112
114 RESTINIO_NODISCARD
115 error_reason_t
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 >
179 struct result_value_wrapper
180{
181 using result_type = T;
182 using wrapped_type = result_type;
183
184 static void
185 as_result( wrapped_type & to, result_type && what )
186 {
187 to = std::move(what);
188 }
189
190 RESTINIO_NODISCARD
191 static result_type &&
192 unwrap_value( wrapped_type & v )
193 {
194 return std::move(v);
195 }
196};
197
198//
199// result_wrapper_for
200//
243 template< typename T >
244 struct result_wrapper_for
245{
246 using type = result_value_wrapper< T >;
247};
248
249 template< typename T >
250 using result_wrapper_for_t = typename result_wrapper_for<T>::type;
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;
257 using wrapped_type = result_type;
258
259 static void
260 as_result( wrapped_type & to, result_type && what )
261 {
262 to = std::move(what);
263 }
264
265 static void
266 to_container( wrapped_type & to, value_type && what )
267 {
268 to.push_back( std::move(what) );
269 }
270
271 RESTINIO_NODISCARD
272 static result_type &&
273 unwrap_value( wrapped_type & v )
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 >
298 struct std_array_wrapper
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;
311 using wrapped_type = impl::std_array_wrapper< T, S >;
312
313 static void
314 as_result( wrapped_type & to, result_type && what )
315 {
316 to.m_array = std::move(what);
317 to.m_index = 0u;
318 }
319
320 static void
321 to_container( wrapped_type & to, value_type && what )
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
333 RESTINIO_NODISCARD
334 static result_type &&
335 unwrap_value( wrapped_type & v )
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{
350 using type = result_value_wrapper< std::array< T, S > >;
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;
358 using wrapped_type = result_type;
359
360 static void
361 as_result( wrapped_type & to, result_type && what )
362 {
363 to = std::move(what);
364 }
365
366 static void
367 to_container( wrapped_type & to, value_type && what )
368 {
369 to.push_back( what );
370 }
371
385 static void
386 to_container( wrapped_type & to, wrapped_type && what )
387 {
388 to.append( what );
389 }
390
391 RESTINIO_NODISCARD
392 static result_type &&
393 unwrap_value( wrapped_type & v )
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>;
407 using wrapped_type = result_type;
408
409 static void
410 as_result( wrapped_type & to, result_type && what )
411 {
412 to = std::move(what);
413 }
414
415 static void
416 to_container( wrapped_type & to, value_type && what )
417 {
418 to.emplace( std::move(what) );
419 }
420
421 RESTINIO_NODISCARD
422 static result_type &&
423 unwrap_value( wrapped_type & v )
424 {
425 return std::move(v);
426 }
427};
428
429 template<>
430 struct result_value_wrapper< nothing_t >
431{
432 using result_type = nothing_t;
433 using value_type = nothing_t;
434 using wrapped_type = result_type;
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
442 RESTINIO_NODISCARD
443 static result_type &&
444 unwrap_value( wrapped_type & v )
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//
466 class digits_to_consume_t
467{
468 public:
469 using underlying_int_t = std::int_fast8_t;
470
472
477 underlying_int_t m_min;
479 underlying_int_t m_max;
480
481 public:
486 constexpr
487 digits_to_consume_t( underlying_int_t total ) noexcept
488 : m_min{ total }
489 , m_max{ total }
490 {}
491
496 constexpr
497 digits_to_consume_t(
498 underlying_int_t min,
499 underlying_int_t max ) noexcept
500 : m_min{ min }
501 , m_max{ max }
502 {}
503
505 RESTINIO_NODISCARD
506 constexpr auto
507 min() const noexcept { return m_min; }
508
510 RESTINIO_NODISCARD
511 constexpr auto
512 max() const noexcept { return m_max; }
513
515 RESTINIO_NODISCARD
516 constexpr static auto
517 unlimited_max() noexcept
518 {
519 return std::numeric_limits<underlying_int_t>::max();
520 }
521
525 RESTINIO_NODISCARD
526 constexpr static auto
527 from_one_to_max() noexcept
528 {
529 return digits_to_consume_t{ 1, unlimited_max() };
530 }
531};
532
547 RESTINIO_NODISCARD
548 inline constexpr digits_to_consume_t
549 expected_digits( digits_to_consume_t::underlying_int_t total ) noexcept
550{
551 return { total };
552}
553
568 RESTINIO_NODISCARD
569 inline constexpr digits_to_consume_t
570 expected_digits(
571 digits_to_consume_t::underlying_int_t min,
572 digits_to_consume_t::underlying_int_t max ) noexcept
573{
574 return { min, max };
575}
576
577 namespace impl
578{
579
580//
581// character_t
582//
592 struct character_t
593{
594 bool m_eof;
595 char m_ch;
596};
597
598 RESTINIO_NODISCARD
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
605 RESTINIO_NODISCARD
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//
633 RESTINIO_NODISCARD
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//
649 struct is_space_predicate_t
650{
651 RESTINIO_NODISCARD
652 bool
653 operator()( const char actual ) const noexcept
654 {
655 return is_space(actual);
656 }
657};
658
659//
660// is_digit
661//
667 RESTINIO_NODISCARD
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//
682 struct is_digit_predicate_t
683{
684 RESTINIO_NODISCARD
685 bool
686 operator()( const char actual ) const noexcept
687 {
688 return is_digit( actual );
689 }
690};
691
692//
693// is_hexdigit
694//
700 RESTINIO_NODISCARD
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//
718 struct is_hexdigit_predicate_t
719{
720 RESTINIO_NODISCARD
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{
742 const string_view_t m_data;
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
763 RESTINIO_NODISCARD
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
784 RESTINIO_NODISCARD
785 position_t
786 current_position() const noexcept
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
801 RESTINIO_NODISCARD
802 bool
803 eof() const noexcept
804 {
805 return m_index >= m_data.size();
806 }
807
809
814 RESTINIO_NODISCARD
815 string_view_t
816 fragment(
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
850 class content_consumer_t
851 {
852 source_t & m_from;
853 const position_t m_started_at;
854 bool m_consumed{ false };
855
856 public :
857 content_consumer_t() = delete;
858 content_consumer_t( const content_consumer_t & ) = delete;
859 content_consumer_t( 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
866 ~content_consumer_t() noexcept
867 {
868 if( !m_consumed )
869 m_from.backto( m_started_at );
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
916 transformer_proxy
917};
918
919//
920// producer_tag
921//
943 template< typename Result_Type >
944 struct producer_tag
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 >
970 constexpr bool is_producer_v = is_producer<T>::value;
971
972//
973// transformer_tag
974//
997 template< typename Result_Type >
998 struct transformer_tag
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 >
1024 constexpr bool is_transformer_v = is_transformer<T>::value;
1025
1026//
1027// transformer_invoker
1028//
1046 template< typename Result_Type >
1047 struct transformer_invoker
1048{
1049 template< typename Transformer, typename Input_Type >
1050 RESTINIO_NODISCARD
1051 static Result_Type
1052 invoke(
1053 source_t &,
1054 Transformer & transformer,
1055 expected_t< Input_Type, parse_error_t > && input )
1056 {
1057 return transformer.transform( std::move(*input) );
1058 }
1059};
1060
1067 template< typename Result_Type >
1068 struct transformer_invoker< expected_t< Result_Type, error_reason_t > >
1069{
1070 template< typename Transformer, typename Input_Type >
1071 RESTINIO_NODISCARD
1072 static expected_t< Result_Type, parse_error_t >
1073 invoke(
1074 // source_t is necessary to get the position in the case of an error.
1075 source_t & source,
1076 Transformer & transformer,
1077 expected_t< Input_Type, parse_error_t > && input )
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 >
1110 struct is_appropriate_transformer_result_type
1111{
1112 static constexpr bool value = true;
1113};
1114
1115 template< typename Result_Type >
1116 struct is_appropriate_transformer_result_type<
1117 expected_t< Result_Type, error_reason_t > >
1118{
1119 static constexpr bool value = true;
1120};
1121
1122 template< typename Result_Type >
1123 struct is_appropriate_transformer_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 >
1144 struct transformed_value_producer_traits_checker
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 =
1163 is_appropriate_transformer_result_type< expected_result_t >::value;
1164};
1165
1166//
1167// transformed_value_producer_t
1168//
1178 template< typename Producer, typename Transformer >
1179 class transformed_value_producer_t
1180 : public producer_tag< typename Transformer::result_type >
1181{
1182 using traits_checker = transformed_value_producer_traits_checker<
1183 Producer, Transformer >;
1184
1185 static_assert(
1186 traits_checker::is_valid_transformation_result_type,
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
1193public :
1194 using result_type = typename Transformer::result_type;
1195
1196 transformed_value_producer_t(
1197 Producer && producer,
1198 Transformer && transformer )
1199 : m_producer{ std::move(producer) }
1200 , m_transformer{ std::move(transformer) }
1201 {}
1202
1203 RESTINIO_NODISCARD
1204 expected_t< result_type, parse_error_t >
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 =
1211 typename traits_checker::transformation_result_t;
1212
1213 return transformer_invoker< transformation_result_t >::invoke(
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 >
1229 RESTINIO_NODISCARD
1230std::enable_if_t<
1231 is_producer_v<P> & is_transformer_v<T>,
1232 transformed_value_producer_t< P, T > >
1233 operator>>(
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//
1266 struct transformer_proxy_tag
1267{
1268 static constexpr entity_type_t entity_type = entity_type_t::transformer_proxy;
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 >
1290 constexpr bool is_transformer_proxy_v = is_transformer_proxy<T>::value;
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 > >
1304 RESTINIO_NODISCARD
1305 auto
1306 operator>>(
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
1315 using producer_type = transformed_value_producer_t< P, transformator_type >;
1316
1317 return producer_type{ std::move(producer), std::move(real_transformer) };
1318}
1319
1320//
1321// consumer_tag
1322//
1342 struct consumer_tag
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 >
1367 constexpr bool is_consumer_v = is_consumer<T>::value;
1368
1369//
1370// clause_tag
1371//
1392 struct clause_tag
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 >
1420 constexpr bool is_clause_v = is_clause<T>::value;
1421
1422//
1423// tuple_of_entities_t
1424//
1455 template< typename... Entities >
1456 using tuple_of_entities_t = meta::rename_t<
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 >
1473 class consume_value_clause_t : public clause_tag
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
1478 P m_producer;
1479 C m_consumer;
1480
1481public :
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 >
1488 RESTINIO_NODISCARD
1489 optional_t< parse_error_t >
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 >
1509 RESTINIO_NODISCARD
1510std::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 >
1532 class top_level_clause_t
1533{
1534 static_assert( is_producer_v<Producer>,
1535 "Producer should be a producer type" );
1536
1537 Producer m_producer;
1538
1539public :
1540 top_level_clause_t( Producer && producer )
1541 : m_producer{ std::move(producer) }
1542 {}
1543
1544 RESTINIO_NODISCARD
1545 auto
1546 try_process( source_t & from )
1547 {
1548 return m_producer.try_parse( from );
1549 }
1550};
1551
1552//
1553// ensure_no_remaining_content
1554//
1564 RESTINIO_NODISCARD
1565 inline optional_t< parse_error_t >
1566 ensure_no_remaining_content(
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//
1592 RESTINIO_NODISCARD
1593 inline string_view_t
1594 remove_trailing_spaces( string_view_t from ) noexcept
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 >
1635 class alternatives_clause_t : public clause_tag
1636{
1637 Subitems_Tuple m_subitems;
1638
1639public :
1640 alternatives_clause_t(
1641 Subitems_Tuple && subitems )
1642 : m_subitems{ std::move(subitems) }
1643 {}
1644
1645 template< typename Target_Type >
1646 RESTINIO_NODISCARD
1647 optional_t< parse_error_t >
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.
1672 return error_reason_t::force_only_this_alternative_failed ==
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 >
1716 class maybe_clause_t : public clause_tag
1717{
1718 Subitems_Tuple m_subitems;
1719
1720public :
1721 maybe_clause_t(
1722 Subitems_Tuple && subitems )
1723 : m_subitems{ std::move(subitems) }
1724 {}
1725
1726 template< typename Target_Type >
1727 RESTINIO_NODISCARD
1728 optional_t< parse_error_t >
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
1783public :
1784 not_clause_t(
1785 Subitems_Tuple && subitems )
1786 : m_subitems{ std::move(subitems) }
1787 {}
1788
1789 template< typename Target_Type >
1790 RESTINIO_NODISCARD
1791 optional_t< parse_error_t >
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
1851public :
1852 and_clause_t(
1853 Subitems_Tuple && subitems )
1854 : m_subitems{ std::move(subitems) }
1855 {}
1856
1857 template< typename Target_Type >
1858 RESTINIO_NODISCARD
1859 optional_t< parse_error_t >
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 >
1908 class sequence_clause_t : public clause_tag
1909{
1910 Subitems_Tuple m_subitems;
1911
1912public :
1913 sequence_clause_t(
1914 Subitems_Tuple && subitems )
1915 : m_subitems{ std::move(subitems) }
1916 {}
1917
1918 template< typename Target_Type >
1919 RESTINIO_NODISCARD
1920 optional_t< parse_error_t >
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.
1927 optional_t< parse_error_t > result;
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{
1963 using base_type_t = sequence_clause_t< Subitems_Tuple >;
1964
1965public :
1966 using base_type_t::base_type_t;
1967
1968 template< typename Target_Type >
1969 RESTINIO_NODISCARD
1970 optional_t< parse_error_t >
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,
1981 error_reason_t::force_only_this_alternative_failed
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{
2011 using value_wrapper_t = result_value_wrapper< Target_Type >;
2012
2013 Subitems_Tuple m_subitems;
2014
2015public :
2016 produce_t(
2017 Subitems_Tuple && subitems )
2018 : m_subitems{ std::move(subitems) }
2019 {}
2020
2021 RESTINIO_NODISCARD
2022 expected_t< Target_Type, parse_error_t >
2023 try_parse( source_t & from )
2024 {
2025 typename value_wrapper_t::wrapped_type tmp_value{};
2026 optional_t< parse_error_t > error;
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 >
2060 class repeat_clause_t : public clause_tag
2061{
2062 std::size_t m_min_occurences;
2063 std::size_t m_max_occurences;
2064
2065 Subitems_Tuple m_subitems;
2066
2067public :
2068 repeat_clause_t(
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 >
2078 RESTINIO_NODISCARD
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 >
2130 class symbol_producer_template_t
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
2140 RESTINIO_NODISCARD
2141 expected_t< char, parse_error_t >
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//
2178 struct any_symbol_predicate_t
2179{
2180 RESTINIO_NODISCARD
2181 constexpr bool
2182 operator()( const char ) const noexcept
2183 {
2184 return true;
2185 }
2186};
2187
2188//
2189// particular_symbol_predicate_t
2190//
2197 struct particular_symbol_predicate_t
2198{
2199 char m_expected;
2200
2201 RESTINIO_NODISCARD
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//
2218 struct not_particular_symbol_predicate_t
2219{
2220 char m_sentinel;
2221
2222 RESTINIO_NODISCARD
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//
2239 struct caseless_particular_symbol_predicate_t
2240{
2241 char m_expected;
2242
2243 caseless_particular_symbol_predicate_t( char v ) noexcept
2244 : m_expected{ restinio::impl::to_lower_case( v ) }
2245 {}
2246
2247 RESTINIO_NODISCARD
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//
2266 struct symbol_from_range_predicate_t
2267{
2268 char m_left;
2269 char m_right;
2270
2271 RESTINIO_NODISCARD
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//
2290 class symbol_producer_t
2291 : public symbol_producer_template_t< particular_symbol_predicate_t >
2292{
2293 using base_type_t =
2294 symbol_producer_template_t< particular_symbol_predicate_t >;
2295
2296 public:
2297 symbol_producer_t( char expected )
2298 : base_type_t{ particular_symbol_predicate_t{expected} }
2299 {}
2300};
2301
2302//
2303// any_symbol_if_not_producer_t
2304//
2313 class any_symbol_if_not_producer_t
2314 : public symbol_producer_template_t< not_particular_symbol_predicate_t >
2315{
2316 using base_type_t =
2317 symbol_producer_template_t< not_particular_symbol_predicate_t >;
2318
2319 public:
2320 any_symbol_if_not_producer_t( char sentinel )
2321 : base_type_t{ not_particular_symbol_predicate_t{sentinel} }
2322 {}
2323};
2324
2325//
2326// caseless_symbol_producer_t
2327//
2339 class caseless_symbol_producer_t
2340 : public symbol_producer_template_t< caseless_particular_symbol_predicate_t >
2341{
2342 using base_type_t =
2343 symbol_producer_template_t< caseless_particular_symbol_predicate_t >;
2344
2345 public:
2346 caseless_symbol_producer_t( char expected )
2347 : base_type_t{ caseless_particular_symbol_predicate_t{expected} }
2348 {}
2349};
2350
2351//
2352// symbol_from_range_producer_t
2353//
2362 class symbol_from_range_producer_t
2363 : public symbol_producer_template_t< symbol_from_range_predicate_t >
2364{
2365 using base_type_t =
2366 symbol_producer_template_t< symbol_from_range_predicate_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//
2385 class digit_producer_t
2386 : public symbol_producer_template_t< is_digit_predicate_t >
2387{
2388 public:
2389 digit_producer_t() {}
2390};
2391
2392//
2393// hexdigit_producer_t
2394//
2403 class hexdigit_producer_t
2404 : public symbol_producer_template_t< is_hexdigit_predicate_t >
2405{
2406 public:
2407 hexdigit_producer_t() {}
2408};
2409
2410//
2411// try_parse_digits_with_digits_limit
2412//
2434 template< typename T, typename Value_Accumulator >
2435 RESTINIO_NODISCARD
2436 expected_t< T, parse_error_t >
2437 try_parse_digits_with_digits_limit(
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 >
2499 RESTINIO_NODISCARD
2500 expected_t< T, parse_error_t >
2501 try_parse_hexdigits_with_digits_limit(
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 >
2570 class non_negative_decimal_number_producer_t : public producer_tag< T >
2571{
2572 public:
2573 RESTINIO_NODISCARD
2574 expected_t< T, parse_error_t >
2575 try_parse( source_t & from ) const noexcept
2576 {
2577 return try_parse_digits_with_digits_limit< T >(
2578 from,
2579 digits_to_consume_t::from_one_to_max(),
2580 restinio::impl::overflow_controlled_integer_accumulator_t<T, 10>{} );
2581 }
2582};
2583
2584//
2585// non_negative_decimal_number_producer_with_digits_limit_t
2586//
2597 template< typename T >
2598 class non_negative_decimal_number_producer_with_digits_limit_t
2599 : public non_negative_decimal_number_producer_t<T>
2600{
2601 digits_to_consume_t m_digits_limit;
2602
2603 public:
2604 non_negative_decimal_number_producer_with_digits_limit_t(
2605 digits_to_consume_t digits_limit )
2606 : m_digits_limit{ digits_limit }
2607 {}
2608
2609 RESTINIO_NODISCARD
2610 expected_t< T, parse_error_t >
2611 try_parse( source_t & from ) const noexcept
2612 {
2613 return try_parse_digits_with_digits_limit< T >(
2614 from,
2615 m_digits_limit,
2616 restinio::impl::overflow_controlled_integer_accumulator_t<T, 10>{} );
2617 }
2618};
2619
2620//
2621// hexadecimal_number_producer_t
2622//
2631 template< typename T >
2632 class hexadecimal_number_producer_t : public producer_tag< T >
2633{
2634 static_assert( std::is_unsigned<T>::value,
2635 "T is expected to be unsigned type" );
2636
2637 public:
2638 RESTINIO_NODISCARD
2639 expected_t< T, parse_error_t >
2640 try_parse( source_t & from ) const noexcept
2641 {
2642 return try_parse_hexdigits_with_digits_limit< T >(
2643 from,
2644 digits_to_consume_t::from_one_to_max(),
2645 restinio::impl::overflow_controlled_integer_accumulator_t<T, 16>{} );
2646 }
2647};
2648
2649//
2650// hexadecimal_number_producer_with_digits_limit_t
2651//
2662 template< typename T >
2663 class hexadecimal_number_producer_with_digits_limit_t
2664 : public hexadecimal_number_producer_t< T >
2665{
2666 digits_to_consume_t m_digits_limit;
2667
2668 public:
2669 hexadecimal_number_producer_with_digits_limit_t(
2670 digits_to_consume_t digits_limit )
2671 : m_digits_limit{ digits_limit }
2672 {}
2673
2674 RESTINIO_NODISCARD
2675 expected_t< T, parse_error_t >
2676 try_parse( source_t & from ) const noexcept
2677 {
2678 return try_parse_hexdigits_with_digits_limit< T >(
2679 from,
2680 m_digits_limit,
2681 restinio::impl::overflow_controlled_integer_accumulator_t<T, 16>{} );
2682 }
2683};
2684
2685//
2686// decimal_number_producer_t
2687//
2696 template< typename T >
2697 class decimal_number_producer_t : public producer_tag<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:
2703 using try_parse_result_type = expected_t< T, parse_error_t >;
2704
2705 RESTINIO_NODISCARD
2706 try_parse_result_type
2707 try_parse( source_t & from ) const noexcept
2708 {
2709 return try_parse_impl( from,
2710 []() noexcept {
2711 return digits_to_consume_t::from_one_to_max();
2712 } );
2713 }
2714
2715 protected:
2716 template< typename Digits_Limit_Maker >
2717 RESTINIO_NODISCARD
2718 try_parse_result_type
2719 try_parse_impl(
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 >
2747 RESTINIO_NODISCARD
2748 static try_parse_result_type
2749 try_parse_with_this_first_symbol(
2750 source_t & from,
2751 char first_symbol,
2752 Digits_Limit_Maker && digits_limit_maker ) noexcept
2753 {
2754 using restinio::impl::overflow_controlled_integer_accumulator_t;
2755 using restinio::impl::check_negative_extremum;
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 >
2810 class decimal_number_producer_with_digits_limit_t
2811 : public decimal_number_producer_t< T >
2812{
2813 digits_to_consume_t m_digits_limit;
2814
2815 public:
2816 decimal_number_producer_with_digits_limit_t(
2817 digits_to_consume_t digits_limit )
2818 : m_digits_limit{ digits_limit }
2819 {}
2820
2821 RESTINIO_NODISCARD
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//
2842 struct any_value_skipper_t : public consumer_tag
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//
2869 struct as_result_consumer_t : public consumer_tag
2870{
2871 template< typename Target_Type, typename Value >
2872 void
2873 consume( Target_Type & dest, Value && src ) const
2874 {
2875 result_wrapper_for_t<Target_Type>::as_result(
2876 dest, std::forward<Value>(src) );
2877 }
2878};
2879
2880//
2881// just_result_consumer_t
2882//
2890 template< typename Result_Type >
2891 class just_result_consumer_t : public consumer_tag
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
2902 make_copy_of_result() const
2903 noexcept(noexcept(Result_Type{m_result}))
2904 {
2905 return m_result;
2906 }
2907
2908public :
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 {
2919 result_wrapper_for_t<Target_Type>::as_result(
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 >
2939 class custom_consumer_t : public consumer_tag
2940{
2941 C m_consumer;
2942
2943public :
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 >
2968 class field_setter_consumer_t : public consumer_tag
2969{
2970 using pointer_t = F C::*;
2971
2972 pointer_t m_ptr;
2973
2974public :
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 >
2998 RESTINIO_NODISCARD
2999std::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 >
3020 struct tuple_item_consumer_t : public consumer_tag
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 >
3041 struct to_lower_transformer_t;
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
3055 RESTINIO_NODISCARD
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<>
3076 struct to_lower_transformer_t< char >
3077 : public transformer_tag< char >
3078{
3079 using input_type = char;
3080
3081 RESTINIO_NODISCARD
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 >;
3100 using base_type = transformer_tag< input_type >;
3101
3102 RESTINIO_NODISCARD
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//
3124 struct to_lower_transformer_proxy_t : public transformer_proxy_tag
3125{
3126 template< typename Input_Type >
3127 RESTINIO_NODISCARD
3128 auto
3129 make_transformer() const noexcept
3130 {
3131 return to_lower_transformer_t< Input_Type >{};
3132 }
3133};
3134
3135//
3136// just_value_transformer_t
3137//
3144 template< typename T >
3145 class just_value_transformer_t : public transformer_tag< T >
3146{
3147 T m_value;
3148
3149public :
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 >
3155 RESTINIO_NODISCARD
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
3177public :
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 >
3193 RESTINIO_NODISCARD
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(
3203 is_appropriate_transformer_result_type<actual_result_t>::value,
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 >
3225 struct conversion_result_type_detector
3226{
3227 using type = Result_Type;
3228};
3229
3230 template< typename Result_Type >
3231 struct conversion_result_type_detector< expected_t< Result_Type, error_reason_t > >
3232{
3233 using type = Result_Type;
3234};
3235
3241 template< typename Result_Type >
3242 using conversion_result_type_detector_t =
3243 typename conversion_result_type_detector<Result_Type>::type;
3244
3245//
3246// convert_transformer_proxy_t
3247//
3261 template< typename Converter >
3262 class convert_transformer_proxy_t : public transformer_proxy_tag
3263{
3264 template< typename Input_Type >
3265 using output = conversion_result_type_detector_t<
3266 std::decay_t< decltype(
3267 std::declval<Converter &>()(std::declval<Input_Type&&>())
3268 ) >
3269 >;
3270
3271 Converter m_converter;
3272
3273public :
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 >
3281 RESTINIO_NODISCARD
3282 auto
3283 make_transformer() const &
3284 noexcept(noexcept(Converter{m_converter}))
3285 {
3286 using output_t = output<Input_Type>;
3287
3288 return convert_transformer_t< output_t, Converter >{ m_converter };
3289 }
3290
3291 template< typename Input_Type >
3292 RESTINIO_NODISCARD
3293 auto
3294 make_transformer() &&
3295 noexcept(noexcept(Converter{std::move(m_converter)}))
3296 {
3297 using output_t = output<Input_Type>;
3298
3299 return convert_transformer_t< output_t, Converter >{
3300 std::move(m_converter)
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 >
3311 RESTINIO_NODISCARD
3312expected_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 >
3354 class exact_fixed_size_fragment_producer_t
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
3369 RESTINIO_NODISCARD
3370 expected_t< bool, parse_error_t >
3371 try_parse( source_t & from )
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//
3387 class exact_fragment_producer_t
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
3401 RESTINIO_NODISCARD
3402 expected_t< bool, parse_error_t >
3403 try_parse( source_t & from )
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 >
3417 RESTINIO_NODISCARD
3418 expected_t< bool, parse_error_t >
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 >
3462 class caseless_exact_fixed_size_fragment_producer_t
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:
3471 caseless_exact_fixed_size_fragment_producer_t( const char (&f)[Size] )
3472 {
3473 // Content should be converted to lower-case.
3474 // NOTE: last zero-byte is discarded.
3475 std::transform(
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
3483 RESTINIO_NODISCARD
3484 expected_t< bool, parse_error_t >
3485 try_parse( source_t & from )
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//
3503 class caseless_exact_fragment_producer_t
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
3521 RESTINIO_NODISCARD
3522 expected_t< bool, parse_error_t >
3523 try_parse( source_t & from )
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 >
3552 RESTINIO_NODISCARD
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 >
3593 RESTINIO_NODISCARD
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 >
3632 RESTINIO_NODISCARD
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 >
3674 RESTINIO_NODISCARD
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 >
3716 RESTINIO_NODISCARD
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 >
3756 RESTINIO_NODISCARD
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 >
3819 RESTINIO_NODISCARD
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 >
3874 RESTINIO_NODISCARD
3875 auto
3876 repeat(
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//
3920 RESTINIO_NODISCARD
3921 inline auto
3922 skip() noexcept { return impl::any_value_skipper_t{}; }
3923
3924//
3925// any_symbol_p
3926//
3935 RESTINIO_NODISCARD
3936 inline auto
3937 any_symbol_p() noexcept
3938{
3939 return impl::symbol_producer_template_t<impl::any_symbol_predicate_t>{};
3940}
3941
3942//
3943// symbol_p
3944//
3953 RESTINIO_NODISCARD
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//
3971 RESTINIO_NODISCARD
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//
3991 RESTINIO_NODISCARD
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//
4009 RESTINIO_NODISCARD
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//
4030 RESTINIO_NODISCARD
4031 inline auto
4032 symbol( char expected ) noexcept
4033{
4034 return symbol_p(expected) >> skip();
4035}
4036
4037//
4038// caseless_symbol
4039//
4053 RESTINIO_NODISCARD
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//
4074 RESTINIO_NODISCARD
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//
4092 RESTINIO_NODISCARD
4093 inline auto
4094 space_p() noexcept
4095{
4096 return impl::symbol_producer_template_t< impl::is_space_predicate_t >{};
4097}
4098
4099//
4100// space
4101//
4113 RESTINIO_NODISCARD
4114 inline auto
4115 space() noexcept
4116{
4117 return space_p() >> skip();
4118}
4119
4120//
4121// digit_p
4122//
4131 RESTINIO_NODISCARD
4132 inline auto
4133 digit_p() noexcept
4134{
4135 return impl::digit_producer_t{};
4136}
4137
4138//
4139// digit
4140//
4152 RESTINIO_NODISCARD
4153 inline auto
4154 digit() noexcept
4155{
4156 return digit_p() >> skip();
4157}
4158
4159//
4160// hexdigit_p
4161//
4170 RESTINIO_NODISCARD
4171 inline auto
4172 hexdigit_p() noexcept
4173{
4174 return impl::hexdigit_producer_t{};
4175}
4176
4177//
4178// hexdigit
4179//
4191 RESTINIO_NODISCARD
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 >
4216 RESTINIO_NODISCARD
4217 inline auto
4218 non_negative_decimal_number_p() noexcept
4219{
4220 return impl::non_negative_decimal_number_producer_t<T>{};
4221}
4222
4223//
4224// non_negative_decimal_number_p
4225//
4254 template< typename T >
4255 RESTINIO_NODISCARD
4256 inline auto
4257 non_negative_decimal_number_p( digits_to_consume_t digits_limit ) noexcept
4258{
4259 return impl::non_negative_decimal_number_producer_with_digits_limit_t<T>{
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
4279 positive_decimal_number_producer() noexcept
4280{
4281 return non_negative_decimal_number_p<T>();
4282}
4283
4284//
4285// hexadecimal_number_p
4286//
4304 template< typename T >
4305 RESTINIO_NODISCARD
4306 inline auto
4307 hexadecimal_number_p() noexcept
4308{
4309 return impl::hexadecimal_number_producer_t<T>{};
4310}
4311
4312//
4313// hexadecimal_number_p
4314//
4346 template< typename T >
4347 RESTINIO_NODISCARD
4348 inline auto
4349 hexadecimal_number_p( digits_to_consume_t digits_limit ) noexcept
4350{
4351 return impl::hexadecimal_number_producer_with_digits_limit_t<T>{
4352 digits_limit
4353 };
4354}
4355
4356//
4357// decimal_number_p
4358//
4384 template< typename T >
4385 RESTINIO_NODISCARD
4386 inline auto
4387 decimal_number_p() noexcept
4388{
4389 static_assert( std::is_signed<T>::value,
4390 "decimal_number_p() can be used only for signed numeric types" );
4391
4392 return impl::decimal_number_producer_t<T>{};
4393}
4394
4395//
4396// decimal_number_p
4397//
4437 template< typename T >
4438 RESTINIO_NODISCARD
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
4445 return impl::decimal_number_producer_with_digits_limit_t<T>{
4446 digits_limit
4447 };
4448}
4449
4450//
4451// as_result
4452//
4468 RESTINIO_NODISCARD
4469 inline auto
4470 as_result() noexcept { return impl::as_result_consumer_t{}; }
4471
4472//
4473// custom_consumer
4474//
4513 template< typename F >
4514 RESTINIO_NODISCARD
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//
4540 struct to_container_consumer_t : public consumer_tag
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>;
4547 container_adaptor_type::to_container( to, std::move(item) );
4548 }
4549};
4550
4551} /* namespace impl */
4552
4553//
4554// to_container
4555//
4581 RESTINIO_NODISCARD
4582 inline auto
4583 to_container()
4584{
4585 return impl::to_container_consumer_t();
4586}
4587
4588//
4589// to_lower
4590//
4608 RESTINIO_NODISCARD
4609 inline auto
4610 to_lower() noexcept { return impl::to_lower_transformer_proxy_t{}; }
4611
4612//
4613// just
4614//
4632 template< typename T >
4633 RESTINIO_NODISCARD
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 >
4662 RESTINIO_NODISCARD
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 >
4735 RESTINIO_NODISCARD
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//
4766 RESTINIO_NODISCARD
4767 inline auto
4768 exact_p( string_view_t fragment )
4769{
4770 return impl::exact_fragment_producer_t{
4771 std::string{ fragment.data(), fragment.size() }
4772 };
4773}
4774
4809 template< std::size_t Size >
4810 RESTINIO_NODISCARD
4811 auto
4812 exact_p( const char (&fragment)[Size] )
4813{
4814 return impl::exact_fixed_size_fragment_producer_t<Size>{ fragment };
4815}
4816
4817//
4818// exact
4819//
4831 RESTINIO_NODISCARD
4832 inline auto
4833 exact( string_view_t fragment )
4834{
4835 return impl::exact_fragment_producer_t{
4836 std::string{ fragment.data(), fragment.size() }
4837 } >> skip();
4838}
4839
4868 template< std::size_t Size >
4869 RESTINIO_NODISCARD
4870 auto
4871 exact( const char (&fragment)[Size] )
4872{
4873 return impl::exact_fixed_size_fragment_producer_t<Size>{ fragment } >> skip();
4874}
4875
4876//
4877// caseless_exact_p
4878//
4895 RESTINIO_NODISCARD
4896 inline auto
4897 caseless_exact_p( string_view_t fragment )
4898{
4899 return impl::caseless_exact_fragment_producer_t{
4900 std::string{ fragment.data(), fragment.size() }
4901 };
4902}
4903
4938 template< std::size_t Size >
4939 RESTINIO_NODISCARD
4940 auto
4941 caseless_exact_p( const char (&fragment)[Size] )
4942{
4943 return impl::caseless_exact_fixed_size_fragment_producer_t<Size>{ fragment };
4944}
4945
4946//
4947// caseless_exact
4948//
4960 RESTINIO_NODISCARD
4961 inline auto
4962 caseless_exact( string_view_t fragment )
4963{
4964 return impl::caseless_exact_fragment_producer_t{
4965 std::string{ fragment.data(), fragment.size() }
4966 } >> skip();
4967}
4968
4997 template< std::size_t Size >
4998 RESTINIO_NODISCARD
4999 auto
5000 caseless_exact( const char (&fragment)[Size] )
5001{
5002 return impl::caseless_exact_fixed_size_fragment_producer_t<Size>{ fragment } >> skip();
5003}
5004
5005//
5006// try_parse
5007//
5039 template< typename Producer >
5040 RESTINIO_NODISCARD
5041 expected_t< typename Producer::result_type, parse_error_t >
5042 try_parse(
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 =
5059 impl::ensure_no_remaining_content( source );
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//
5101 RESTINIO_NODISCARD
5102 inline std::string
5103 make_error_description(
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
5190 case error_reason_t::force_only_this_alternative_failed:
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
nonstd::optional_lite::optional
class optional
Definition: optional.hpp:919
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
restinio::easy_parser::digits_to_consume_t::underlying_int_t
std::int_fast8_t underlying_int_t
Definition: easy_parser.hpp:469
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::digits_to_consume_t::from_one_to_max
RESTINIO_NODISCARD static constexpr auto from_one_to_max() noexcept
Definition: easy_parser.hpp:527
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::digits_to_consume_t::max
RESTINIO_NODISCARD constexpr auto max() const noexcept
Get the maximum value.
Definition: easy_parser.hpp:512
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::digits_to_consume_t::unlimited_max
RESTINIO_NODISCARD static constexpr auto unlimited_max() noexcept
Get the value that means that maximum is not limited.
Definition: easy_parser.hpp:517
restinio::easy_parser::digits_to_consume_t::min
RESTINIO_NODISCARD constexpr auto min() const noexcept
Get the minimal value.
Definition: easy_parser.hpp:507
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::alternatives_clause_t
A template for implementation of clause that selects one of alternative clauses.
Definition: easy_parser.hpp:1636
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::impl::alternatives_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1637
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::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::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::and_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1849
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::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::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::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::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::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::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::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::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::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::caseless_exact_fragment_producer_t::m_fragment
std::string m_fragment
Definition: easy_parser.hpp:3506
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::caseless_symbol_producer_t::caseless_symbol_producer_t
caseless_symbol_producer_t(char expected)
Definition: easy_parser.hpp:2346
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::easy_parser::impl::consume_value_clause_t::m_consumer
C m_consumer
Definition: easy_parser.hpp:1479
restinio::easy_parser::impl::consume_value_clause_t::m_producer
P m_producer
Definition: easy_parser.hpp:1475
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::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::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::impl::convert_transformer_proxy_t::m_converter
Converter m_converter
Definition: easy_parser.hpp:3271
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::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::convert_transformer_proxy_t::make_transformer
RESTINIO_NODISCARD auto make_transformer() const &noexcept(noexcept(Converter{m_converter}))
Definition: easy_parser.hpp:3283
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::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::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::impl::convert_transformer_t::m_converter
Converter m_converter
Definition: easy_parser.hpp:3175
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::impl::custom_consumer_t
A template for consumers that are released by lambda/functional objects.
Definition: easy_parser.hpp:2940
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::easy_parser::impl::custom_consumer_t::custom_consumer_t
custom_consumer_t(C &&consumer)
Definition: easy_parser.hpp:2944
restinio::easy_parser::impl::custom_consumer_t::m_consumer
C m_consumer
Definition: easy_parser.hpp:2941
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::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::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::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::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::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
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::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::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::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::digit_producer_t::digit_producer_t
digit_producer_t()
Definition: easy_parser.hpp:2389
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::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::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::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::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::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::exact_fragment_producer_t::exact_fragment_producer_t
exact_fragment_producer_t(std::string fragment)
Definition: easy_parser.hpp:3393
restinio::easy_parser::impl::exact_fragment_producer_t::m_fragment
std::string m_fragment
Definition: easy_parser.hpp:3390
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::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::field_setter_consumer_t::pointer_t
F C::* pointer_t
Definition: easy_parser.hpp:2970
restinio::easy_parser::impl::field_setter_consumer_t::m_ptr
pointer_t m_ptr
Definition: easy_parser.hpp:2972
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::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::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::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::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::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::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::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::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::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::impl::hexdigit_producer_t::hexdigit_producer_t
hexdigit_producer_t()
Definition: easy_parser.hpp:2407
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::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::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::impl::just_result_consumer_t::consume
void consume(Target_Type &dest, Value &&) const
Definition: easy_parser.hpp:2917
restinio::easy_parser::impl::just_result_consumer_t::m_result
Result_Type m_result
Definition: easy_parser.hpp:2893
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::just_value_transformer_t::transform
RESTINIO_NODISCARD T transform(Input &&) const noexcept(noexcept(T{m_value}))
Definition: easy_parser.hpp:3157
restinio::easy_parser::impl::just_value_transformer_t::m_value
T m_value
Definition: easy_parser.hpp:3147
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::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::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::maybe_clause_t::maybe_clause_t
maybe_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1721
restinio::easy_parser::impl::maybe_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1718
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::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::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::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::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::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
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_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1781
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::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::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::produce_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:2013
restinio::easy_parser::impl::produce_t::produce_t
produce_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:2016
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::repeat_clause_t
A template for handling repetition of clauses.
Definition: easy_parser.hpp:2061
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::repeat_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:2065
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::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::impl::repeat_clause_t::m_max_occurences
std::size_t m_max_occurences
Definition: easy_parser.hpp:2063
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::sequence_clause_t::m_subitems
Subitems_Tuple m_subitems
Definition: easy_parser.hpp:1910
restinio::easy_parser::impl::sequence_clause_t::sequence_clause_t
sequence_clause_t(Subitems_Tuple &&subitems)
Definition: easy_parser.hpp:1913
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::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::source_t::content_consumer_t::content_consumer_t
content_consumer_t(const content_consumer_t &)=delete
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::impl::source_t::content_consumer_t::m_consumed
bool m_consumed
Definition: easy_parser.hpp:854
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t(content_consumer_t &&)=delete
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::source_t::content_consumer_t::commit
void commit() noexcept
Consume all acquired content.
Definition: easy_parser.hpp:885
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::source_t::content_consumer_t::content_consumer_t
content_consumer_t(source_t &from) noexcept
Definition: easy_parser.hpp:861
restinio::easy_parser::impl::source_t::content_consumer_t::content_consumer_t
content_consumer_t()=delete
restinio::easy_parser::impl::source_t::content_consumer_t::m_from
source_t & m_from
Definition: easy_parser.hpp:852
restinio::easy_parser::impl::source_t
The class that implements "input stream".
Definition: easy_parser.hpp:740
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::impl::source_t::eof
RESTINIO_NODISCARD bool eof() const noexcept
Is EOF has been reached?
Definition: easy_parser.hpp:803
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::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::source_t::putback
void putback() noexcept
Return one character back to the input stream.
Definition: easy_parser.hpp:777
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::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::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::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::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::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::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::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::symbol_producer_t::symbol_producer_t
symbol_producer_t(char expected)
Definition: easy_parser.hpp:2297
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::impl::symbol_producer_template_t::symbol_producer_template_t
symbol_producer_template_t(Args &&... args)
Definition: easy_parser.hpp:2136
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::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::top_level_clause_t::m_producer
Producer m_producer
Definition: easy_parser.hpp:1535
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::top_level_clause_t::try_process
RESTINIO_NODISCARD auto try_process(source_t &from)
Definition: easy_parser.hpp:1546
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::transformed_value_producer_t::m_producer
Producer m_producer
Definition: easy_parser.hpp:1188
restinio::easy_parser::impl::transformed_value_producer_t::m_transformer
Transformer m_transformer
Definition: easy_parser.hpp:1191
restinio::easy_parser::impl::transformed_value_producer_t::result_type
typename Transformer::result_type result_type
Definition: easy_parser.hpp:1194
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::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::parse_error_t
Information about parsing error.
Definition: easy_parser.hpp:93
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::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::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::parse_error_t::m_position
std::size_t m_position
Position in the input stream.
Definition: easy_parser.hpp:95
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::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
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
compiler_features.hpp
Detection of compiler version and absence of various features.
RESTINIO_NODISCARD
#define RESTINIO_NODISCARD
Definition: compiler_features.hpp:33
exception.hpp
expected.hpp
metaprogramming.hpp
Various tools for C++ metaprogramming.
nonstd::optional_lite::std11::false_type
bool_constant< false > false_type
Definition: optional.hpp:460
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
nonstd::optional_lite::nullopt
const nullopt_t nullopt((nullopt_t::init()))
nonstd::sv_lite::to_string
std::basic_string< CharT, Traits > to_string(basic_string_view< CharT, Traits > v)
Definition: string_view.hpp:1508
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::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::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::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::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::HTAB
constexpr char HTAB
A constant for Horizontal Tab value.
Definition: easy_parser.hpp:623
restinio::easy_parser::impl::is_space
RESTINIO_NODISCARD constexpr bool is_space(const char ch) noexcept
If a character a space character?
Definition: easy_parser.hpp:635
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::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::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::SP
constexpr char SP
A constant for SPACE value.
Definition: easy_parser.hpp:617
restinio::easy_parser::impl::is_hexdigit
RESTINIO_NODISCARD constexpr bool is_hexdigit(const char ch) noexcept
Is a character a hexadecimal digit?
Definition: easy_parser.hpp:702
restinio::easy_parser::impl::is_digit
RESTINIO_NODISCARD constexpr bool is_digit(const char ch) noexcept
Is a character a decimal digit?
Definition: easy_parser.hpp:669
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::entity_type_t::consumer
@ consumer
Entity is a consumer of values. It requires a value on the input and doesn't produces anything.
restinio::easy_parser::impl::entity_type_t::transformer
@ transformer
Entity is a transformer of a value from one type to another.
restinio::easy_parser::impl::entity_type_t::clause
@ clause
Entity is a clause. It doesn't produces anything.
restinio::easy_parser::impl::entity_type_t::producer
@ producer
Entity is a producer of values.
restinio::easy_parser::impl::entity_type_t::transformer_proxy
@ transformer_proxy
Entity is a transformer-proxy. It can't be used directly, only for binding a producer and transformer...
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::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::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::impl::operator!=
RESTINIO_NODISCARD bool operator!=(const character_t &a, const character_t &b) noexcept
Definition: easy_parser.hpp:607
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::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::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::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
Definition: easy_parser.hpp:39
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::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::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::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::maybe
RESTINIO_NODISCARD auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
Definition: easy_parser.hpp:3634
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::sequence
RESTINIO_NODISCARD auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
Definition: easy_parser.hpp:3758
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::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::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::expected_digits
RESTINIO_NODISCARD constexpr 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::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::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::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::easy_parser::error_reason_t
error_reason_t
Reason of parsing error.
Definition: easy_parser.hpp:52
restinio::easy_parser::error_reason_t::unexpected_eof
@ unexpected_eof
Unexpected end of input is encontered when some character expected.
restinio::easy_parser::error_reason_t::force_only_this_alternative_failed
@ force_only_this_alternative_failed
A failure of parsing an alternative marked as "force only this alternative".
restinio::easy_parser::error_reason_t::no_appropriate_alternative
@ no_appropriate_alternative
None of alternatives was found in the input.
restinio::easy_parser::error_reason_t::unexpected_character
@ unexpected_character
Unexpected character is found in the input.
restinio::easy_parser::error_reason_t::unconsumed_input
@ unconsumed_input
There are some unconsumed non-whitespace characters in the input after the completion of parsing.
restinio::easy_parser::error_reason_t::pattern_not_found
@ pattern_not_found
Required pattern is not found in the input.
restinio::easy_parser::error_reason_t::illegal_value_found
@ illegal_value_found
Illegal value was found in the input.
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::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::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::skip
RESTINIO_NODISCARD auto skip() noexcept
A factory function to create a skip_consumer.
Definition: easy_parser.hpp:3922
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::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::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::digit_p
RESTINIO_NODISCARD auto digit_p() noexcept
A factory function to create a digit_producer.
Definition: easy_parser.hpp:4133
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::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::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::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::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::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::N
constexpr std::size_t N
A special marker that means infinite repetitions.
Definition: easy_parser.hpp:455
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::hexdigit_p
RESTINIO_NODISCARD auto hexdigit_p() noexcept
A factory function to create a hexdigit_producer.
Definition: easy_parser.hpp:4172
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::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::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::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::result_wrapper_for_t
typename result_wrapper_for< T >::type result_wrapper_for_t
Definition: easy_parser.hpp:250
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::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::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::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::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::alternatives
RESTINIO_NODISCARD auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
Definition: easy_parser.hpp:3595
restinio::easy_parser::convert
RESTINIO_NODISCARD auto convert(Converter &&converter)
A factory function to create convert_transformer.
Definition: easy_parser.hpp:4737
restinio::impl::to_lower_case
RESTINIO_NODISCARD char to_lower_case(char ch)
Definition: to_lower_lut.hpp:39
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::utils::metaprogramming
Definition: metaprogramming.hpp:24
restinio::utils::metaprogramming::all_of_v
constexpr bool all_of_v
Applies the predicate to all types from the list and return true only if all types satisty that predi...
Definition: metaprogramming.hpp:325
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::utils::metaprogramming::void_t
typename make_void< Ts... >::type void_t
Definition: metaprogramming.hpp:28
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::utils::tuple_algorithms::all_of
RESTINIO_NODISCARD bool all_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:103
restinio::utils::tuple_algorithms::any_of
RESTINIO_NODISCARD bool any_of(Tuple &&tuple, Predicate &&predicate)
Definition: tuple_algorithms.hpp:117
restinio
Definition: asio_include.hpp:21
restinio::string_view_t
nonstd::string_view string_view_t
Definition: string_view.hpp:19
restinio::expected_t
nonstd::expected< T, E > expected_t
Definition: expected.hpp:22
std
STL namespace.
optional.hpp
overflow_controlled_integer_accumulator.hpp
Helper for parsing integer values.
string_view.hpp
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::any_symbol_predicate_t::operator()
RESTINIO_NODISCARD constexpr bool operator()(const char) const noexcept
Definition: easy_parser.hpp:2182
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::any_value_skipper_t::consume
void consume(Target_Type &, Value &&) const noexcept
Definition: easy_parser.hpp:2846
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::impl::as_result_consumer_t::consume
void consume(Target_Type &dest, Value &&src) const
Definition: easy_parser.hpp:2873
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::caseless_particular_symbol_predicate_t::m_expected
char m_expected
Definition: easy_parser.hpp:2241
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::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::impl::character_t
One character extracted from the input stream.
Definition: easy_parser.hpp:593
restinio::easy_parser::impl::character_t::m_eof
bool m_eof
Definition: easy_parser.hpp:594
restinio::easy_parser::impl::character_t::m_ch
char m_ch
Definition: easy_parser.hpp:595
restinio::easy_parser::impl::clause_tag
A special base class to be used with clauses.
Definition: easy_parser.hpp:1393
restinio::easy_parser::impl::clause_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1394
restinio::easy_parser::impl::consumer_tag
A special base class to be used with consumers.
Definition: easy_parser.hpp:1343
restinio::easy_parser::impl::consumer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1344
restinio::easy_parser::impl::conversion_result_type_detector< expected_t< Result_Type, error_reason_t > >::type
Result_Type type
Definition: easy_parser.hpp:3233
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::conversion_result_type_detector::type
Result_Type type
Definition: easy_parser.hpp:3227
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::impl::is_appropriate_transformer_result_type::value
static constexpr bool value
Definition: easy_parser.hpp:1112
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::is_clause
Definition: easy_parser.hpp:1398
restinio::easy_parser::impl::is_consumer
Definition: easy_parser.hpp:1348
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::is_digit_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:686
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::is_hexdigit_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:722
restinio::easy_parser::impl::is_producer
Definition: easy_parser.hpp:951
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
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::is_transformer_proxy
Definition: easy_parser.hpp:1272
restinio::easy_parser::impl::is_transformer
Definition: easy_parser.hpp:1005
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::not_particular_symbol_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2224
restinio::easy_parser::impl::not_particular_symbol_predicate_t::m_sentinel
char m_sentinel
Definition: easy_parser.hpp:2220
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::particular_symbol_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2203
restinio::easy_parser::impl::particular_symbol_predicate_t::m_expected
char m_expected
Definition: easy_parser.hpp:2199
restinio::easy_parser::impl::producer_tag
A special base class to be used with producers.
Definition: easy_parser.hpp:945
restinio::easy_parser::impl::producer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:947
restinio::easy_parser::impl::producer_tag::result_type
Result_Type result_type
Definition: easy_parser.hpp:946
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::impl::std_array_wrapper::m_index
std::size_t m_index
Definition: easy_parser.hpp:301
restinio::easy_parser::impl::std_array_wrapper::m_array
std::array< T, S > m_array
Definition: easy_parser.hpp:300
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::symbol_from_range_predicate_t::operator()
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
Definition: easy_parser.hpp:2273
restinio::easy_parser::impl::symbol_from_range_predicate_t::m_left
char m_left
Definition: easy_parser.hpp:2268
restinio::easy_parser::impl::symbol_from_range_predicate_t::m_right
char m_right
Definition: easy_parser.hpp:2269
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::impl::to_container_consumer_t::consume
void consume(Container &to, Item &&item)
Definition: easy_parser.hpp:4544
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::impl::to_lower_transformer_proxy_t::make_transformer
RESTINIO_NODISCARD auto make_transformer() const noexcept
Definition: easy_parser.hpp:3129
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::to_lower_transformer_t< char >::input_type
char input_type
Definition: easy_parser.hpp:3079
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< 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::to_lower_transformer_t< std::string >::input_type
std::string input_type
Definition: easy_parser.hpp:3053
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::to_lower_transformer_t
Definition: easy_parser.hpp:3041
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::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::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::transformed_value_producer_traits_checker::expected_result_t
typename Transformer::result_type expected_result_t
Definition: easy_parser.hpp:1160
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::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::transformer_invoker
A helper template for calling transformation function.
Definition: easy_parser.hpp:1048
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::impl::transformer_proxy_tag
A special base class to be used with transformer-proxies.
Definition: easy_parser.hpp:1267
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::transformer_tag
A special base class to be used with transformers.
Definition: easy_parser.hpp:999
restinio::easy_parser::impl::transformer_tag::result_type
Result_Type result_type
Definition: easy_parser.hpp:1000
restinio::easy_parser::impl::transformer_tag::entity_type
static constexpr entity_type_t entity_type
Definition: easy_parser.hpp:1001
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::tuple_item_consumer_t::consume
void consume(Target_Type &&to, Value &&value)
Definition: easy_parser.hpp:3030
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::result_value_wrapper< nothing_t >::as_result
static void as_result(wrapped_type &, result_type &&) noexcept
Definition: easy_parser.hpp:437
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::result_value_wrapper< nothing_t >::to_container
static void to_container(wrapped_type &, value_type &&) noexcept
Definition: easy_parser.hpp:440
restinio::easy_parser::result_value_wrapper< std::array< T, S > >
Definition: easy_parser.hpp:308
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::array< T, S > >::result_type
std::array< T, S > result_type
Definition: easy_parser.hpp:309
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::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::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::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::result_value_wrapper< std::basic_string< Char, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:358
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::result_value_wrapper< std::basic_string< Char, Args... > >::result_type
std::basic_string< Char, Args... > result_type
Definition: easy_parser.hpp:356
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::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
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::map< K, V, Args... > >::value_type
std::pair< K, V > value_type
Definition: easy_parser.hpp:406
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::result_value_wrapper< std::map< K, V, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:407
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::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::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::result_value_wrapper< std::vector< T, Args... > >::value_type
typename result_type::value_type value_type
Definition: easy_parser.hpp:256
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::result_value_wrapper< std::vector< T, Args... > >::result_type
std::vector< T, Args... > result_type
Definition: easy_parser.hpp:255
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::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::vector< T, Args... > >::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:257
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::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::unwrap_value
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Definition: easy_parser.hpp:192
restinio::easy_parser::result_value_wrapper::result_type
T result_type
Definition: easy_parser.hpp:181
restinio::easy_parser::result_value_wrapper::wrapped_type
result_type wrapped_type
Definition: easy_parser.hpp:182
restinio::easy_parser::result_wrapper_for
A metafunction for detection of actual result_value_wrapper type for T.
Definition: easy_parser.hpp:245
restinio::impl::check_negative_extremum
Definition: overflow_controlled_integer_accumulator.hpp:33
restinio::utils::metaprogramming::type_list
The basic building block: a type for representation of a type list.
Definition: metaprogramming.hpp:54
to_lower_lut.hpp
tuple_algorithms.hpp
Various meta-functions for operating the content of a tuple.
const
#define const
Definition: zconf.h:230