Loading...
Searching...
No Matches
easy_parser.hpp
Go to the documentation of this file.
/*
* RESTinio
*/
#pragma once
#include <restinio/impl/to_lower_lut.hpp>
#include <restinio/impl/overflow_controlled_integer_accumulator.hpp>
#include <restinio/utils/tuple_algorithms.hpp>
#include <restinio/utils/metaprogramming.hpp>
#include <restinio/string_view.hpp>
#include <restinio/compiler_features.hpp>
#include <restinio/exception.hpp>
#include <restinio/optional.hpp>
#include <restinio/expected.hpp>
#include <iostream>
#include <limits>
#include <map>
#include <array>
#include <vector>
#include <cstring>
namespace restinio
{
namespace easy_parser
{
namespace meta = restinio::utils::metaprogramming;
//
// error_reason_t
//
enum class error_reason_t
{
unexpected_character,
unexpected_eof,
no_appropriate_alternative,
pattern_not_found,
unconsumed_input,
illegal_value_found,
force_only_this_alternative_failed
};
//
// parse_error_t
//
class parse_error_t
{
std::size_t m_position;
error_reason_t m_reason;
public:
parse_error_t(
std::size_t position,
error_reason_t reason ) noexcept
: m_position{ position }
, m_reason{ reason }
{}
RESTINIO_NODISCARD
std::size_t
position() const noexcept { return m_position; }
RESTINIO_NODISCARD
error_reason_t
reason() const noexcept { return m_reason; }
};
//
// nothing_t
//
struct nothing_t {};
//
// result_value_wrapper
//
template< typename T >
struct result_value_wrapper
{
using result_type = T;
using wrapped_type = result_type;
static void
as_result( wrapped_type & to, result_type && what )
{
to = std::move(what);
}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v);
}
};
//
// result_wrapper_for
//
template< typename T >
struct result_wrapper_for
{
using type = result_value_wrapper< T >;
};
template< typename T >
using result_wrapper_for_t = typename result_wrapper_for<T>::type;
template< typename T, typename... Args >
struct result_value_wrapper< std::vector< T, Args... > >
{
using result_type = std::vector< T, Args... >;
using value_type = typename result_type::value_type;
using wrapped_type = result_type;
static void
as_result( wrapped_type & to, result_type && what )
{
to = std::move(what);
}
static void
to_container( wrapped_type & to, value_type && what )
{
to.push_back( std::move(what) );
}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v);
}
};
namespace impl
{
//
// std_array_wrapper
//
template< typename T, std::size_t S >
struct std_array_wrapper
{
std::array< T, S > m_array;
std::size_t m_index{ 0u };
};
} /* namespace impl */
template< typename T, std::size_t S >
struct result_value_wrapper< std::array< T, S > >
{
using result_type = std::array< T, S >;
using value_type = typename result_type::value_type;
using wrapped_type = impl::std_array_wrapper< T, S >;
static void
as_result( wrapped_type & to, result_type && what )
{
to.m_array = std::move(what);
to.m_index = 0u;
}
static void
to_container( wrapped_type & to, value_type && what )
{
if( to.m_index >= S )
throw exception_t(
"index in the result std::array is out of range, "
"index=" + std::to_string(to.m_index) +
", size={}" + std::to_string(S) );
to.m_array[ to.m_index ] = std::move(what);
++to.m_index;
}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v.m_array);
}
};
template< typename T, std::size_t S >
struct result_wrapper_for< impl::std_array_wrapper<T, S> >
{
using type = result_value_wrapper< std::array< T, S > >;
};
template< typename Char, typename... Args >
struct result_value_wrapper< std::basic_string< Char, Args... > >
{
using result_type = std::basic_string< Char, Args... >;
using value_type = Char;
using wrapped_type = result_type;
static void
as_result( wrapped_type & to, result_type && what )
{
to = std::move(what);
}
static void
to_container( wrapped_type & to, value_type && what )
{
to.push_back( what );
}
static void
to_container( wrapped_type & to, wrapped_type && what )
{
to.append( what );
}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v);
}
};
template< typename K, typename V, typename... Args >
struct result_value_wrapper< std::map< K, V, Args... > >
{
using result_type = std::map< K, V, Args... >;
// NOTE: we can't use container_type::value_type here
// because value_type for std::map is std::pair<const K, V>,
// not just std::pair<K, V>,
using value_type = std::pair<K, V>;
using wrapped_type = result_type;
static void
as_result( wrapped_type & to, result_type && what )
{
to = std::move(what);
}
static void
to_container( wrapped_type & to, value_type && what )
{
to.emplace( std::move(what) );
}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v);
}
};
template<>
struct result_value_wrapper< nothing_t >
{
using result_type = nothing_t;
using value_type = nothing_t;
using wrapped_type = result_type;
static void
as_result( wrapped_type &, result_type && ) noexcept {}
static void
to_container( wrapped_type &, value_type && ) noexcept {}
RESTINIO_NODISCARD
static result_type &&
unwrap_value( wrapped_type & v )
{
return std::move(v);
}
};
constexpr std::size_t N = std::numeric_limits<std::size_t>::max();
//
// digits_to_consume_t
//
class digits_to_consume_t
{
public:
using underlying_int_t = std::int_fast8_t;
underlying_int_t m_min;
underlying_int_t m_max;
public:
constexpr
digits_to_consume_t( underlying_int_t total ) noexcept
: m_min{ total }
, m_max{ total }
{}
constexpr
digits_to_consume_t(
underlying_int_t min,
underlying_int_t max ) noexcept
: m_min{ min }
, m_max{ max }
{}
RESTINIO_NODISCARD
constexpr auto
min() const noexcept { return m_min; }
RESTINIO_NODISCARD
constexpr auto
max() const noexcept { return m_max; }
RESTINIO_NODISCARD
constexpr static auto
unlimited_max() noexcept
{
return std::numeric_limits<underlying_int_t>::max();
}
RESTINIO_NODISCARD
constexpr static auto
from_one_to_max() noexcept
{
return digits_to_consume_t{ 1, unlimited_max() };
}
};
RESTINIO_NODISCARD
inline constexpr digits_to_consume_t
expected_digits( digits_to_consume_t::underlying_int_t total ) noexcept
{
return { total };
}
RESTINIO_NODISCARD
inline constexpr digits_to_consume_t
expected_digits(
digits_to_consume_t::underlying_int_t min,
digits_to_consume_t::underlying_int_t max ) noexcept
{
return { min, max };
}
namespace impl
{
//
// character_t
//
struct character_t
{
bool m_eof;
char m_ch;
};
RESTINIO_NODISCARD
inline bool
operator==( const character_t & a, const character_t & b ) noexcept
{
return (a.m_eof == b.m_eof && a.m_ch == b.m_ch);
}
RESTINIO_NODISCARD
inline bool
operator!=( const character_t & a, const character_t & b ) noexcept
{
return (a.m_eof != b.m_eof || a.m_ch != b.m_ch);
}
constexpr char SP = ' ';
constexpr char HTAB = '\x09';
//
// is_space
//
RESTINIO_NODISCARD
inline constexpr bool
is_space( const char ch ) noexcept
{
return ch == SP || ch == HTAB;
}
//
// is_space_predicate_t
//
struct is_space_predicate_t
{
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return is_space(actual);
}
};
//
// is_digit
//
RESTINIO_NODISCARD
inline constexpr bool
is_digit( const char ch ) noexcept
{
return (ch >= '0' && ch <= '9');
}
//
// is_digit_predicate_t
//
struct is_digit_predicate_t
{
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return is_digit( actual );
}
};
//
// is_hexdigit
//
RESTINIO_NODISCARD
inline constexpr bool
is_hexdigit( const char ch ) noexcept
{
return (ch >= '0' && ch <= '9') ||
(ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f');
}
//
// is_hexdigit_predicate_t
//
struct is_hexdigit_predicate_t
{
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return is_hexdigit( actual );
}
};
//
// source_t
//
class source_t
{
const string_view_t m_data;
string_view_t::size_type m_index{};
public:
using position_t = string_view_t::size_type;
explicit source_t( string_view_t data ) noexcept : m_data{ data } {}
RESTINIO_NODISCARD
character_t
getch() noexcept
{
if( m_index < m_data.size() )
{
return {false, m_data[ m_index++ ]};
}
else
return {true, 0};
}
void
putback() noexcept
{
if( m_index )
--m_index;
}
RESTINIO_NODISCARD
position_t
current_position() const noexcept
{
return m_index;
}
void
backto( position_t pos ) noexcept
{
if( pos <= m_data.size() )
m_index = pos;
}
RESTINIO_NODISCARD
bool
eof() const noexcept
{
return m_index >= m_data.size();
}
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 m_data.substr( from, length );
}
class content_consumer_t
{
source_t & m_from;
const position_t m_started_at;
bool m_consumed{ false };
public :
content_consumer_t() = delete;
content_consumer_t( const content_consumer_t & ) = delete;
content_consumer_t( content_consumer_t && ) = delete;
content_consumer_t( source_t & from ) noexcept
: m_from{ from }
, m_started_at{ from.current_position() }
{}
~content_consumer_t() noexcept
{
if( !m_consumed )
m_from.backto( m_started_at );
}
position_t
started_at() const noexcept
{
return m_started_at;
}
void
commit() noexcept
{
m_consumed = true;
}
};
};
//
// entity_type_t
//
enum class entity_type_t
{
producer,
transformer,
consumer,
clause,
transformer_proxy
};
//
// producer_tag
//
template< typename Result_Type >
struct producer_tag
{
using result_type = Result_Type;
static constexpr entity_type_t entity_type = entity_type_t::producer;
};
template< typename T, typename = meta::void_t<> >
struct is_producer : public std::false_type {};
template< typename T >
struct is_producer< T, meta::void_t< decltype(T::entity_type) > >
{
static constexpr bool value = entity_type_t::producer == T::entity_type;
};
template< typename T >
constexpr bool is_producer_v = is_producer<T>::value;
//
// transformer_tag
//
template< typename Result_Type >
struct transformer_tag
{
using result_type = Result_Type;
static constexpr entity_type_t entity_type = entity_type_t::transformer;
};
template< typename T, typename = meta::void_t<> >
struct is_transformer : public std::false_type {};
template< typename T >
struct is_transformer< T, meta::void_t< decltype(T::entity_type) > >
{
static constexpr bool value = entity_type_t::transformer == T::entity_type;
};
template< typename T >
constexpr bool is_transformer_v = is_transformer<T>::value;
//
// transformer_invoker
//
template< typename Result_Type >
struct transformer_invoker
{
template< typename Transformer, typename Input_Type >
RESTINIO_NODISCARD
static Result_Type
invoke(
source_t &,
Transformer & transformer,
expected_t< Input_Type, parse_error_t > && input )
{
return transformer.transform( std::move(*input) );
}
};
template< typename Result_Type >
struct transformer_invoker< expected_t< Result_Type, error_reason_t > >
{
template< typename Transformer, typename Input_Type >
RESTINIO_NODISCARD
static expected_t< Result_Type, parse_error_t >
invoke(
// source_t is necessary to get the position in the case of an error.
source_t & source,
Transformer & transformer,
expected_t< Input_Type, parse_error_t > && input )
{
auto result = transformer.transform( std::move(*input) );
if( result )
return *result;
else
return make_unexpected( parse_error_t{
source.current_position(),
result.error()
} );
}
};
//
// is_appropriate_transformer_result_type
//
template< typename Result_Type >
struct is_appropriate_transformer_result_type
{
static constexpr bool value = true;
};
template< typename Result_Type >
struct is_appropriate_transformer_result_type<
expected_t< Result_Type, error_reason_t > >
{
static constexpr bool value = true;
};
template< typename Result_Type >
struct is_appropriate_transformer_result_type<
expected_t< Result_Type, parse_error_t > >
{
static constexpr bool value = false;
};
//
// transformed_value_producer_traits_checker
//
template< typename Producer, typename Transformer >
struct transformed_value_producer_traits_checker
{
static_assert( is_producer_v<Producer>,
"Producer should be a producer type" );
static_assert( is_transformer_v<Transformer>,
"Transformer should be a transformer type" );
using producer_result_t = std::decay_t< decltype(
std::declval<Producer &>().try_parse( std::declval<source_t &>() )
) >;
using transformation_result_t = std::decay_t< decltype(
std::declval<Transformer &>().transform(
std::move(*(std::declval<producer_result_t>())) )
) >;
using expected_result_t = typename Transformer::result_type;
static constexpr bool is_valid_transformation_result_type =
is_appropriate_transformer_result_type< expected_result_t >::value;
};
//
// transformed_value_producer_t
//
template< typename Producer, typename Transformer >
class transformed_value_producer_t
: public producer_tag< typename Transformer::result_type >
{
using traits_checker = transformed_value_producer_traits_checker<
Producer, Transformer >;
static_assert(
traits_checker::is_valid_transformation_result_type,
"transformation result should be either T or "
"expected_t<T, error_reson_t>, not expected_t<T, parse_error_t>" );
Producer m_producer;
Transformer m_transformer;
public :
using result_type = typename Transformer::result_type;
transformed_value_producer_t(
Producer && producer,
Transformer && transformer )
: m_producer{ std::move(producer) }
, m_transformer{ std::move(transformer) }
{}
RESTINIO_NODISCARD
expected_t< result_type, parse_error_t >
try_parse( source_t & source )
{
auto producer_result = m_producer.try_parse( source );
if( producer_result )
{
using transformation_result_t =
typename traits_checker::transformation_result_t;
return transformer_invoker< transformation_result_t >::invoke(
source,
m_transformer,
std::move(producer_result) );
}
else
return make_unexpected( producer_result.error() );
}
};
template< typename P, typename T >
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 )
{
using transformator_type = transformed_value_producer_t< P, T >;
return transformator_type{ std::move(producer), std::move(transformer) };
}
//
// transformer_proxy_tag
//
struct transformer_proxy_tag
{
static constexpr entity_type_t entity_type = entity_type_t::transformer_proxy;
};
template< typename T, typename = meta::void_t<> >
struct is_transformer_proxy : public std::false_type {};
template< typename T >
struct is_transformer_proxy< T, meta::void_t< decltype(T::entity_type) > >
{
static constexpr bool value = entity_type_t::transformer_proxy == T::entity_type;
};
template< typename T >
constexpr bool is_transformer_proxy_v = is_transformer_proxy<T>::value;
template<
typename P,
typename T,
typename S = std::enable_if_t<
is_producer_v<P> & is_transformer_proxy_v<T>,
void > >
RESTINIO_NODISCARD
auto
operator>>(
P producer,
T transformer_proxy )
{
auto real_transformer = transformer_proxy.template make_transformer<
typename P::result_type >();
using transformator_type = std::decay_t< decltype(real_transformer) >;
using producer_type = transformed_value_producer_t< P, transformator_type >;
return producer_type{ std::move(producer), std::move(real_transformer) };
}
//
// consumer_tag
//
struct consumer_tag
{
static constexpr entity_type_t entity_type = entity_type_t::consumer;
};
template< typename T, typename = meta::void_t<> >
struct is_consumer : public std::false_type {};
template< typename T >
struct is_consumer< T, meta::void_t< decltype(T::entity_type) > >
{
static constexpr bool value = entity_type_t::consumer == T::entity_type;
};
template< typename T >
constexpr bool is_consumer_v = is_consumer<T>::value;
//
// clause_tag
//
struct clause_tag
{
static constexpr entity_type_t entity_type = entity_type_t::clause;
};
template< typename T, typename = meta::void_t<> >
struct is_clause : public std::false_type {};
template< typename T >
struct is_clause< T, meta::void_t<
decltype(std::decay_t<T>::entity_type) > >
{
using real_type = std::decay_t<T>;
static constexpr bool value = entity_type_t::clause == real_type::entity_type;
};
template< typename T >
constexpr bool is_clause_v = is_clause<T>::value;
//
// tuple_of_entities_t
//
template< typename... Entities >
using tuple_of_entities_t = meta::rename_t<
meta::transform_t< std::decay, meta::type_list<Entities...> >,
std::tuple >;
//
// consume_value_clause_t
//
template< typename P, typename C >
class consume_value_clause_t : public clause_tag
{
static_assert( is_producer_v<P>, "P should be a producer type" );
static_assert( is_consumer_v<C>, "C should be a consumer type" );
P m_producer;
C m_consumer;
public :
consume_value_clause_t( P && producer, C && consumer )
: m_producer{ std::move(producer) }
, m_consumer{ std::move(consumer) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & target )
{
auto parse_result = m_producer.try_parse( from );
if( parse_result )
{
m_consumer.consume( target, std::move(*parse_result) );
return nullopt;
}
else
return parse_result.error();
}
};
template< typename P, typename C >
RESTINIO_NODISCARD
std::enable_if_t<
is_producer_v<P> && is_consumer_v<C>,
consume_value_clause_t< P, C > >
operator>>( P producer, C consumer )
{
return { std::move(producer), std::move(consumer) };
}
//
// top_level_clause_t
//
template< typename Producer >
class top_level_clause_t
{
static_assert( is_producer_v<Producer>,
"Producer should be a producer type" );
Producer m_producer;
public :
top_level_clause_t( Producer && producer )
: m_producer{ std::move(producer) }
{}
RESTINIO_NODISCARD
auto
try_process( source_t & from )
{
return m_producer.try_parse( from );
}
};
//
// ensure_no_remaining_content
//
RESTINIO_NODISCARD
inline optional_t< parse_error_t >
ensure_no_remaining_content(
source_t & from )
{
while( !from.eof() )
{
if( !is_space( from.getch().m_ch ) )
{
from.putback(); // Otherwise current_position() will be wrong.
return parse_error_t{
from.current_position(),
error_reason_t::unconsumed_input
};
}
}
return nullopt;
}
//
// remove_trailing_spaces
//
RESTINIO_NODISCARD
inline string_view_t
remove_trailing_spaces( string_view_t from ) noexcept
{
auto s = from.size();
for(; s && is_space( from[ (s-1u) ] ); --s) {}
return from.substr( 0u, s );
}
//
// alternatives_clause_t
//
template<
typename Subitems_Tuple >
class alternatives_clause_t : public clause_tag
{
Subitems_Tuple m_subitems;
public :
alternatives_clause_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & target )
{
const auto starting_pos = from.current_position();
optional_t< parse_error_t > actual_parse_error;
const bool success = restinio::utils::tuple_algorithms::any_of(
m_subitems,
[&from, &target, &actual_parse_error]( auto && one_producer ) {
source_t::content_consumer_t consumer{ from };
Target_Type tmp_value{ target };
actual_parse_error = one_producer.try_process( from, tmp_value );
if( !actual_parse_error )
{
target = std::move(tmp_value);
consumer.commit();
return true;
}
else {
// Since v.0.6.7 we should check for
// force_only_this_alternative_failed error.
// In the case of that error enumeration of alternatives
// should be stopped.
return error_reason_t::force_only_this_alternative_failed ==
actual_parse_error->reason();
}
} );
if( !success || actual_parse_error )
return parse_error_t{
starting_pos,
error_reason_t::no_appropriate_alternative
};
else
return nullopt;
}
};
//
// maybe_clause_t
//
template<
typename Subitems_Tuple >
class maybe_clause_t : public clause_tag
{
Subitems_Tuple m_subitems;
public :
maybe_clause_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & target )
{
source_t::content_consumer_t consumer{ from };
Target_Type tmp_value{ target };
const bool success = restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &tmp_value]( auto && one_producer ) {
return !one_producer.try_process( from, tmp_value );
} );
if( success )
{
target = std::move(tmp_value);
consumer.commit();
}
// maybe_clause always returns success even if nothing consumed.
return nullopt;
}
};
//
// not_clause_t
//
template<
typename Subitems_Tuple >
class not_clause_t : public clause_tag
{
Subitems_Tuple m_subitems;
public :
not_clause_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & )
{
// NOTE: will always return the current position back.
source_t::content_consumer_t consumer{ from };
Target_Type dummy_value;
const auto success = !restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &dummy_value]( auto && one_producer ) {
return !one_producer.try_process( from, dummy_value );
} );
// This is contra-intuitive but: we return pattern_not_found in
// the case when pattern is actually found in the input.
if( !success )
return parse_error_t{
consumer.started_at(),
//FIXME: maybe a more appropriate error_reason can
//be used here?
error_reason_t::pattern_not_found
};
else
return nullopt;
}
};
//
// and_clause_t
//
template<
typename Subitems_Tuple >
class and_clause_t : public clause_tag
{
Subitems_Tuple m_subitems;
public :
and_clause_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & )
{
// NOTE: will always return the current position back.
source_t::content_consumer_t consumer{ from };
Target_Type dummy_value;
const bool success = restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &dummy_value]( auto && one_producer ) {
return !one_producer.try_process( from, dummy_value );
} );
if( !success )
return parse_error_t{
consumer.started_at(),
error_reason_t::pattern_not_found
};
else
return nullopt;
}
};
//
// sequence_clause_t
//
template<
typename Subitems_Tuple >
class sequence_clause_t : public clause_tag
{
Subitems_Tuple m_subitems;
public :
sequence_clause_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & target )
{
source_t::content_consumer_t consumer{ from };
Target_Type tmp_value{ target };
// We should store actual parse error from subitems to return it.
optional_t< parse_error_t > result;
const bool success = restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &tmp_value, &result]( auto && one_producer ) {
result = one_producer.try_process( from, tmp_value );
return !result;
} );
if( success )
{
target = std::move(tmp_value);
consumer.commit();
}
return result;
}
};
//
// forced_alternative_clause_t
//
template<
typename Subitems_Tuple >
class forced_alternative_clause_t : public sequence_clause_t< Subitems_Tuple >
{
using base_type_t = sequence_clause_t< Subitems_Tuple >;
public :
using base_type_t::base_type_t;
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & target )
{
const auto starting_pos = from.current_position();
if( base_type_t::try_process( from, target ) )
{
// The forced clause is not parsed correctly.
// So the special error code should be returned in that case.
return parse_error_t{
starting_pos,
error_reason_t::force_only_this_alternative_failed
};
}
else
return nullopt;
}
};
//
// produce_t
//
template<
typename Target_Type,
typename Subitems_Tuple >
class produce_t : public producer_tag< Target_Type >
{
using value_wrapper_t = result_value_wrapper< Target_Type >;
Subitems_Tuple m_subitems;
public :
produce_t(
Subitems_Tuple && subitems )
: m_subitems{ std::move(subitems) }
{}
RESTINIO_NODISCARD
expected_t< Target_Type, parse_error_t >
try_parse( source_t & from )
{
typename value_wrapper_t::wrapped_type tmp_value{};
optional_t< parse_error_t > error;
const bool success = restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &tmp_value, &error]( auto && one_clause ) {
error = one_clause.try_process( from, tmp_value );
return !error;
} );
if( success )
return value_wrapper_t::unwrap_value( tmp_value );
else
return make_unexpected( *error );
}
};
//
// repeat_clause_t
//
template<
typename Subitems_Tuple >
class repeat_clause_t : public clause_tag
{
std::size_t m_min_occurences;
std::size_t m_max_occurences;
Subitems_Tuple m_subitems;
public :
repeat_clause_t(
std::size_t min_occurences,
std::size_t max_occurences,
Subitems_Tuple && subitems )
: m_min_occurences{ min_occurences }
, m_max_occurences{ max_occurences }
, m_subitems{ std::move(subitems) }
{}
template< typename Target_Type >
RESTINIO_NODISCARD
optional_t< parse_error_t >
try_process( source_t & from, Target_Type & dest )
{
source_t::content_consumer_t whole_consumer{ from };
std::size_t count{};
bool failure_detected{ false };
for(; !failure_detected && count != m_max_occurences; )
{
source_t::content_consumer_t item_consumer{ from };
failure_detected = !restinio::utils::tuple_algorithms::all_of(
m_subitems,
[&from, &dest]( auto && one_clause ) {
return !one_clause.try_process( from, dest );
} );
if( !failure_detected )
{
// Another item successfully parsed and should be stored.
item_consumer.commit();
++count;
}
}
if( count >= m_min_occurences )
{
whole_consumer.commit();
return nullopt;
}
return parse_error_t{
from.current_position(),
error_reason_t::pattern_not_found
};
}
};
//
// symbol_producer_template_t
//
template< typename Predicate >
class symbol_producer_template_t
: public producer_tag< char >
, protected Predicate
{
public:
template< typename... Args >
symbol_producer_template_t( Args &&... args )
: Predicate{ std::forward<Args>(args)... }
{}
RESTINIO_NODISCARD
expected_t< char, parse_error_t >
try_parse( source_t & from ) const noexcept
{
const auto ch = from.getch();
if( !ch.m_eof )
{
// A call to predicate.
if( (*this)(ch.m_ch) )
return ch.m_ch;
else
{
from.putback();
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::unexpected_character
} );
}
}
else
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::unexpected_eof
} );
}
};
//
// any_symbol_predicate_t
//
struct any_symbol_predicate_t
{
RESTINIO_NODISCARD
constexpr bool
operator()( const char ) const noexcept
{
return true;
}
};
//
// particular_symbol_predicate_t
//
struct particular_symbol_predicate_t
{
char m_expected;
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return m_expected == actual;
}
};
//
// not_particular_symbol_predicate_t
//
struct not_particular_symbol_predicate_t
{
char m_sentinel;
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return m_sentinel != actual;
}
};
//
// caseless_particular_symbol_predicate_t
//
struct caseless_particular_symbol_predicate_t
{
char m_expected;
caseless_particular_symbol_predicate_t( char v ) noexcept
: m_expected{ restinio::impl::to_lower_case( v ) }
{}
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return m_expected == restinio::impl::to_lower_case(actual);
}
};
//
// symbol_from_range_predicate_t
//
struct symbol_from_range_predicate_t
{
char m_left;
char m_right;
RESTINIO_NODISCARD
bool
operator()( const char actual ) const noexcept
{
return ( actual >= m_left && actual <= m_right );
}
};
//
// symbol_producer_t
//
class symbol_producer_t
: public symbol_producer_template_t< particular_symbol_predicate_t >
{
using base_type_t =
symbol_producer_template_t< particular_symbol_predicate_t >;
public:
symbol_producer_t( char expected )
: base_type_t{ particular_symbol_predicate_t{expected} }
{}
};
//
// any_symbol_if_not_producer_t
//
class any_symbol_if_not_producer_t
: public symbol_producer_template_t< not_particular_symbol_predicate_t >
{
using base_type_t =
symbol_producer_template_t< not_particular_symbol_predicate_t >;
public:
any_symbol_if_not_producer_t( char sentinel )
: base_type_t{ not_particular_symbol_predicate_t{sentinel} }
{}
};
//
// caseless_symbol_producer_t
//
class caseless_symbol_producer_t
: public symbol_producer_template_t< caseless_particular_symbol_predicate_t >
{
using base_type_t =
symbol_producer_template_t< caseless_particular_symbol_predicate_t >;
public:
caseless_symbol_producer_t( char expected )
: base_type_t{ caseless_particular_symbol_predicate_t{expected} }
{}
};
//
// symbol_from_range_producer_t
//
class symbol_from_range_producer_t
: public symbol_producer_template_t< symbol_from_range_predicate_t >
{
using base_type_t =
symbol_producer_template_t< symbol_from_range_predicate_t >;
public:
symbol_from_range_producer_t( char left, char right )
: base_type_t{ symbol_from_range_predicate_t{left, right} }
{}
};
//
// digit_producer_t
//
class digit_producer_t
: public symbol_producer_template_t< is_digit_predicate_t >
{
public:
digit_producer_t() {}
};
//
// hexdigit_producer_t
//
class hexdigit_producer_t
: public symbol_producer_template_t< is_hexdigit_predicate_t >
{
public:
hexdigit_producer_t() {}
};
//
// try_parse_digits_with_digits_limit
//
template< typename T, typename Value_Accumulator >
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
{
source_t::content_consumer_t consumer{ from };
digits_to_consume_t::underlying_int_t symbols_processed{};
for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
{
if( is_digit(ch.m_ch) )
{
acc.next_digit( static_cast<T>(ch.m_ch - '0') );
if( acc.overflow_detected() )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::illegal_value_found
} );
++symbols_processed;
if( symbols_processed == digits_limit.max() )
break;
}
else
{
from.putback();
break;
}
}
if( symbols_processed < digits_limit.min() )
// Not all required digits are extracted.
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::pattern_not_found
} );
else
{
consumer.commit();
return acc.value();
}
}
//
// try_parse_hexdigits_with_digits_limit
//
template< typename T, typename Value_Accumulator >
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
{
const auto ch_to_digit = []( char ch ) -> std::pair<bool, T> {
if( ch >= '0' && ch <= '9' )
return std::make_pair( true, static_cast<T>(ch - '0') );
else if( ch >= 'A' && ch <= 'F' )
return std::make_pair( true, static_cast<T>(10 + (ch - 'A')) );
else if( ch >= 'a' && ch <= 'f' )
return std::make_pair( true, static_cast<T>(10 + (ch - 'a')) );
else
return std::make_pair( false, static_cast<T>(0) );
};
source_t::content_consumer_t consumer{ from };
digits_to_consume_t::underlying_int_t symbols_processed{};
for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
{
const auto d = ch_to_digit( ch.m_ch );
if( d.first )
{
acc.next_digit( d.second );
if( acc.overflow_detected() )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::illegal_value_found
} );
++symbols_processed;
if( symbols_processed == digits_limit.max() )
break;
}
else
{
from.putback();
break;
}
}
if( symbols_processed < digits_limit.min() )
// Not all required digits are extracted.
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::pattern_not_found
} );
else
{
consumer.commit();
return acc.value();
}
}
//
// non_negative_decimal_number_producer_t
//
template< typename T >
class non_negative_decimal_number_producer_t : public producer_tag< T >
{
public:
RESTINIO_NODISCARD
expected_t< T, parse_error_t >
try_parse( source_t & from ) const noexcept
{
return try_parse_digits_with_digits_limit< T >(
from,
digits_to_consume_t::from_one_to_max(),
restinio::impl::overflow_controlled_integer_accumulator_t<T, 10>{} );
}
};
//
// non_negative_decimal_number_producer_with_digits_limit_t
//
template< typename T >
class non_negative_decimal_number_producer_with_digits_limit_t
: public non_negative_decimal_number_producer_t<T>
{
digits_to_consume_t m_digits_limit;
public:
non_negative_decimal_number_producer_with_digits_limit_t(
digits_to_consume_t digits_limit )
: m_digits_limit{ digits_limit }
{}
RESTINIO_NODISCARD
expected_t< T, parse_error_t >
try_parse( source_t & from ) const noexcept
{
return try_parse_digits_with_digits_limit< T >(
from,
m_digits_limit,
restinio::impl::overflow_controlled_integer_accumulator_t<T, 10>{} );
}
};
//
// hexadecimal_number_producer_t
//
template< typename T >
class hexadecimal_number_producer_t : public producer_tag< T >
{
static_assert( std::is_unsigned<T>::value,
"T is expected to be unsigned type" );
public:
RESTINIO_NODISCARD
expected_t< T, parse_error_t >
try_parse( source_t & from ) const noexcept
{
return try_parse_hexdigits_with_digits_limit< T >(
from,
digits_to_consume_t::from_one_to_max(),
restinio::impl::overflow_controlled_integer_accumulator_t<T, 16>{} );
}
};
//
// hexadecimal_number_producer_with_digits_limit_t
//
template< typename T >
class hexadecimal_number_producer_with_digits_limit_t
: public hexadecimal_number_producer_t< T >
{
digits_to_consume_t m_digits_limit;
public:
hexadecimal_number_producer_with_digits_limit_t(
digits_to_consume_t digits_limit )
: m_digits_limit{ digits_limit }
{}
RESTINIO_NODISCARD
expected_t< T, parse_error_t >
try_parse( source_t & from ) const noexcept
{
return try_parse_hexdigits_with_digits_limit< T >(
from,
m_digits_limit,
restinio::impl::overflow_controlled_integer_accumulator_t<T, 16>{} );
}
};
//
// decimal_number_producer_t
//
template< typename T >
class decimal_number_producer_t : public producer_tag<T>
{
static_assert( std::is_signed<T>::value,
"decimal_number_producer_t can be used only for signed types" );
public:
using try_parse_result_type = expected_t< T, parse_error_t >;
RESTINIO_NODISCARD
try_parse_result_type
try_parse( source_t & from ) const noexcept
{
return try_parse_impl( from,
[]() noexcept {
return digits_to_consume_t::from_one_to_max();
} );
}
protected:
template< typename Digits_Limit_Maker >
RESTINIO_NODISCARD
try_parse_result_type
try_parse_impl(
source_t & from,
Digits_Limit_Maker && digits_limit_maker ) const noexcept
{
source_t::content_consumer_t consumer{ from };
auto sign_ch = from.getch();
if( !sign_ch.m_eof )
{
const auto r = try_parse_with_this_first_symbol(
from,
sign_ch.m_ch,
std::forward<Digits_Limit_Maker>(digits_limit_maker) );
if( r )
consumer.commit();
return r;
}
else
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::pattern_not_found
} );
}
private:
template< typename Digits_Limit_Maker >
RESTINIO_NODISCARD
static try_parse_result_type
try_parse_with_this_first_symbol(
source_t & from,
char first_symbol,
Digits_Limit_Maker && digits_limit_maker ) noexcept
{
using restinio::impl::overflow_controlled_integer_accumulator_t;
using restinio::impl::check_negative_extremum;
if( '-' == first_symbol )
{
const auto r = try_parse_digits_with_digits_limit< T >(
from,
digits_limit_maker(),
overflow_controlled_integer_accumulator_t<
T,
10,
check_negative_extremum >{} );
if( r )
return static_cast< T >( -(*r) ); // This static_cast is required
// for clang compiler that warns that if type of *r is `short`,
// then -(*r) will have type `int`.
else
return r;
}
else if( '+' == first_symbol )
{
return try_parse_digits_with_digits_limit< T >(
from,
digits_limit_maker(),
overflow_controlled_integer_accumulator_t< T, 10 >{} );
}
else if( is_digit(first_symbol) )
{
from.putback();
return try_parse_digits_with_digits_limit< T >(
from,
digits_limit_maker(),
overflow_controlled_integer_accumulator_t< T, 10 >{} );
}
return make_unexpected( parse_error_t{
from.current_position(),
error_reason_t::pattern_not_found
} );
}
};
//
// decimal_number_producer_with_digits_limit_t
//
template< typename T >
class decimal_number_producer_with_digits_limit_t
: public decimal_number_producer_t< T >
{
digits_to_consume_t m_digits_limit;
public:
decimal_number_producer_with_digits_limit_t(
digits_to_consume_t digits_limit )
: m_digits_limit{ digits_limit }
{}
RESTINIO_NODISCARD
auto
try_parse( source_t & from ) const noexcept
{
return this->try_parse_impl(
from,
[this]() noexcept { return m_digits_limit; } );
}
};
//
// any_value_skipper_t
//
struct any_value_skipper_t : public consumer_tag
{
template< typename Target_Type, typename Value >
void
consume( Target_Type &, Value && ) const noexcept {}
};
//
// as_result_consumer_t
//
struct as_result_consumer_t : public consumer_tag
{
template< typename Target_Type, typename Value >
void
consume( Target_Type & dest, Value && src ) const
{
result_wrapper_for_t<Target_Type>::as_result(
dest, std::forward<Value>(src) );
}
};
//
// just_result_consumer_t
//
template< typename Result_Type >
class just_result_consumer_t : public consumer_tag
{
Result_Type m_result;
// NOTE: this helper method is necessary for MSVC++ compiler.
// It's because MSVC++ can't compile expression:
//
// as_result(dest, Result_Type{m_result})
//
// in consume() method for trivial types like size_t.
Result_Type
make_copy_of_result() const
noexcept(noexcept(Result_Type{m_result}))
{
return m_result;
}
public :
template< typename Result_Arg >
just_result_consumer_t( Result_Arg && result )
noexcept(noexcept(Result_Type{std::forward<Result_Arg>(result)}))
: m_result{ std::forward<Result_Arg>(result) }
{}
template< typename Target_Type, typename Value >
void
consume( Target_Type & dest, Value && ) const
{
result_wrapper_for_t<Target_Type>::as_result(
dest,
// NOTE: use a copy of m_result.
make_copy_of_result() );
}
};
//
// custom_consumer_t
//
template< typename C >
class custom_consumer_t : public consumer_tag
{
C m_consumer;
public :
custom_consumer_t( C && consumer ) : m_consumer{std::move(consumer)} {}
template< typename Target_Type, typename Value >
void
consume( Target_Type & dest, Value && src ) const
noexcept(noexcept(m_consumer(dest, std::forward<Value>(src))))
{
m_consumer( dest, std::forward<Value>(src) );
}
};
//
// field_setter_consumer_t
//
template< typename F, typename C >
class field_setter_consumer_t : public consumer_tag
{
using pointer_t = F C::*;
pointer_t m_ptr;
public :
field_setter_consumer_t( pointer_t ptr ) noexcept : m_ptr{ptr} {}
// NOTE: it seems that this method won't be compiled if
// result_value_wrapper::result_type differs from
// result_value_wrapper::wrapped_type.
//
// This is not a problem for the current version.
// But this moment would require more attention in the future.
void
consume( C & to, F && value ) const
noexcept(noexcept(to.*m_ptr = std::move(value)))
{
to.*m_ptr = std::move(value);
}
};
template< typename P, typename F, typename C >
RESTINIO_NODISCARD
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 )
{
return {
std::move(producer),
field_setter_consumer_t<F,C>{ member_ptr }
};
}
//
// tuple_item_consumer_t
//
template< std::size_t Index >
struct tuple_item_consumer_t : public consumer_tag
{
// NOTE: it seems that this method won't be compiled if
// result_value_wrapper::result_type differs from
// result_value_wrapper::wrapped_type.
//
// This is not a problem for the current version.
// But this moment would require more attention in the future.
template< typename Target_Type, typename Value >
void
consume( Target_Type && to, Value && value )
{
std::get<Index>(std::forward<Target_Type>(to)) =
std::forward<Value>(value);
}
};
//
// to_lower_transformer_t
//
template< typename Input_Type >
struct to_lower_transformer_t;
template<>
struct to_lower_transformer_t< std::string >
: public transformer_tag< std::string >
{
using input_type = std::string;
RESTINIO_NODISCARD
result_type
transform( input_type && input ) const noexcept
{
result_type result{ std::move(input) };
std::transform( result.begin(), result.end(), result.begin(),
[]( unsigned char ch ) -> char {
return restinio::impl::to_lower_case(ch);
} );
return result;
}
};
template<>
struct to_lower_transformer_t< char >
: public transformer_tag< char >
{
using input_type = char;
RESTINIO_NODISCARD
result_type
transform( input_type && input ) const noexcept
{
return restinio::impl::to_lower_case(input);
}
};
template< std::size_t S >
struct to_lower_transformer_t< std::array< char, S > >
: public transformer_tag< std::array< char, S > >
{
using input_type = std::array< char, S >;
using base_type = transformer_tag< input_type >;
RESTINIO_NODISCARD
typename base_type::result_type
transform( input_type && input ) const noexcept
{
typename base_type::result_type result;
std::transform( input.begin(), input.end(), result.begin(),
[]( unsigned char ch ) -> char {
return restinio::impl::to_lower_case(ch);
} );
return result;
}
};
//
// to_lower_transformer_proxy_t
//
struct to_lower_transformer_proxy_t : public transformer_proxy_tag
{
template< typename Input_Type >
RESTINIO_NODISCARD
auto
make_transformer() const noexcept
{
return to_lower_transformer_t< Input_Type >{};
}
};
//
// just_value_transformer_t
//
template< typename T >
class just_value_transformer_t : public transformer_tag< T >
{
T m_value;
public :
just_value_transformer_t( T v ) noexcept(noexcept(T{std::move(v)}))
: m_value{ std::move(v) }
{}
template< typename Input >
RESTINIO_NODISCARD
T
transform( Input && ) const noexcept(noexcept(T{m_value}))
{
return m_value;
}
};
//
// convert_transformer_t
//
template< typename Output_Type, typename Converter >
class convert_transformer_t : public transformer_tag< Output_Type >
{
Converter m_converter;
public :
template< typename Convert_Arg >
convert_transformer_t( Convert_Arg && converter )
noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
: m_converter{ std::forward<Convert_Arg>(converter) }
{}
template< typename Input >
RESTINIO_NODISCARD
auto
transform( Input && input ) const
noexcept(noexcept(m_converter(std::forward<Input>(input))))
{
using actual_result_t = std::decay_t< decltype(
m_converter(std::forward<Input>(input))
) >;
static_assert(
is_appropriate_transformer_result_type<actual_result_t>::value,
"the return value of converter should be either Output_Type or "
"expected_t<Output_Type, error_reason_t>" );
return m_converter(std::forward<Input>(input));
}
};
//
// conversion_result_type_detector
//
template< typename Result_Type >
struct conversion_result_type_detector
{
using type = Result_Type;
};
template< typename Result_Type >
struct conversion_result_type_detector< expected_t< Result_Type, error_reason_t > >
{
using type = Result_Type;
};
template< typename Result_Type >
using conversion_result_type_detector_t =
typename conversion_result_type_detector<Result_Type>::type;
//
// convert_transformer_proxy_t
//
template< typename Converter >
class convert_transformer_proxy_t : public transformer_proxy_tag
{
template< typename Input_Type >
using output = conversion_result_type_detector_t<
std::decay_t< decltype(
std::declval<Converter &>()(std::declval<Input_Type&&>())
) >
>;
Converter m_converter;
public :
template< typename Convert_Arg >
convert_transformer_proxy_t( Convert_Arg && converter )
noexcept(noexcept(Converter{std::forward<Convert_Arg>(converter)}))
: m_converter{ std::forward<Convert_Arg>(converter) }
{}
template< typename Input_Type >
RESTINIO_NODISCARD
auto
make_transformer() const &
noexcept(noexcept(Converter{m_converter}))
{
using output_t = output<Input_Type>;
return convert_transformer_t< output_t, Converter >{ m_converter };
}
template< typename Input_Type >
RESTINIO_NODISCARD
auto
make_transformer() &&
noexcept(noexcept(Converter{std::move(m_converter)}))
{
using output_t = output<Input_Type>;
return convert_transformer_t< output_t, Converter >{
std::move(m_converter)
};
}
};
//
// try_parse_exact_fragment
//
// Requires that begin is not equal to end.
template< typename It >
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse_exact_fragment( source_t & from, It begin, It end )
{
assert( begin != end );
source_t::content_consumer_t consumer{ from };
for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
{
if( ch.m_ch != *begin )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::pattern_not_found
} );
if( ++begin == end )
break;
}
if( begin != end )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::unexpected_eof
} );
consumer.commit();
return true;
}
//
// exact_fixed_size_fragment_producer_t
//
template< std::size_t Size >
class exact_fixed_size_fragment_producer_t
: public producer_tag< bool >
{
static_assert( 1u < Size, "Size is expected to greater that 1" );
// NOTE: there is no space for last zero-byte.
std::array< char, Size-1u > m_fragment;
public:
exact_fixed_size_fragment_producer_t( const char (&f)[Size] )
{
// NOTE: last zero-byte is discarded.
std::copy( &f[ 0 ], &f[ m_fragment.size() ], m_fragment.data() );
}
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse( source_t & from )
{
return try_parse_exact_fragment( from,
m_fragment.begin(), m_fragment.end() );
}
};
//
// exact_fragment_producer_t
//
class exact_fragment_producer_t
: public producer_tag< bool >
{
std::string m_fragment;
public:
exact_fragment_producer_t( std::string fragment )
: m_fragment{ std::move(fragment) }
{
if( m_fragment.empty() )
throw exception_t( "'fragment' value for exact_fragment_producer_t "
"can't be empty!" );
}
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse( source_t & from )
{
return try_parse_exact_fragment( from,
m_fragment.begin(), m_fragment.end() );
}
};
//
// try_parse_caseless_exact_fragment
//
// Requires that begin is not equal to end.
// It assumes that content in [begin, end) is already in lower case.
template< typename It >
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse_caseless_exact_fragment( source_t & from, It begin, It end )
{
assert( begin != end );
source_t::content_consumer_t consumer{ from };
for( auto ch = from.getch(); !ch.m_eof; ch = from.getch() )
{
if( restinio::impl::to_lower_case(ch.m_ch) != *begin )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::pattern_not_found
} );
if( ++begin == end )
break;
}
if( begin != end )
return make_unexpected( parse_error_t{
consumer.started_at(),
error_reason_t::unexpected_eof
} );
consumer.commit();
return true;
}
//
// caseless_exact_fixed_size_fragment_producer_t
//
template< std::size_t Size >
class caseless_exact_fixed_size_fragment_producer_t
: public producer_tag< bool >
{
static_assert( 1u < Size, "Size is expected to greater that 1" );
// NOTE: there is no space for last zero-byte.
std::array< char, Size-1u > m_fragment;
public:
caseless_exact_fixed_size_fragment_producer_t( const char (&f)[Size] )
{
// Content should be converted to lower-case.
// NOTE: last zero-byte is discarded.
std::transform(
&f[ 0 ], &f[ m_fragment.size() ],
m_fragment.data(),
[]( const char src ) {
return restinio::impl::to_lower_case( src );
} );
}
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse( source_t & from )
{
return try_parse_caseless_exact_fragment( from,
m_fragment.begin(), m_fragment.end() );
}
};
//
// caseless_exact_fragment_producer_t
//
class caseless_exact_fragment_producer_t
: public producer_tag< bool >
{
std::string m_fragment;
public:
caseless_exact_fragment_producer_t( std::string fragment )
: m_fragment{ std::move(fragment) }
{
if( m_fragment.empty() )
throw exception_t( "'fragment' value for exact_fragment_producer_t "
"can't be empty!" );
// Content should be converted to lower-case.
for( auto & ch : m_fragment )
ch = restinio::impl::to_lower_case( ch );
}
RESTINIO_NODISCARD
expected_t< bool, parse_error_t >
try_parse( source_t & from )
{
return try_parse_caseless_exact_fragment( from,
m_fragment.begin(), m_fragment.end() );
}
};
} /* namespace impl */
//
// produce
//
template<
typename Target_Type,
typename... Clauses >
RESTINIO_NODISCARD
auto
produce( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for produce() should be clauses" );
using producer_type_t = impl::produce_t<
Target_Type,
impl::tuple_of_entities_t<Clauses...> >;
return producer_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// alternatives
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
alternatives( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for alternatives() should be clauses" );
using clause_type_t = impl::alternatives_clause_t<
impl::tuple_of_entities_t< Clauses... > >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// maybe
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
maybe( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for maybe() should be clauses" );
using clause_type_t = impl::maybe_clause_t<
impl::tuple_of_entities_t<Clauses...> >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// not_clause
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
not_clause( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for not_clause() should be clauses" );
using clause_type_t = impl::not_clause_t<
impl::tuple_of_entities_t<Clauses...> >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// and_clause
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
and_clause( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for sequence() should be clauses" );
using clause_type_t = impl::and_clause_t<
impl::tuple_of_entities_t<Clauses...> >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// sequence
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
sequence( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for sequence() should be clauses" );
using clause_type_t = impl::sequence_clause_t<
impl::tuple_of_entities_t< Clauses... > >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// force_only_this_alternative
//
template< typename... Clauses >
RESTINIO_NODISCARD
auto
force_only_this_alternative( Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for force_only_this_alternative() should "
"be clauses" );
using clause_type_t = impl::forced_alternative_clause_t<
impl::tuple_of_entities_t< Clauses... > >;
return clause_type_t{
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// repeat
//
template<
typename... Clauses >
RESTINIO_NODISCARD
auto
repeat(
std::size_t min_occurences,
std::size_t max_occurences,
Clauses &&... clauses )
{
static_assert( 0 != sizeof...(clauses),
"list of clauses can't be empty" );
static_assert( meta::all_of_v< impl::is_clause, Clauses... >,
"all arguments for repeat() should be clauses" );
using producer_type_t = impl::repeat_clause_t<
impl::tuple_of_entities_t<Clauses...> >;
return producer_type_t{
min_occurences,
max_occurences,
std::make_tuple(std::forward<Clauses>(clauses)...)
};
}
//
// skip
//
RESTINIO_NODISCARD
inline auto
skip() noexcept { return impl::any_value_skipper_t{}; }
//
// any_symbol_p
//
RESTINIO_NODISCARD
inline auto
any_symbol_p() noexcept
{
return impl::symbol_producer_template_t<impl::any_symbol_predicate_t>{};
}
//
// symbol_p
//
RESTINIO_NODISCARD
inline auto
symbol_p( char expected ) noexcept
{
return impl::symbol_producer_t{expected};
}
//
// any_symbol_if_not_p
//
RESTINIO_NODISCARD
inline auto
any_symbol_if_not_p( char sentinel ) noexcept
{
return impl::any_symbol_if_not_producer_t{sentinel};
}
//
// caseless_symbol_p
//
RESTINIO_NODISCARD
inline auto
caseless_symbol_p( char expected ) noexcept
{
return impl::caseless_symbol_producer_t{expected};
}
//
// symbol_from_range_p
//
RESTINIO_NODISCARD
inline auto
symbol_from_range_p( char left, char right ) noexcept
{
return impl::symbol_from_range_producer_t{left, right};
}
//
// symbol
//
RESTINIO_NODISCARD
inline auto
symbol( char expected ) noexcept
{
return symbol_p(expected) >> skip();
}
//
// caseless_symbol
//
RESTINIO_NODISCARD
inline auto
caseless_symbol( char expected ) noexcept
{
return caseless_symbol_p(expected) >> skip();
}
//
// symbol_from_range
//
RESTINIO_NODISCARD
inline auto
symbol_from_range( char left, char right ) noexcept
{
return symbol_from_range_p(left, right) >> skip();
}
//
// space_p
//
RESTINIO_NODISCARD
inline auto
space_p() noexcept
{
return impl::symbol_producer_template_t< impl::is_space_predicate_t >{};
}
//
// space
//
RESTINIO_NODISCARD
inline auto
space() noexcept
{
return space_p() >> skip();
}
//
// digit_p
//
RESTINIO_NODISCARD
inline auto
digit_p() noexcept
{
return impl::digit_producer_t{};
}
//
// digit
//
RESTINIO_NODISCARD
inline auto
digit() noexcept
{
return digit_p() >> skip();
}
//
// hexdigit_p
//
RESTINIO_NODISCARD
inline auto
hexdigit_p() noexcept
{
return impl::hexdigit_producer_t{};
}
//
// hexdigit
//
RESTINIO_NODISCARD
inline auto
hexdigit() noexcept
{
return hexdigit_p() >> skip();
}
//
// non_negative_decimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
non_negative_decimal_number_p() noexcept
{
return impl::non_negative_decimal_number_producer_t<T>{};
}
//
// non_negative_decimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
non_negative_decimal_number_p( digits_to_consume_t digits_limit ) noexcept
{
return impl::non_negative_decimal_number_producer_with_digits_limit_t<T>{
digits_limit
};
}
//FIXME: remove in v.0.7.0!
//
// positive_decimal_number_p
//
template< typename T >
[[deprecated]] RESTINIO_NODISCARD
inline auto
positive_decimal_number_producer() noexcept
{
return non_negative_decimal_number_p<T>();
}
//
// hexadecimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
hexadecimal_number_p() noexcept
{
return impl::hexadecimal_number_producer_t<T>{};
}
//
// hexadecimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
hexadecimal_number_p( digits_to_consume_t digits_limit ) noexcept
{
return impl::hexadecimal_number_producer_with_digits_limit_t<T>{
digits_limit
};
}
//
// decimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
decimal_number_p() noexcept
{
static_assert( std::is_signed<T>::value,
"decimal_number_p() can be used only for signed numeric types" );
return impl::decimal_number_producer_t<T>{};
}
//
// decimal_number_p
//
template< typename T >
RESTINIO_NODISCARD
inline auto
decimal_number_p( digits_to_consume_t digits_limit ) noexcept
{
static_assert( std::is_signed<T>::value,
"decimal_number_p() can be used only for signed numeric types" );
return impl::decimal_number_producer_with_digits_limit_t<T>{
digits_limit
};
}
//
// as_result
//
RESTINIO_NODISCARD
inline auto
as_result() noexcept { return impl::as_result_consumer_t{}; }
//
// custom_consumer
//
template< typename F >
RESTINIO_NODISCARD
auto
custom_consumer( F consumer )
{
using actual_consumer_t = impl::custom_consumer_t< F >;
return actual_consumer_t{ std::move(consumer) };
}
namespace impl
{
//
// to_container_consumer_t
//
struct to_container_consumer_t : public consumer_tag
{
template< typename Container, typename Item >
void
consume( Container & to, Item && item )
{
using container_adaptor_type = result_wrapper_for_t<Container>;
container_adaptor_type::to_container( to, std::move(item) );
}
};
} /* namespace impl */
//
// to_container
//
RESTINIO_NODISCARD
inline auto
to_container()
{
return impl::to_container_consumer_t();
}
//
// to_lower
//
RESTINIO_NODISCARD
inline auto
to_lower() noexcept { return impl::to_lower_transformer_proxy_t{}; }
//
// just
//
template< typename T >
RESTINIO_NODISCARD
auto
just( T value ) noexcept(noexcept(impl::just_value_transformer_t<T>{value}))
{
return impl::just_value_transformer_t<T>{value};
}
//
// just_result
//
template< typename T >
RESTINIO_NODISCARD
auto
just_result( T value )
noexcept(noexcept(impl::just_result_consumer_t<T>{value}))
{
return impl::just_result_consumer_t<T>{value};
}
//
// convert
//
template< typename Converter >
RESTINIO_NODISCARD
auto
convert( Converter && converter )
{
using converter_type = std::decay_t<Converter>;
using transformer_proxy_type = impl::convert_transformer_proxy_t<
converter_type >;
return transformer_proxy_type{ std::forward<Converter>(converter) };
}
//
// exact_p
//
RESTINIO_NODISCARD
inline auto
exact_p( string_view_t fragment )
{
return impl::exact_fragment_producer_t{
std::string{ fragment.data(), fragment.size() }
};
}
template< std::size_t Size >
RESTINIO_NODISCARD
auto
exact_p( const char (&fragment)[Size] )
{
return impl::exact_fixed_size_fragment_producer_t<Size>{ fragment };
}
//
// exact
//
RESTINIO_NODISCARD
inline auto
exact( string_view_t fragment )
{
return impl::exact_fragment_producer_t{
std::string{ fragment.data(), fragment.size() }
} >> skip();
}
template< std::size_t Size >
RESTINIO_NODISCARD
auto
exact( const char (&fragment)[Size] )
{
return impl::exact_fixed_size_fragment_producer_t<Size>{ fragment } >> skip();
}
//
// caseless_exact_p
//
RESTINIO_NODISCARD
inline auto
caseless_exact_p( string_view_t fragment )
{
return impl::caseless_exact_fragment_producer_t{
std::string{ fragment.data(), fragment.size() }
};
}
template< std::size_t Size >
RESTINIO_NODISCARD
auto
caseless_exact_p( const char (&fragment)[Size] )
{
return impl::caseless_exact_fixed_size_fragment_producer_t<Size>{ fragment };
}
//
// caseless_exact
//
RESTINIO_NODISCARD
inline auto
caseless_exact( string_view_t fragment )
{
return impl::caseless_exact_fragment_producer_t{
std::string{ fragment.data(), fragment.size() }
} >> skip();
}
template< std::size_t Size >
RESTINIO_NODISCARD
auto
caseless_exact( const char (&fragment)[Size] )
{
return impl::caseless_exact_fixed_size_fragment_producer_t<Size>{ fragment } >> skip();
}
//
// try_parse
//
template< typename Producer >
RESTINIO_NODISCARD
expected_t< typename Producer::result_type, parse_error_t >
try_parse(
string_view_t from,
Producer producer )
{
static_assert( impl::is_producer_v<Producer>,
"Producer should be a value producer type" );
from = impl::remove_trailing_spaces( from );
impl::source_t source{ from };
auto result = impl::top_level_clause_t< Producer >{ std::move(producer) }
.try_process( source );
if( result )
{
// We should ensure that all content has been consumed.
const auto all_content_check =
impl::ensure_no_remaining_content( source );
if( all_content_check )
return make_unexpected( *all_content_check );
}
return result;
}
//
// make_error_description
//
RESTINIO_NODISCARD
inline std::string
make_error_description(
const parse_error_t & error,
string_view_t from )
{
const auto append_quote = [&]( std::string & dest ) {
constexpr std::size_t max_quote_size = 16u;
if( error.position() > 0u )
{
// How many chars we can get from right of error position?
const auto prefix_size = error.position() > max_quote_size ?
max_quote_size : error.position();
dest.append( 1u, '"' );
dest.append(
&from[ error.position() ] - prefix_size,
prefix_size );
dest.append( "\" >>> " );
}
const char problematic_symbol = error.position() < from.size() ?
from[ error.position() ] : '?';
dest.append( 1u, '\'' );
if( problematic_symbol >= '\x00' && problematic_symbol < ' ' )
{
constexpr char hex_digits[] = "0123456789abcdef";
dest.append( "\\x" );
dest.append( 1u, hex_digits[
static_cast<unsigned char>(problematic_symbol) >> 4 ] );
dest.append( 1u, hex_digits[
static_cast<unsigned char>(problematic_symbol) & 0xfu ] );
}
else
dest.append( 1u, problematic_symbol );
dest.append( 1u, '\'' );
if( error.position() + 1u < from.size() )
{
// How many chars we can get from the right of error position?
const auto suffix_size =
error.position() + 1u + max_quote_size < from.size() ?
max_quote_size : from.size() - error.position() - 1u;
dest.append( " <<< \"" );
dest.append( &from[ error.position() + 1u ], suffix_size );
dest.append( 1u, '"' );
}
};
std::string result;
const auto basic_reaction = [&](const char * msg) {
result += msg;
result += " at ";
result += std::to_string( error.position() );
result += ": ";
append_quote( result );
};
switch( error.reason() )
{
case error_reason_t::unexpected_character:
basic_reaction( "unexpected character" );
break;
case error_reason_t::unexpected_eof:
result += "unexpected EOF at ";
result += std::to_string( error.position() );
break;
case error_reason_t::no_appropriate_alternative:
basic_reaction( "appropriate alternative can't found" );
break;
case error_reason_t::pattern_not_found:
basic_reaction( "expected pattern is not found" );
break;
case error_reason_t::unconsumed_input:
basic_reaction( "unconsumed input found" );
break;
case error_reason_t::illegal_value_found:
basic_reaction( "some illegal value found" );
break;
case error_reason_t::force_only_this_alternative_failed:
basic_reaction( "forced selection alternative failed" );
break;
}
return result;
}
} /* namespace easy_parser */
} /* namespace restinio */
nonstd::optional_lite::optional
class optional
Definition: optional.hpp:932
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:3468
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:1478
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:3360
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:1537
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:1190
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:36
exception.hpp
expected.hpp
metaprogramming.hpp
Various tools for C++ metaprogramming.
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::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::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