15 #include <restinio/impl/to_lower_lut.hpp> 16 #include <restinio/impl/overflow_controlled_integer_accumulator.hpp> 18 #include <restinio/utils/tuple_algorithms.hpp> 19 #include <restinio/utils/metaprogramming.hpp> 21 #include <restinio/string_view.hpp> 22 #include <restinio/compiler_features.hpp> 24 #include <restinio/exception.hpp> 25 #include <restinio/expected.hpp> 103 std::size_t position,
179 template<
typename T >
182 using result_type = T;
183 using wrapped_type = result_type;
192 static result_type &&
244 template<
typename T >
250 template<
typename T >
253 template<
typename T,
typename...
Args >
298 template<
typename T, std::size_t S >
326 "index in the result std::array is out of range, " 348 template<
typename T, std::size_t S >
354 template<
typename Char,
typename...
Args >
400 template<
typename K,
typename V,
typename...
Args >
435 using wrapped_type = result_type;
444 static result_type &&
499 underlying_int_t min,
500 underlying_int_t max )
noexcept 508 min()
const noexcept {
return m_min; }
513 max()
const noexcept {
return m_max; }
517 constexpr static auto 520 return std::numeric_limits<underlying_int_t>::max();
527 constexpr static auto 530 return digits_to_consume_t{ 1, unlimited_max() };
572 digits_to_consume_t::underlying_int_t min,
573 digits_to_consume_t::underlying_int_t max )
noexcept 618 constexpr char SP =
' ';
635 inline constexpr bool 638 return ch ==
SP || ch ==
HTAB;
669 inline constexpr bool 672 return (ch >=
'0' && ch <=
'9');
702 inline constexpr bool 705 return (ch >=
'0' && ch <=
'9') ||
706 (ch >=
'A' && ch <=
'F') ||
707 (ch >=
'a' && ch <=
'f');
768 if( m_index < m_data.size() )
770 return {
false, m_data[ m_index++ ]};
797 if( pos <= m_data.size() )
806 return m_index >= m_data.size();
825 return m_data.substr( from, length );
870 m_from.backto( m_started_at );
944 template<
typename Result_Type >
947 using result_type = Result_Type;
951 template<
typename T,
typename =
meta::
void_t<> >
954 template<
typename T >
970 template<
typename T >
998 template<
typename Result_Type >
1001 using result_type = Result_Type;
1005 template<
typename T,
typename =
meta::
void_t<> >
1008 template<
typename T >
1024 template<
typename T >
1047 template<
typename Result_Type >
1050 template<
typename Transformer,
typename Input_Type >
1055 Transformer & transformer,
1056 expected_t< Input_Type, parse_error_t > && input )
1110 template<
typename Result_Type >
1144 template<
typename Producer,
typename Transformer >
1147 static_assert( is_producer_v<Producer>,
1148 "Producer should be a producer type" );
1149 static_assert( is_transformer_v<Transformer>,
1150 "Transformer should be a transformer type" );
1161 using expected_result_t =
typename Transformer::result_type;
1179 template<
typename Producer,
typename Transformer >
1184 Producer, Transformer >;
1187 traits_checker::is_valid_transformation_result_type,
1188 "transformation result should be either T or " 1189 "expected_t<T, error_reson_t>, not expected_t<T, parse_error_t>" );
1195 using result_type =
typename Transformer::result_type;
1198 Producer && producer,
1199 Transformer && transformer )
1229 template<
typename P,
typename T >
1272 template<
typename T,
typename =
meta::
void_t<> >
1275 template<
typename T >
1290 template<
typename T >
1309 T transformer_proxy )
1311 auto real_transformer = transformer_proxy.
template make_transformer<
1312 typename P::result_type >();
1314 using transformator_type = std::decay_t<
decltype(real_transformer) >;
1316 using producer_type = transformed_value_producer_t< P, transformator_type >;
1318 return producer_type{ std::move(producer), std::move(real_transformer) };
1348 template<
typename T,
typename =
meta::
void_t<> >
1351 template<
typename T >
1367 template<
typename T >
1398 template<
typename T,
typename =
meta::
void_t<> >
1401 template<
typename T >
1420 template<
typename T >
1473 template<
typename P,
typename C >
1476 static_assert( is_producer_v<P>,
"P should be a producer type" );
1477 static_assert( is_consumer_v<C>,
"C should be a consumer type" );
1488 template<
typename Target_Type >
1509 template<
typename P,
typename C >
1532 template<
typename Producer >
1535 static_assert( is_producer_v<Producer>,
1536 "Producer should be a producer type" );
1575 return parse_error_t{
1576 from.current_position(),
1577 error_reason_t::unconsumed_input
1582 return std::nullopt;
1597 auto s = from.size();
1598 for(; s && is_space( from[ (s-1u) ] ); --s) {}
1600 return from.substr( 0u, s );
1635 typename Subitems_Tuple >
1642 Subitems_Tuple && subitems )
1646 template<
typename Target_Type >
1716 typename Subitems_Tuple >
1723 Subitems_Tuple && subitems )
1727 template<
typename Target_Type >
1779 typename Subitems_Tuple >
1786 Subitems_Tuple && subitems )
1790 template<
typename Target_Type >
1847 typename Subitems_Tuple >
1854 Subitems_Tuple && subitems )
1858 template<
typename Target_Type >
1908 typename Subitems_Tuple >
1915 Subitems_Tuple && subitems )
1919 template<
typename Target_Type >
1961 typename Subitems_Tuple >
1967 using base_type_t::base_type_t;
1969 template<
typename Target_Type >
2008 typename Target_Type,
2009 typename Subitems_Tuple >
2018 Subitems_Tuple && subitems )
2060 typename Subitems_Tuple >
2070 std::size_t min_occurences,
2071 std::size_t max_occurences,
2072 Subitems_Tuple && subitems )
2078 template<
typename Target_Type >
2130 template<
typename Predicate >
2133 ,
protected Predicate
2136 template<
typename... Args >
2252 return m_expected == restinio::impl::to_lower_case(actual);
2435 template<
typename T,
typename Value_Accumulator >
2499 template<
typename T,
typename Value_Accumulator >
2508 if(
ch >=
'0' &&
ch <=
'9' )
2510 else if(
ch >=
'A' &&
ch <=
'F' )
2512 else if(
ch >=
'a' &&
ch <=
'f' )
2570 template<
typename T >
2598 template<
typename T >
2632 template<
typename T >
2636 "T is expected to be unsigned type" );
2663 template<
typename T >
2697 template<
typename T >
2701 "decimal_number_producer_t can be used only for signed types" );
2717 template<
typename Digits_Limit_Maker >
2747 template<
typename Digits_Limit_Maker >
2768 return static_cast<
T >( -(*
r) );
2810 template<
typename T >
2826 return this->try_parse_impl(
2828 [
this]()
noexcept {
return m_digits_limit; } );
2845 template<
typename Target_Type,
typename Value >
2847 consume( Target_Type &, Value && )
const noexcept {}
2872 template<
typename Target_Type,
typename Value >
2891 template<
typename Result_Type >
2910 template<
typename Result_Arg >
2916 template<
typename Target_Type,
typename Value >
2939 template<
typename C >
2947 template<
typename Target_Type,
typename Value >
2968 template<
typename F,
typename C >
2971 using pointer_t = F C::*;
2998 template<
typename P,
typename F,
typename C >
3020 template< std::size_t Index >
3029 template<
typename Target_Type,
typename Value >
3041 template<
typename Input_Type >
3042 struct to_lower_transformer_t;
3062 [](
unsigned char ch ) ->
char {
3077 struct to_lower_transformer_t<
char >
3078 :
public transformer_tag<
char >
3080 using input_type =
char;
3086 return restinio::impl::to_lower_case(input);
3096 template< std::size_t S >
3097 struct to_lower_transformer_t< std::array<
char, S > >
3098 :
public transformer_tag< std::array<
char, S > >
3109 [](
unsigned char ch ) ->
char {
3127 template<
typename Input_Type >
3132 return to_lower_transformer_t< Input_Type >{};
3145 template<
typename T >
3155 template<
typename Input >
3173 template<
typename Output_Type,
typename Converter >
3179 template<
typename Convert_Arg >
3193 template<
typename Input >
3199 using actual_result_t = std::decay_t<
decltype(
3200 m_converter(std::forward<Input>(input))
3204 is_appropriate_transformer_result_type<actual_result_t>::value,
3205 "the return value of converter should be either Output_Type or " 3206 "expected_t<Output_Type, error_reason_t>" );
3225 template<
typename Result_Type >
3228 using type = Result_Type;
3242 template<
typename Result_Type >
3243 using conversion_result_type_detector_t =
3262 template<
typename Converter >
3275 template<
typename Convert_Arg >
3281 template<
typename Input_Type >
3287 using output_t = output<Input_Type>;
3289 return convert_transformer_t< output_t, Converter >{ m_converter };
3292 template<
typename Input_Type >
3298 using output_t = output<Input_Type>;
3300 return convert_transformer_t< output_t, Converter >{
3301 std::move(m_converter)
3311 template<
typename It >
3354 template< std::size_t Size >
3358 static_assert( 1u < Size,
"Size is expected to greater that 1" );
3397 if( m_fragment.empty() )
3398 throw exception_t(
"'fragment' value for exact_fragment_producer_t " 3399 "can't be empty!" );
3406 return try_parse_exact_fragment( from,
3407 m_fragment.begin(), m_fragment.end() );
3417 template<
typename It >
3462 template< std::size_t Size >
3466 static_assert( 1u < Size,
"Size is expected to greater that 1" );
3479 [](
const char src ) {
3513 if( m_fragment.empty() )
3514 throw exception_t(
"'fragment' value for exact_fragment_producer_t " 3515 "can't be empty!" );
3518 for(
auto & ch : m_fragment )
3519 ch = restinio::impl::to_lower_case( ch );
3526 return try_parse_caseless_exact_fragment( from,
3527 m_fragment.begin(), m_fragment.end() );
3551 typename Target_Type,
3552 typename... Clauses >
3557 static_assert( 0 !=
sizeof...(clauses),
3558 "list of clauses can't be empty" );
3559 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3560 "all arguments for produce() should be clauses" );
3562 using producer_type_t = impl::produce_t<
3564 impl::tuple_of_entities_t<Clauses...> >;
3566 return producer_type_t{
3567 std::make_tuple(std::forward<Clauses>(clauses)...)
3593 template<
typename... Clauses >
3598 static_assert( 0 !=
sizeof...(clauses),
3599 "list of clauses can't be empty" );
3600 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3601 "all arguments for alternatives() should be clauses" );
3603 using clause_type_t = impl::alternatives_clause_t<
3604 impl::tuple_of_entities_t< Clauses... > >;
3606 return clause_type_t{
3607 std::make_tuple(std::forward<Clauses>(clauses)...)
3632 template<
typename... Clauses >
3637 static_assert( 0 !=
sizeof...(clauses),
3638 "list of clauses can't be empty" );
3639 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3640 "all arguments for maybe() should be clauses" );
3642 using clause_type_t = impl::maybe_clause_t<
3643 impl::tuple_of_entities_t<Clauses...> >;
3645 return clause_type_t{
3646 std::make_tuple(std::forward<Clauses>(clauses)...)
3674 template<
typename... Clauses >
3679 static_assert( 0 !=
sizeof...(clauses),
3680 "list of clauses can't be empty" );
3681 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3682 "all arguments for not_clause() should be clauses" );
3684 using clause_type_t = impl::not_clause_t<
3685 impl::tuple_of_entities_t<Clauses...> >;
3687 return clause_type_t{
3688 std::make_tuple(std::forward<Clauses>(clauses)...)
3716 template<
typename... Clauses >
3721 static_assert( 0 !=
sizeof...(clauses),
3722 "list of clauses can't be empty" );
3723 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3724 "all arguments for sequence() should be clauses" );
3726 using clause_type_t = impl::and_clause_t<
3727 impl::tuple_of_entities_t<Clauses...> >;
3729 return clause_type_t{
3730 std::make_tuple(std::forward<Clauses>(clauses)...)
3756 template<
typename... Clauses >
3761 static_assert( 0 !=
sizeof...(clauses),
3762 "list of clauses can't be empty" );
3763 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3764 "all arguments for sequence() should be clauses" );
3766 using clause_type_t = impl::sequence_clause_t<
3767 impl::tuple_of_entities_t< Clauses... > >;
3769 return clause_type_t{
3770 std::make_tuple(std::forward<Clauses>(clauses)...)
3819 template<
typename... Clauses >
3824 static_assert( 0 !=
sizeof...(clauses),
3825 "list of clauses can't be empty" );
3826 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3827 "all arguments for force_only_this_alternative() should " 3830 using clause_type_t = impl::forced_alternative_clause_t<
3831 impl::tuple_of_entities_t< Clauses... > >;
3833 return clause_type_t{
3834 std::make_tuple(std::forward<Clauses>(clauses)...)
3874 typename... Clauses >
3879 std::size_t min_occurences,
3886 std::size_t max_occurences,
3888 Clauses &&... clauses )
3890 static_assert( 0 !=
sizeof...(clauses),
3891 "list of clauses can't be empty" );
3892 static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
3893 "all arguments for repeat() should be clauses" );
3895 using producer_type_t = impl::repeat_clause_t<
3896 impl::tuple_of_entities_t<Clauses...> >;
3898 return producer_type_t{
3901 std::make_tuple(std::forward<Clauses>(clauses)...)
3940 return impl::symbol_producer_template_t<impl::any_symbol_predicate_t>{};
4035 return symbol_p(expected) >> skip();
4058 return caseless_symbol_p(expected) >> skip();
4079 return symbol_from_range_p(left, right) >> skip();
4097 return impl::symbol_producer_template_t< impl::is_space_predicate_t >{};
4118 return space_p() >> skip();
4157 return digit_p() >> skip();
4196 return hexdigit_p() >> skip();
4216 template<
typename T >
4255 template<
typename T >
4285 template<
typename T >
4327 template<
typename T >
4365 template<
typename T >
4370 static_assert( std::is_signed<T>::value,
4371 "decimal_number_p() can be used only for signed numeric types" );
4418 template<
typename T >
4423 static_assert( std::is_signed<T>::value,
4424 "decimal_number_p() can be used only for signed numeric types" );
4494 template<
typename F >
4501 return actual_consumer_t{ std::move(consumer) };
4523 template<
typename Container,
typename Item >
4613 template<
typename T >
4642 template<
typename T >
4715 template<
typename Converter >
4720 using converter_type = std::decay_t<Converter>;
4722 using transformer_proxy_type = impl::convert_transformer_proxy_t<
4725 return transformer_proxy_type{ std::forward<Converter>(converter) };
4751 return impl::exact_fragment_producer_t{
4752 std::string{ fragment.data(), fragment.size() }
4790 template< std::size_t Size >
4816 return impl::exact_fragment_producer_t{
4817 std::string{ fragment.data(), fragment.size() }
4849 template< std::size_t Size >
4880 return impl::caseless_exact_fragment_producer_t{
4881 std::string{ fragment.data(), fragment.size() }
4919 template< std::size_t Size >
4945 return impl::caseless_exact_fragment_producer_t{
4946 std::string{ fragment.data(), fragment.size() }
4978 template< std::size_t Size >
5020 template<
typename Producer >
5028 "Producer should be a value producer type" );
5088 const auto append_quote = [&]( std::string & dest ) {
5089 constexpr std::size_t max_quote_size = 16u;
5090 if( error.position() > 0u )
5093 const auto prefix_size = error.position() > max_quote_size ?
5094 max_quote_size : error.position();
5096 dest.append( 1u,
'"' );
5098 &from[ error.position() ] - prefix_size,
5100 dest.append(
"\" >>> " );
5103 const char problematic_symbol = error.position() < from.size() ?
5104 from[ error.position() ] :
'?';
5105 dest.append( 1u,
'\'' );
5106 if( problematic_symbol >=
'\x00' && problematic_symbol <
' ' )
5108 constexpr char hex_digits[] =
"0123456789abcdef";
5110 dest.append(
"\\x" );
5111 dest.append( 1u, hex_digits[
5112 static_cast<
unsigned char>(problematic_symbol) >> 4 ] );
5113 dest.append( 1u, hex_digits[
5114 static_cast<
unsigned char>(problematic_symbol) & 0xfu ] );
5117 dest.append( 1u, problematic_symbol );
5119 dest.append( 1u,
'\'' );
5121 if( error.position() + 1u < from.size() )
5124 const auto suffix_size =
5125 error.position() + 1u + max_quote_size < from.size() ?
5126 max_quote_size : from.size() - error.position() - 1u;
5128 dest.append(
" <<< \"" );
5129 dest.append( &from[ error.position() + 1u ], suffix_size );
5130 dest.append( 1u,
'"' );
5136 const auto basic_reaction = [&](
const char * msg) {
5139 result += std::to_string( error.position() );
5141 append_quote( result );
5147 basic_reaction(
"unexpected character" );
5150 case error_reason_t::unexpected_eof:
5151 result +=
"unexpected EOF at ";
5152 result += std::to_string( error.position() );
5156 basic_reaction(
"appropriate alternative can't found" );
5160 basic_reaction(
"expected pattern is not found" );
5164 basic_reaction(
"unconsumed input found" );
5168 basic_reaction(
"some illegal value found" );
5172 basic_reaction(
"forced selection alternative failed" );
expected_t< bool, parse_error_t > try_parse(source_t &from)
expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
Subitems_Tuple m_subitems
hexadecimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
auto exact_p(const char(&fragment)[Size])
A factory function that creates an instance of exact_fragment_producer.
Unexpected end of input is encontered when some character expected.
expected_t< bool, parse_error_t > try_parse(source_t &from)
A producer for the case when a decimal digit is expected in the input stream.
A special base class to be used with consumers.
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.
auto operator>>(P producer, T transformer_proxy)
A special operator to connect a value producer with value transformer via transformer-proxy.
std::optional< parse_error_t > try_process(source_t &from, Target_Type &)
expected_t< bool, parse_error_t > try_parse(source_t &from)
A producer for the case when a number in hexadecimal form is expected in the input stream...
void consume(Target_Type &dest, Value &&src) const noexcept(noexcept(m_consumer(dest, std::forward< Value >(src))))
A helper template for the detection of type to be produced as conversion procedure.
error_reason_t
Reason of parsing error.
A predicate for cases where char to be expected to be a decimal digit.
const position_t m_started_at
alternatives_clause_t(Subitems_Tuple &&subitems)
constexpr bool operator()(const char) const noexcept
A producer that expects a fragment in the input and produces boolean value if that fragment is found...
bool operator()(const char actual) const noexcept
std::string make_error_description(const parse_error_t &error, string_view_t from)
Make textual description of error returned by try_parse function.
repeat_clause_t(std::size_t min_occurences, std::size_t max_occurences, Subitems_Tuple &&subitems)
A producer for the case when a particual character is expected in the input stream.
digits_to_consume_t m_digits_limit
A producer for the case when any character except the specific sentinel character is expected in the ...
A producer for the case when a symbol should belong to specified range.
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.
auto maybe(Clauses &&... clauses)
A factory function to create an optional clause.
constexpr digits_to_consume_t(underlying_int_t total) noexcept
A template for producer of charachers that satisfy some predicate.
Entity is a producer of values.
static result_type && unwrap_value(wrapped_type &v)
auto as_result() noexcept
A factory function to create a as_result_consumer.
std::size_t m_position
Position in the input stream.
A template with specializations for different kind of result values and for type nothing.
bool operator()(const char actual) const noexcept
std::optional< parse_error_t > try_process(source_t &from, Target_Type &target)
underlying_int_t m_max
Maximal number of digits to consume.
Required pattern is not found in the input.
auto convert(Converter &&converter)
A factory function to create convert_transformer.
A special wrapper for std::array type to be used inside a producer during the parsing.
caseless_exact_fixed_size_fragment_producer_t(const char(&f)[Size])
expected_t< bool, parse_error_t > try_parse_exact_fragment(source_t &from, It begin, It end)
One character extracted from the input stream.
static constexpr entity_type_t entity_type
auto decimal_number_p(digits_to_consume_t digits_limit) noexcept
A factory function to create a decimal_number_producer.
auto decimal_number_p() noexcept
A factory function to create a decimal_number_producer.
auto and_clause(Clauses &&... clauses)
A factory function to create an and_clause.
A predicate for cases where char to be expected to be a hexadecimal digit.
content_consumer_t(const content_consumer_t &)=delete
auto hexdigit() noexcept
A factory function to create a clause that expects a hexadecimal digit, extracts it and then skips it...
try_parse_result_type try_parse_impl(source_t &from, Digits_Limit_Maker &&digits_limit_maker) const noexcept
std::size_t m_max_occurences
bool operator!=(const character_t &a, const character_t &b) noexcept
constexpr digits_to_consume_t(underlying_int_t min, underlying_int_t max) noexcept
auto any_symbol_p() noexcept
A factory function to create an any_symbol_producer.
string_view_t remove_trailing_spaces(string_view_t from) noexcept
Helper function for removal of trailing spaces from a string-view.
std::optional< parse_error_t > try_process(source_t &from, Target_Type &target)
constexpr bool is_clause_v
A meta-value to check whether T is a consumer type.
Entity is a transformer of a value from one type to another.
static result_type && unwrap_value(wrapped_type &v)
void consume(Target_Type &dest, Value &&) const
None of alternatives was found in the input.
A predicate for cases where a symbol should belong to specified range.
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.
A template for implementation of clause that checks and handles presence of sequence of entities in t...
auto space() noexcept
A factory function to create a clause that expects a space, extracts it and then skips it...
Entity is a transformer-proxy. It can't be used directly, only for binding a producer and transformer...
A template for implementation of clause that checks and handles presence of optional entity in the in...
A producer for the case when a number in hexadecimal form is expected in the input stream...
auto try_process(source_t &from)
static constexpr entity_type_t entity_type
auto not_clause(Clauses &&... clauses)
A factory function to create a not_clause.
static constexpr auto from_one_to_max() noexcept
Unexpected character is found in the input.
auto non_negative_decimal_number_p() noexcept
A factory function to create a non_negative_decimal_number_producer.
auto alternatives(Clauses &&... clauses)
A factory function to create an alternatives clause.
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.
bool operator()(const char actual) const noexcept
auto symbol_from_range_p(char left, char right) noexcept
A factory function to create a symbol_from_range_producer.
A predicate that allows extraction of any symbol.
A producer for the case when a hexadecimal digit is expected in the input stream. ...
static constexpr auto unlimited_max() noexcept
Get the value that means that maximum is not limited.
A consumer for the case when a specific value should be used as the result instead of the value produ...
A template for a consumer that stories values into a container.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
just_result_consumer_t(Result_Arg &&result) noexcept(noexcept(Result_Type{std::forward< Result_Arg >(result)}))
exact_fragment_producer_t(std::string fragment)
Subitems_Tuple m_subitems
not_clause_t(Subitems_Tuple &&subitems)
expected_t< Target_Type, parse_error_t > try_parse(source_t &from)
Subitems_Tuple m_subitems
static void as_result(wrapped_type &to, result_type &&what)
auto to_lower() noexcept
A factory function to create a to_lower_transformer.
auto non_negative_decimal_number_p(digits_to_consume_t digits_limit) noexcept
A factory function to create a non_negative_decimal_number_producer.
A consumer that stores a result value at the specified index in the result tuple. ...
expected_t< char, parse_error_t > try_parse(source_t &from) const noexcept
constexpr std::size_t N
A special marker that means infinite repetitions.
symbol_from_range_producer_t(char left, char right)
maybe_clause_t(Subitems_Tuple &&subitems)
Subitems_Tuple m_subitems
constexpr bool is_hexdigit(const char ch) noexcept
Is a character a hexadecimal digit?
expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
auto caseless_exact(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment clause.
std::optional< parse_error_t > try_process(source_t &from, Target_Type &target)
auto caseless_symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
auto exact(string_view_t fragment)
A factory function that creates an instance of exact_fragment clause.
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.
bool operator()(const char actual) const noexcept
and_clause_t(Subitems_Tuple &&subitems)
static try_parse_result_type try_parse_with_this_first_symbol(source_t &from, char first_symbol, Digits_Limit_Maker &&digits_limit_maker) noexcept
consume_value_clause_t(P &&producer, C &&consumer)
caseless_symbol_producer_t(char expected)
void putback() noexcept
Return one character back to the input stream.
void consume(Target_Type &dest, Value &&src) const
auto caseless_exact_p(const char(&fragment)[Size])
A factory function that creates an instance of caseless_exact_fragment_producer.
A producer that expects a fragment in the input and produces boolean value if that fragment is found...
A template for producing a value of specific type of a sequence of entities from the input stream...
A helper class to automatically return acquired content back to the input stream. ...
Subitems_Tuple m_subitems
std::size_t position() const noexcept
Get the position in the input stream where error was detected.
constexpr auto max() const noexcept
Get the maximum value.
expected_t< bool, parse_error_t > try_parse_caseless_exact_fragment(source_t &from, It begin, It end)
An alternative that should be parsed correctly or the parsing of the whole alternatives clause should...
character_t getch() noexcept
Get the next character from the input stream.
Entity is a consumer of values. It requires a value on the input and doesn't produces anything...
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.
std::enable_if_t< is_producer_v< P >, consume_value_clause_t< P, field_setter_consumer_t< F, C > > > operator>>(P producer, F C::*member_ptr)
A special operator to connect a value producer with field_setter_consumer.
constexpr bool is_transformer_proxy_v
A meta-value to check whether T is a transformer-proxy type.
constexpr bool is_digit(const char ch) noexcept
Is a character a decimal digit?
auto caseless_exact_p(string_view_t fragment)
A factory function that creates an instance of caseless_exact_fragment_producer.
error_reason_t reason() const noexcept
Get the reason of the error.
A producer that expects a fragment in the input and produces boolean value if that fragment is found...
A predicate for cases where the case-insensitive match of expected and actual symbols is required...
expected_t< T, parse_error_t > try_parse_result_type
auto produce(Clauses &&... clauses)
A factory function to create a producer that creates an instance of the target type by using specifie...
auto sequence(Clauses &&... clauses)
A factory function to create a sequence of subclauses.
std::array< T, S > m_array
auto exact(const char(&fragment)[Size])
A factory function that creates an instance of exact_fragment clause.
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...
A template for implementation of clause that selects one of alternative clauses.
auto try_parse(source_t &from) const noexcept
A template for implementation of clause that checks the presence of some entity in the input stream...
A producer that expects a fragment in the input and produces boolean value if that fragment is found...
top_level_clause_t(Producer &&producer)
any_symbol_if_not_producer_t(char sentinel)
expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept
caseless_exact_fragment_producer_t(std::string fragment)
constexpr auto min() const noexcept
Get the minimal value.
A special consumer that simply throws any value away.
constexpr bool is_transformer_v
A meta-value to check whether T is a transformer type.
Illegal value was found in the input.
const string_view_t m_data
The content to be used as "input stream".
digits_to_consume_t m_digits_limit
std::size_t m_min_occurences
static result_type && unwrap_value(wrapped_type &v)
bool eof() const noexcept
Is EOF has been reached?
Entity is a clause. It doesn't produces anything.
There are some unconsumed non-whitespace characters in the input after the completion of parsing...
constexpr bool is_space(const char ch) noexcept
If a character a space character?
exact_fixed_size_fragment_producer_t(const char(&f)[Size])
content_consumer_t()=delete
auto repeat(std::size_t min_occurences, std::size_t max_occurences, Clauses &&... clauses)
A factory function to create repetitor of subclauses.
produce_t(Subitems_Tuple &&subitems)
constexpr char HTAB
A constant for Horizontal Tab value.
A failure of parsing an alternative marked as "force only this alternative".
Subitems_Tuple m_subitems
std::enable_if_t< is_producer_v< P > &&is_consumer_v< C >, consume_value_clause_t< P, C > > operator>>(P producer, C consumer)
A special operator to connect a value producer with a value consumer.
digits_to_consume_t m_digits_limit
caseless_particular_symbol_predicate_t(char v) noexcept
non_negative_decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
void consume(Target_Type &, Value &&) const noexcept
void consume(Container &to, Item &&item)
A template for consumers that store a value to the specified field of a target object.
A special class to be used as the top level clause in parser.
auto digit() noexcept
A factory function to create a clause that expects a decimal digit, extracts it and then skips it...
A consumer for the case when the current value should be returned as the result for the producer at o...
A special base class to be used with clauses.
auto symbol_p(char expected) noexcept
A factory function to create a symbol_producer.
auto caseless_exact(const char(&fragment)[Size])
A factory function that creates an instance of caseless_exact_fragment clause.
bool operator()(const char actual) const noexcept
symbol_producer_template_t(Args &&... args)
std::optional< parse_error_t > try_process(source_t &from, Target_Type &target)
auto symbol(char expected) noexcept
A factory function to create a clause that expects the speficied symbol, extracts it and then skips i...
content_consumer_t(content_consumer_t &&)=delete
The class that implements "input stream".
void commit() noexcept
Consume all acquired content.
std::optional< parse_error_t > try_process(source_t &from, Target_Type &target)
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...
static void to_container(wrapped_type &, value_type &&) noexcept
Limits for number of digits to be extracted during parsing of decimal numbers.
auto custom_consumer(F consumer)
A factory function to create a custom_consumer.
auto hexadecimal_number_p() noexcept
A factory function to create a hexadecimal_number_producer.
Information about parsing error.
void consume(Target_Type &&to, Value &&value)
A special base class to be used with producers.
custom_consumer_t(C &&consumer)
symbol_producer_t(char expected)
source_t(string_view_t data) noexcept
Initializing constructor.
expected_t< bool, parse_error_t > try_parse(source_t &from)
std::array< char, Size-1u > m_fragment
underlying_int_t m_min
Minimal number of digits to consume.
auto exact_p(string_view_t fragment)
A factory function that creates an instance of exact_fragment_producer.
try_parse_result_type try_parse(source_t &from) const noexcept
bool operator()(const char actual) const noexcept
void consume(C &to, F &&value) const noexcept(noexcept(to.*m_ptr=std::move(value)))
A template for handling repetition of clauses.
string_view_t::size_type m_index
The current position in the input stream.
static constexpr entity_type_t entity_type
constexpr digits_to_consume_t expected_digits(digits_to_consume_t::underlying_int_t min, digits_to_consume_t::underlying_int_t max) noexcept
Create a limit for number of digits to be extracted.
constexpr bool is_consumer_v
A meta-value to check whether T is a consumer type.
parse_error_t(std::size_t position, error_reason_t reason) noexcept
Initializing constructor.
field_setter_consumer_t(pointer_t ptr) noexcept
bool operator()(const char actual) const noexcept
std::optional< parse_error_t > try_process(source_t &from, Target_Type &)
auto skip() noexcept
A factory function to create a skip_consumer.
Result_Type make_copy_of_result() const noexcept(noexcept(Result_Type{m_result}))
std::array< char, Size-1u > m_fragment
static void as_result(wrapped_type &, result_type &&) noexcept
std::optional< parse_error_t > try_process(source_t &from, Target_Type &dest)
auto caseless_symbol_p(char expected) noexcept
A factory function to create a caseless_symbol_producer.
A producer for the case when a non-negative decimal number is expected in the input stream...
A predicate for cases where exact match of expected and actual symbols is required.
decimal_number_producer_with_digits_limit_t(digits_to_consume_t digits_limit)
auto hexdigit_p() noexcept
A factory function to create a hexdigit_producer.
auto space_p() noexcept
A factory function to create a space_producer.
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 producer for the case when a particual character is expected in the input stream.
A template for implementation of clause that checks absence of some entity in the input stream...
A template for a clause that binds a value producer with value consumer.
position_t current_position() const noexcept
Get the current position in the stream.
~content_consumer_t() noexcept
content_consumer_t(source_t &from) noexcept
constexpr char SP
A constant for SPACE value.
A producer for the case when a non-negative decimal number is expected in the input stream...
auto force_only_this_alternative(Clauses &&... clauses)
An alternative that should be parsed correctly or the parsing of the whole alternatives clause should...
A template for consumers that are released by lambda/functional objects.
position_t started_at() const noexcept
A special type to be used in the case where there is no need to store produced value.
entity_type_t
A marker for distinguish different kind of entities in parser.
error_reason_t m_reason
The reason of the error.
A predicate for cases where mismatch with a particular symbol is required.
auto hexadecimal_number_p(digits_to_consume_t digits_limit) noexcept
A factory function to create a hexadecimal_number_producer.
bool operator==(const character_t &a, const character_t &b) noexcept
A metafunction for detection of actual result_value_wrapper type for T.
Subitems_Tuple m_subitems
auto to_container()
A factory function to create a to_container_consumer.
auto digit_p() noexcept
A factory function to create a digit_producer.
void backto(position_t pos) noexcept
Return the current position in the input stream at the specified position.
sequence_clause_t(Subitems_Tuple &&subitems)
auto any_symbol_if_not_p(char sentinel) noexcept
A factory function to create a any_symbol_if_not_producer.
std::optional< 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...
constexpr bool is_producer_v
A meta-value to check whether T is a producer type.
expected_t< T, parse_error_t > try_parse(source_t &from) const noexcept