Go to the documentation of this file.
58 no_appropriate_alternative,
178 template<
typename T >
243 template<
typename T >
249 template<
typename T >
252 template<
typename T,
typename... Args >
297 template<
typename T, std::
size_t S >
306 template<
typename T, std::
size_t S >
325 "index in the result std::array is out of range, "
347 template<
typename T, std::
size_t S >
353 template<
typename Char,
typename... Args >
369 to.push_back( what );
399 template<
typename K,
typename V,
typename... Args >
455 constexpr std::size_t
N = std::numeric_limits<std::size_t>::max();
516 constexpr
static auto
519 return std::numeric_limits<underlying_int_t>::max();
526 constexpr
static auto
548 inline constexpr digits_to_consume_t
569 inline constexpr digits_to_consume_t
602 return (a.m_eof == b.m_eof && a.m_ch == b.m_ch);
609 return (a.m_eof != b.m_eof || a.m_ch != b.m_ch);
617 constexpr
char SP =
' ';
634 inline constexpr
bool
637 return ch ==
SP || ch ==
HTAB;
668 inline constexpr
bool
671 return (ch >=
'0' && ch <=
'9');
701 inline constexpr
bool
704 return (ch >=
'0' && ch <=
'9') ||
705 (ch >=
'A' && ch <=
'F') ||
706 (ch >=
'a' && ch <=
'f');
796 if( pos <=
m_data.size() )
818 string_view_t::size_type from,
822 string_view_t::size_type length = string_view_t::npos )
const noexcept
824 return m_data.substr( from, length );
943 template<
typename Result_Type >
950 template<
typename T,
typename = meta::
void_t<> >
953 template<
typename T >
956 static constexpr
bool value = entity_type_t::producer == T::entity_type;
969 template<
typename T >
997 template<
typename Result_Type >
1004 template<
typename T,
typename = meta::
void_t<> >
1007 template<
typename T >
1010 static constexpr
bool value = entity_type_t::transformer == T::entity_type;
1023 template<
typename T >
1046 template<
typename Result_Type >
1049 template<
typename Transformer,
typename Input_Type >
1054 Transformer & transformer,
1057 return transformer.transform(
std::move(*input) );
1067 template<
typename Result_Type >
1070 template<
typename Transformer,
typename Input_Type >
1076 Transformer & transformer,
1079 auto result = transformer.transform(
std::move(*input) );
1109 template<
typename Result_Type >
1115 template<
typename Result_Type >
1122 template<
typename Result_Type >
1143 template<
typename Producer,
typename Transformer >
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" );
1152 std::declval<Producer &>().
try_parse( std::declval<source_t &>() )
1156 std::declval<Transformer &>().
transform(
1157 std::move(*(std::declval<producer_result_t>())) )
1178 template<
typename Producer,
typename Transformer >
1180 :
public producer_tag< typename Transformer::result_type >
1183 Producer, Transformer >;
1187 "transformation result should be either T or "
1188 "expected_t<T, error_reson_t>, not expected_t<T, parse_error_t>" );
1197 Producer && producer,
1198 Transformer && transformer )
1207 auto producer_result =
m_producer.try_parse( source );
1208 if( producer_result )
1210 using transformation_result_t =
1219 return make_unexpected( producer_result.error() );
1228 template<
typename P,
typename T >
1231 is_producer_v<P> & is_transformer_v<T>,
1232 transformed_value_producer_t< P, T > >
1271 template<
typename T,
typename = meta::
void_t<> >
1274 template<
typename T >
1289 template<
typename T >
1301 typename S = std::enable_if_t<
1302 is_producer_v<P> & is_transformer_proxy_v<T>,
1308 T transformer_proxy )
1311 typename P::result_type >();
1313 using transformator_type = std::decay_t< decltype(real_transformer) >;
1347 template<
typename T,
typename = meta::
void_t<> >
1350 template<
typename T >
1353 static constexpr
bool value = entity_type_t::consumer == T::entity_type;
1366 template<
typename T >
1397 template<
typename T,
typename = meta::
void_t<> >
1400 template<
typename T >
1402 decltype(std::decay_t<T>::entity_type) > >
1406 static constexpr
bool value = entity_type_t::clause == real_type::entity_type;
1419 template<
typename T >
1455 template<
typename... Entities >
1472 template<
typename P,
typename C >
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" );
1487 template<
typename Target_Type >
1492 auto parse_result =
m_producer.try_parse( from );
1499 return parse_result.error();
1508 template<
typename P,
typename C >
1511 is_producer_v<P> && is_consumer_v<C>,
1512 consume_value_clause_t< P, C > >
1531 template<
typename Producer >
1534 static_assert( is_producer_v<Producer>,
1535 "Producer should be a producer type" );
1569 while( !from.
eof() )
1576 error_reason_t::unconsumed_input
1596 auto s = from.size();
1597 for(; s &&
is_space( from[ (s-1u) ] ); --s) {}
1599 return from.substr( 0u, s );
1634 typename Subitems_Tuple >
1641 Subitems_Tuple && subitems )
1645 template<
typename Target_Type >
1655 [&from, &target, &actual_parse_error](
auto && one_producer ) {
1657 Target_Type tmp_value{ target };
1659 actual_parse_error = one_producer.try_process( from, tmp_value );
1660 if( !actual_parse_error )
1673 actual_parse_error->reason();
1677 if( !success || actual_parse_error )
1680 error_reason_t::no_appropriate_alternative
1715 typename Subitems_Tuple >
1722 Subitems_Tuple && subitems )
1726 template<
typename Target_Type >
1732 Target_Type tmp_value{ target };
1736 [&from, &tmp_value](
auto && one_producer ) {
1737 return !one_producer.try_process( from, tmp_value );
1778 typename Subitems_Tuple >
1785 Subitems_Tuple && subitems )
1789 template<
typename Target_Type >
1797 Target_Type dummy_value;
1801 [&from, &dummy_value](
auto && one_producer ) {
1802 return !one_producer.try_process( from, dummy_value );
1809 consumer.started_at(),
1812 error_reason_t::pattern_not_found
1846 typename Subitems_Tuple >
1853 Subitems_Tuple && subitems )
1857 template<
typename Target_Type >
1865 Target_Type dummy_value;
1869 [&from, &dummy_value](
auto && one_producer ) {
1870 return !one_producer.try_process( from, dummy_value );
1875 consumer.started_at(),
1876 error_reason_t::pattern_not_found
1907 typename Subitems_Tuple >
1914 Subitems_Tuple && subitems )
1918 template<
typename Target_Type >
1924 Target_Type tmp_value{ target };
1931 [&from, &tmp_value, &result](
auto && one_producer ) {
1932 result = one_producer.try_process( from, tmp_value );
1960 typename Subitems_Tuple >
1966 using base_type_t::base_type_t;
1968 template<
typename Target_Type >
2007 typename Target_Type,
2008 typename Subitems_Tuple >
2017 Subitems_Tuple && subitems )
2030 [&from, &tmp_value, &error](
auto && one_clause ) {
2031 error = one_clause.try_process( from, tmp_value );
2038 return make_unexpected( *error );
2059 typename Subitems_Tuple >
2069 std::size_t min_occurences,
2070 std::size_t max_occurences,
2071 Subitems_Tuple && subitems )
2077 template<
typename Target_Type >
2079 optional_t< parse_error_t >
2084 std::size_t count{};
2085 bool failure_detected{
false };
2092 [&from, &dest](
auto && one_clause ) {
2093 return !one_clause.try_process( from, dest );
2096 if( !failure_detected )
2099 item_consumer.commit();
2106 whole_consumer.commit();
2112 error_reason_t::pattern_not_found
2129 template<
typename Predicate >
2132 ,
protected Predicate
2135 template<
typename... Args >
2137 : Predicate{ std::forward<Args>(args)... }
2144 const auto ch = from.getch();
2148 if( (*
this)(ch.m_ch) )
2154 from.current_position(),
2155 error_reason_t::unexpected_character
2161 from.current_position(),
2162 error_reason_t::unexpected_eof
2434 template<
typename T,
typename Value_Accumulator >
2440 Value_Accumulator acc ) noexcept
2446 for(
auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
2450 acc.next_digit(
static_cast<T
>(ch.m_ch -
'0') );
2452 if( acc.overflow_detected() )
2454 consumer.started_at(),
2455 error_reason_t::illegal_value_found
2458 ++symbols_processed;
2459 if( symbols_processed == digits_limit.max() )
2469 if( symbols_processed < digits_limit.min() )
2472 from.current_position(),
2473 error_reason_t::pattern_not_found
2498 template<
typename T,
typename Value_Accumulator >
2504 Value_Accumulator acc ) noexcept
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')) );
2514 return std::make_pair(
false,
static_cast<T
>(0) );
2521 for(
auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
2523 const auto d = ch_to_digit( ch.m_ch );
2526 acc.next_digit( d.second );
2528 if( acc.overflow_detected() )
2530 consumer.started_at(),
2531 error_reason_t::illegal_value_found
2534 ++symbols_processed;
2535 if( symbols_processed == digits_limit.max() )
2545 if( symbols_processed < digits_limit.min() )
2548 from.current_position(),
2549 error_reason_t::pattern_not_found
2569 template<
typename T >
2577 return try_parse_digits_with_digits_limit< T >(
2597 template<
typename T >
2613 return try_parse_digits_with_digits_limit< T >(
2631 template<
typename T >
2634 static_assert( std::is_unsigned<T>::value,
2635 "T is expected to be unsigned type" );
2642 return try_parse_hexdigits_with_digits_limit< T >(
2662 template<
typename T >
2678 return try_parse_hexdigits_with_digits_limit< T >(
2696 template<
typename T >
2699 static_assert( std::is_signed<T>::value,
2700 "decimal_number_producer_t can be used only for signed types" );
2716 template<
typename Digits_Limit_Maker >
2721 Digits_Limit_Maker && digits_limit_maker )
const noexcept
2725 auto sign_ch = from.getch();
2726 if( !sign_ch.m_eof )
2731 std::forward<Digits_Limit_Maker>(digits_limit_maker) );
2740 from.current_position(),
2741 error_reason_t::pattern_not_found
2746 template<
typename Digits_Limit_Maker >
2752 Digits_Limit_Maker && digits_limit_maker ) noexcept
2757 if(
'-' == first_symbol )
2759 const auto r = try_parse_digits_with_digits_limit< T >(
2761 digits_limit_maker(),
2762 overflow_controlled_integer_accumulator_t<
2765 check_negative_extremum >{} );
2767 return static_cast< T
>( -(*r) );
2773 else if(
'+' == first_symbol )
2775 return try_parse_digits_with_digits_limit< T >(
2777 digits_limit_maker(),
2778 overflow_controlled_integer_accumulator_t< T, 10 >{} );
2783 return try_parse_digits_with_digits_limit< T >(
2785 digits_limit_maker(),
2786 overflow_controlled_integer_accumulator_t< T, 10 >{} );
2790 from.current_position(),
2791 error_reason_t::pattern_not_found
2809 template<
typename T >
2844 template<
typename Target_Type,
typename Value >
2871 template<
typename Target_Type,
typename Value >
2876 dest, std::forward<Value>(src) );
2890 template<
typename Result_Type >
2903 noexcept(noexcept(Result_Type{
m_result}))
2909 template<
typename Result_Arg >
2911 noexcept(noexcept(Result_Type{std::forward<Result_Arg>(result)}))
2912 :
m_result{ std::forward<Result_Arg>(result) }
2915 template<
typename Target_Type,
typename Value >
2938 template<
typename C >
2946 template<
typename Target_Type,
typename Value >
2949 noexcept(noexcept(
m_consumer(dest, std::forward<Value>(src))))
2951 m_consumer( dest, std::forward<Value>(src) );
2967 template<
typename F,
typename C >
2997 template<
typename P,
typename F,
typename C >
3001 consume_value_clause_t< P, field_setter_consumer_t<F,C> > >
3019 template< std::
size_t Index >
3028 template<
typename Target_Type,
typename Value >
3032 std::get<Index>(std::forward<Target_Type>(to)) =
3033 std::forward<Value>(value);
3040 template<
typename Input_Type >
3061 [](
unsigned char ch ) ->
char {
3062 return restinio::impl::to_lower_case(ch);
3095 template< std::
size_t S >
3108 [](
unsigned char ch ) ->
char {
3109 return restinio::impl::to_lower_case(ch);
3126 template<
typename Input_Type >
3144 template<
typename T >
3154 template<
typename Input >
3172 template<
typename Output_Type,
typename Converter >
3178 template<
typename Convert_Arg >
3180 noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
3181 :
m_converter{ std::forward<Convert_Arg>(converter) }
3192 template<
typename Input >
3196 noexcept(noexcept(
m_converter(std::forward<Input>(input))))
3198 using actual_result_t = std::decay_t< decltype(
3204 "the return value of converter should be either Output_Type or "
3205 "expected_t<Output_Type, error_reason_t>" );
3224 template<
typename Result_Type >
3230 template<
typename Result_Type >
3241 template<
typename Result_Type >
3261 template<
typename Converter >
3264 template<
typename Input_Type >
3266 std::decay_t< decltype(
3267 std::declval<Converter &>()(std::declval<Input_Type&&>())
3274 template<
typename Convert_Arg >
3276 noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
3277 :
m_converter{ std::forward<Convert_Arg>(converter) }
3280 template<
typename Input_Type >
3286 using output_t = output<Input_Type>;
3291 template<
typename Input_Type >
3297 using output_t = output<Input_Type>;
3310 template<
typename It >
3312 expected_t< bool, parse_error_t >
3315 assert( begin != end );
3321 if( ch.m_ch != *begin )
3323 consumer.started_at(),
3324 error_reason_t::pattern_not_found
3326 if( ++begin == end )
3332 consumer.started_at(),
3333 error_reason_t::unexpected_eof
3353 template< std::
size_t Size >
3357 static_assert( 1u < Size,
"Size is expected to greater that 1" );
3397 throw exception_t(
"'fragment' value for exact_fragment_producer_t "
3398 "can't be empty!" );
3416 template<
typename It >
3421 assert( begin != end );
3429 consumer.started_at(),
3430 error_reason_t::pattern_not_found
3432 if( ++begin == end )
3438 consumer.started_at(),
3439 error_reason_t::unexpected_eof
3461 template< std::
size_t Size >
3465 static_assert( 1u < Size,
"Size is expected to greater that 1" );
3478 [](
const char src ) {
3479 return restinio::impl::to_lower_case( src );
3513 throw exception_t(
"'fragment' value for exact_fragment_producer_t "
3514 "can't be empty!" );
3550 typename Target_Type,
3551 typename... Clauses >
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" );
3565 return producer_type_t{
3566 std::make_tuple(std::forward<Clauses>(clauses)...)
3592 template<
typename... Clauses >
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" );
3605 return clause_type_t{
3606 std::make_tuple(std::forward<Clauses>(clauses)...)
3631 template<
typename... Clauses >
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" );
3644 return clause_type_t{
3645 std::make_tuple(std::forward<Clauses>(clauses)...)
3673 template<
typename... Clauses >
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" );
3686 return clause_type_t{
3687 std::make_tuple(std::forward<Clauses>(clauses)...)
3715 template<
typename... Clauses >
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" );
3728 return clause_type_t{
3729 std::make_tuple(std::forward<Clauses>(clauses)...)
3755 template<
typename... Clauses >
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" );
3768 return clause_type_t{
3769 std::make_tuple(std::forward<Clauses>(clauses)...)
3818 template<
typename... Clauses >
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 "
3832 return clause_type_t{
3833 std::make_tuple(std::forward<Clauses>(clauses)...)
3873 typename... Clauses >
3878 std::size_t min_occurences,
3885 std::size_t max_occurences,
3887 Clauses &&... clauses )
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" );
3897 return producer_type_t{
3900 std::make_tuple(std::forward<Clauses>(clauses)...)
4215 template<
typename T >
4254 template<
typename T >
4276 template<
typename T >
4281 return non_negative_decimal_number_p<T>();
4304 template<
typename T >
4346 template<
typename T >
4384 template<
typename T >
4389 static_assert( std::is_signed<T>::value,
4390 "decimal_number_p() can be used only for signed numeric types" );
4437 template<
typename T >
4442 static_assert( std::is_signed<T>::value,
4443 "decimal_number_p() can be used only for signed numeric types" );
4513 template<
typename F >
4520 return actual_consumer_t{
std::move(consumer) };
4542 template<
typename Container,
typename Item >
4632 template<
typename T >
4637 return impl::just_value_transformer_t<T>{value};
4661 template<
typename T >
4667 return impl::just_result_consumer_t<T>{value};
4734 template<
typename Converter >
4739 using converter_type = std::decay_t<Converter>;
4744 return transformer_proxy_type{ std::forward<Converter>(converter) };
4771 std::string{ fragment.data(), fragment.size() }
4809 template< std::
size_t Size >
4836 std::string{ fragment.data(), fragment.size() }
4868 template< std::
size_t Size >
4900 std::string{ fragment.data(), fragment.size() }
4938 template< std::
size_t Size >
4965 std::string{ fragment.data(), fragment.size() }
4997 template< std::
size_t Size >
5039 template<
typename Producer >
5046 static_assert( impl::is_producer_v<Producer>,
5047 "Producer should be a value producer type" );
5053 .try_process( source );
5058 const auto all_content_check =
5060 if( all_content_check )
5061 return make_unexpected( *all_content_check );
5107 const auto append_quote = [&]( std::string & dest ) {
5108 constexpr std::size_t max_quote_size = 16u;
5112 const auto prefix_size = error.
position() > max_quote_size ?
5115 dest.append( 1u,
'"' );
5117 &from[ error.
position() ] - prefix_size,
5119 dest.append(
"\" >>> " );
5122 const char problematic_symbol = error.
position() < from.size() ?
5124 dest.append( 1u,
'\'' );
5125 if( problematic_symbol >=
'\x00' && problematic_symbol <
' ' )
5127 constexpr
char hex_digits[] =
"0123456789abcdef";
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 ] );
5136 dest.append( 1u, problematic_symbol );
5138 dest.append( 1u,
'\'' );
5140 if( error.
position() + 1u < from.size() )
5143 const auto suffix_size =
5144 error.
position() + 1u + max_quote_size < from.size() ?
5145 max_quote_size : from.size() - error.
position() - 1u;
5147 dest.append(
" <<< \"" );
5148 dest.append( &from[ error.
position() + 1u ], suffix_size );
5149 dest.append( 1u,
'"' );
5155 const auto basic_reaction = [&](
const char * msg) {
5160 append_quote( result );
5165 case error_reason_t::unexpected_character:
5166 basic_reaction(
"unexpected character" );
5169 case error_reason_t::unexpected_eof:
5170 result +=
"unexpected EOF at ";
5174 case error_reason_t::no_appropriate_alternative:
5175 basic_reaction(
"appropriate alternative can't found" );
5178 case error_reason_t::pattern_not_found:
5179 basic_reaction(
"expected pattern is not found" );
5182 case error_reason_t::unconsumed_input:
5183 basic_reaction(
"unconsumed input found" );
5186 case error_reason_t::illegal_value_found:
5187 basic_reaction(
"some illegal value found" );
5191 basic_reaction(
"forced selection alternative failed" );
constexpr digits_to_consume_t(underlying_int_t total) noexcept
std::int_fast8_t underlying_int_t
Exception class for all exceptions thrown by RESTinio.
void consume(Target_Type &dest, Value &&src) const noexcept(noexcept(m_consumer(dest, std::forward< Value >(src))))
std::map< K, V, Args... > result_type
A template for consumers that are released by lambda/functional objects.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
RESTINIO_NODISCARD std::size_t position() const noexcept
Get the position in the input stream where error was detected.
#define RESTINIO_NODISCARD
RESTINIO_NODISCARD position_t current_position() const noexcept
Get the current position in the stream.
Subitems_Tuple m_subitems
@ unexpected_character
Unexpected character is found in the input.
std::array< T, S > m_array
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...
caseless_particular_symbol_predicate_t(char v) noexcept
static void as_result(wrapped_type &to, result_type &&what)
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
RESTINIO_NODISCARD auto produce(Clauses &&... clauses)
A factory function to create a producer that creates an instance of the target type by using specifie...
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
A predicate for cases where char to be expected to be a decimal digit.
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
A template for producer of charachers that satisfy some predicate.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
Limits for number of digits to be extracted during parsing of decimal numbers.
std::pair< K, V > value_type
content_consumer_t(const content_consumer_t &)=delete
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
RESTINIO_NODISCARD char to_lower_case(char ch)
One character extracted from the input stream.
RESTINIO_NODISCARD bool operator==(const character_t &a, const character_t &b) noexcept
constexpr static RESTINIO_NODISCARD auto from_one_to_max() noexcept
A special base class to be used with clauses.
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.
A template with specializations for different kind of result values and for type nothing.
A producer for the case when a number in hexadecimal form is expected in the input stream.
source_t(string_view_t data) noexcept
Initializing constructor.
RESTINIO_NODISCARD auto digit() noexcept
A factory function to create a clause that expects a decimal digit, extracts it and then skips it.
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
constexpr RESTINIO_NODISCARD bool operator()(const char) const noexcept
consume_value_clause_t(P &&producer, C &&consumer)
static constexpr entity_type_t entity_type
constexpr bool is_producer_v
A meta-value to check whether T is a producer type.
symbol_producer_t(char expected)
RESTINIO_NODISCARD try_parse_result_type try_parse(source_t &from) const noexcept
constexpr std::size_t N
A special marker that means infinite repetitions.
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...
A special consumer that simply throws any value away.
error_reason_t m_reason
The reason of the error.
RESTINIO_NODISCARD auto not_clause(Clauses &&... clauses)
A factory function to create a not_clause.
RESTINIO_NODISCARD auto digit_p() noexcept
A factory function to create a digit_producer.
RESTINIO_NODISCARD character_t getch() noexcept
Get the next character from the input stream.
Information about parsing error.
A producer for the case when a hexadecimal digit is expected in the input stream.
static void to_container(wrapped_type &to, value_type &&what)
static void to_container(wrapped_type &to, value_type &&what)
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.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
underlying_int_t m_max
Maximal number of digits to consume.
A template for implementation of clause that checks the presence of some entity in the input stream.
A producer for the case when a particual character is expected in the input stream.
const position_t m_started_at
A template for implementation of clause that selects one of alternative clauses.
RESTINIO_NODISCARD auto hexdigit() noexcept
A factory function to create a clause that expects a hexadecimal digit, extracts it and then skips it...
Subitems_Tuple m_subitems
Helper for parsing integer values.
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...
nonstd::string_view string_view_t
constexpr bool is_consumer_v
A meta-value to check whether T is a consumer type.
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
A template for implementation of clause that checks absence of some entity in the input stream.
A special wrapper for std::array type to be used inside a producer during the parsing.
A producer for the case when a non-negative decimal number is expected in the input stream.
RESTINIO_NODISCARD auto any_symbol_p() noexcept
A factory function to create an any_symbol_producer.
void commit() noexcept
Consume all acquired content.
constexpr digits_to_consume_t(underlying_int_t min, underlying_int_t max) noexcept
A template for implementation of clause that checks and handles presence of sequence of entities in t...
typename result_type::value_type value_type
std::vector< T, Args... > result_type
A predicate for cases where char to be expected to be a hexadecimal digit.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
A producer for the case when any character except the specific sentinel character is expected in the ...
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
RESTINIO_NODISCARD error_reason_t reason() const noexcept
Get the reason of the error.
std::size_t m_max_occurences
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
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.
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.
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
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
symbol_from_range_producer_t(char left, char right)
A template for implementation of clause that checks and handles presence of optional entity in the in...
void consume(Target_Type &dest, Value &&src) const
content_consumer_t()=delete
RESTINIO_NODISCARD auto symbol_from_range_p(char left, char right) noexcept
A factory function to create a symbol_from_range_producer.
static void as_result(wrapped_type &to, result_type &&what)
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.
custom_consumer_t(C &&consumer)
Subitems_Tuple m_subitems
RESTINIO_NODISCARD auto any_symbol_if_not_p(char sentinel) noexcept
A factory function to create a any_symbol_if_not_producer.
Result_Type make_copy_of_result() const noexcept(noexcept(Result_Type{m_result}))
expected_t< T, parse_error_t > try_parse_result_type
constexpr RESTINIO_NODISCARD bool is_digit(const char ch) noexcept
Is a character a decimal digit?
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
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...
A predicate for cases where the case-insensitive match of expected and actual symbols is required.
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
content_consumer_t(source_t &from) noexcept
const string_view_t m_data
The content to be used as "input stream".
RESTINIO_NODISCARD auto as_result() noexcept
A factory function to create a as_result_consumer.
constexpr RESTINIO_NODISCARD auto max() const noexcept
Get the maximum value.
A special base class to be used with consumers.
A producer for the case when a symbol should belong to specified range.
entity_type_t
A marker for distinguish different kind of entities in parser.
A template for a consumer that stories values into a container.
RESTINIO_NODISCARD auto symbol_p(char expected) noexcept
A factory function to create a symbol_producer.
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &target)
RESTINIO_NODISCARD auto space_p() noexcept
A factory function to create a space_producer.
A consumer for the case when the current value should be returned as the result for the producer at o...
A metafunction for detection of actual result_value_wrapper type for T.
RESTINIO_NODISCARD auto positive_decimal_number_producer() noexcept
A factory function to create a producer for non-negative decimal numbers.
RESTINIO_NODISCARD bool all_of(Tuple &&tuple, Predicate &&predicate)
A producer for the case when a particual character is expected in the input stream.
@ producer
Entity is a producer of values.
RESTINIO_NODISCARD expected_t< Target_Type, parse_error_t > try_parse(source_t &from)
A template for producing a value of specific type of a sequence of entities from the input stream.
static void as_result(wrapped_type &to, result_type &&what)
RESTINIO_NODISCARD auto caseless_exact_p(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment_producer.
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.
A producer for the case when a non-negative decimal number is expected in the input stream.
Subitems_Tuple m_subitems
constexpr bool is_transformer_v
A meta-value to check whether T is a transformer type.
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.
static void to_container(wrapped_type &to, value_type &&what)
An alternative that should be parsed correctly or the parsing of the whole alternatives clause should...
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
position_t started_at() const noexcept
typename result_type::value_type value_type
constexpr char SP
A constant for SPACE value.
string_view_t::size_type m_index
The current position in the input stream.
caseless_symbol_producer_t(char expected)
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
RESTINIO_NODISCARD auto non_negative_decimal_number_p() noexcept
A factory function to create a non_negative_decimal_number_producer.
static void to_container(wrapped_type &to, value_type &&what)
constexpr bool is_clause_v
A meta-value to check whether T is a consumer type.
constexpr RESTINIO_NODISCARD bool is_space(const char ch) noexcept
If a character a space character?
and_clause_t(Subitems_Tuple &&subitems)
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.
A predicate for cases where a symbol should belong to specified range.
A helper class to automatically return acquired content back to the input stream.
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
const nullopt_t nullopt((nullopt_t::init()))
nonstd::expected< T, E > expected_t
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
std::basic_string< Char, Args... > result_type
A producer for the case when a signed decimal number is expected in the input stream.
Various meta-functions for operating the content of a tuple.
RESTINIO_NODISCARD auto hexdigit_p() noexcept
A factory function to create a hexdigit_producer.
std::array< char, Size-1u > m_fragment
top_level_clause_t(Producer &&producer)
typename conversion_result_type_detector< Result_Type >::type conversion_result_type_detector_t
string_view_t::size_type position_t
Type to be used as the index inside the input stream.
A special base class to be used with producers.
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.
void backto(position_t pos) noexcept
Return the current position in the input stream at the specified position.
RESTINIO_NODISCARD auto to_container()
A factory function to create a to_container_consumer.
A producer for the case when a number in hexadecimal form is expected in the input stream.
caseless_exact_fixed_size_fragment_producer_t(const char(&f)[Size])
void consume(Target_Type &, Value &&) const noexcept
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
RESTINIO_NODISCARD bool operator!=(const character_t &a, const character_t &b) noexcept
RESTINIO_NODISCARD auto exact(string_view_t fragment)
A factory function that creates an instance of exact_fragment clause.
symbol_producer_template_t(Args &&... args)
void consume(C &to, F &&value) const noexcept(noexcept(to.*m_ptr=std::move(value)))
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse_exact_fragment(source_t &from, It begin, It end)
constexpr RESTINIO_NODISCARD auto min() const noexcept
Get the minimal value.
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
~content_consumer_t() noexcept
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &dest)
constexpr RESTINIO_NODISCARD bool is_hexdigit(const char ch) noexcept
Is a character a hexadecimal digit?
static void as_result(wrapped_type &to, result_type &&what)
not_clause_t(Subitems_Tuple &&subitems)
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.
typename result_wrapper_for< T >::type result_wrapper_for_t
constexpr static RESTINIO_NODISCARD auto unlimited_max() noexcept
Get the value that means that maximum is not limited.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
RESTINIO_NODISCARD auto space() noexcept
A factory function to create a clause that expects a space, extracts it and then skips it.
A special class to be used as the top level clause in parser.
void consume(Target_Type &dest, Value &&) const
RESTINIO_NODISCARD auto convert(Converter &&converter)
A factory function to create convert_transformer.
RESTINIO_NODISCARD auto to_lower() noexcept
A factory function to create a to_lower_transformer.
static void as_result(wrapped_type &to, result_type &&what)
A helper template for the detection of type to be produced as conversion procedure.
std::size_t m_min_occurences
exact_fixed_size_fragment_producer_t(const char(&f)[Size])
Helper class for accumulating integer value during parsing it from string (with check for overflow).
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
std::size_t m_position
Position in the input stream.
static void to_container(wrapped_type &, value_type &&) noexcept
produce_t(Subitems_Tuple &&subitems)
Subitems_Tuple m_subitems
error_reason_t
Reason of parsing error.
static constexpr entity_type_t entity_type
constexpr char HTAB
A constant for Horizontal Tab value.
A template for a clause that binds a value producer with value consumer.
RESTINIO_NODISCARD bool any_of(Tuple &&tuple, Predicate &&predicate)
A producer for the case when a decimal digit is expected in the input stream.
digits_to_consume_t m_digits_limit
RESTINIO_NODISCARD auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
Detection of compiler version and absence of various features.
RESTINIO_NODISCARD auto exact_p(string_view_t fragment)
A factory function that creates an instance of exact_fragment_producer.
content_consumer_t(content_consumer_t &&)=delete
std::array< char, Size-1u > m_fragment
void consume(Container &to, Item &&item)
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
RESTINIO_NODISCARD auto hexadecimal_number_p() noexcept
A factory function to create a hexadecimal_number_producer.
static RESTINIO_NODISCARD result_type && unwrap_value(wrapped_type &v)
A template for handling repetition of clauses.
void consume(Target_Type &&to, Value &&value)
RESTINIO_NODISCARD auto try_process(source_t &from)
field_setter_consumer_t(pointer_t ptr) noexcept
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &)
maybe_clause_t(Subitems_Tuple &&subitems)
hexadecimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
sequence_clause_t(Subitems_Tuple &&subitems)
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...
constexpr bool is_transformer_proxy_v
A meta-value to check whether T is a transformer-proxy type.
just_result_consumer_t(Result_Arg &&result) noexcept(noexcept(Result_Type{std::forward< Result_Arg >(result)}))
parse_error_t(std::size_t position, error_reason_t reason) noexcept
Initializing constructor.
A special type to be used in the case where there is no need to store produced value.
digits_to_consume_t m_digits_limit
static constexpr entity_type_t entity_type
The class that implements "input stream".
underlying_int_t m_min
Minimal number of digits to consume.
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse(source_t &from)
caseless_exact_fragment_producer_t(std::string fragment)
static void as_result(wrapped_type &, result_type &&) noexcept
Subitems_Tuple m_subitems
exact_fragment_producer_t(std::string fragment)
void putback() noexcept
Return one character back to the input stream.
RESTINIO_NODISCARD auto decimal_number_p() noexcept
A factory function to create a decimal_number_producer.
RESTINIO_NODISCARD auto caseless_exact(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment clause.
alternatives_clause_t(Subitems_Tuple &&subitems)
A producer that expects a fragment in the input and produces boolean value if that fragment is found.
A predicate for cases where exact match of expected and actual symbols is required.
RESTINIO_NODISCARD expected_t< bool, parse_error_t > try_parse_caseless_exact_fragment(source_t &from, It begin, It end)
RESTINIO_NODISCARD string_view_t remove_trailing_spaces(string_view_t from) noexcept
Helper function for removal of trailing spaces from a string-view.
RESTINIO_NODISCARD bool operator()(const char actual) const noexcept
any_symbol_if_not_producer_t(char sentinel)
constexpr RESTINIO_NODISCARD digits_to_consume_t expected_digits(digits_to_consume_t::underlying_int_t total) noexcept
Create a limit for number of digits to be extracted.
RESTINIO_NODISCARD auto and_clause(Clauses &&... clauses)
A factory function to create an and_clause.
A template for consumers that store a value to the specified field of a target object.
std::array< T, S > result_type
repeat_clause_t(std::size_t min_occurences, std::size_t max_occurences, Subitems_Tuple &&subitems)
RESTINIO_NODISCARD auto caseless_symbol_p(char expected) noexcept
A factory function to create a caseless_symbol_producer.
RESTINIO_NODISCARD auto custom_consumer(F consumer)
A factory function to create a custom_consumer.
RESTINIO_NODISCARD auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
A producer for the case when a signed decimal number is expected in the input stream.
A preducate for symbol_producer_template that checks that a symbol is a space.
std::basic_string< CharT, Traits > to_string(basic_string_view< CharT, Traits > v)
A predicate for cases where mismatch with a particular symbol is required.
decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
RESTINIO_NODISCARD auto try_parse(source_t &from) const noexcept
RESTINIO_NODISCARD try_parse_result_type try_parse_impl(source_t &from, Digits_Limit_Maker &&digits_limit_maker) const noexcept
A consumer that stores a result value at the specified index in the result tuple.
RESTINIO_NODISCARD expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
A predicate that allows extraction of any symbol.
Subitems_Tuple m_subitems
A consumer for the case when a specific value should be used as the result instead of the value produ...
RESTINIO_NODISCARD optional_t< parse_error_t > try_process(source_t &from, Target_Type &)
RESTINIO_NODISCARD expected_t< char, parse_error_t > try_parse(source_t &from) const noexcept
RESTINIO_NODISCARD auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
RESTINIO_NODISCARD bool eof() const noexcept
Is EOF has been reached?
RESTINIO_NODISCARD auto skip() noexcept
A factory function to create a skip_consumer.
RESTINIO_NODISCARD auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
digits_to_consume_t m_digits_limit
non_negative_decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)