#pragma once #include #include #include namespace abnf::detail { template struct in_variant : std::false_type {}; template struct in_variant> : std::disjunction...> {}; } namespace abnf { struct literal; struct reference; struct char_range; struct repeated; struct one_of; struct rule; using rule_part = std::variant; class grammar_base; class grammar_group; class grammar; grammar parse(std::istream & in); grammar parse(std::istream && in); grammar_group parse_group(std::istream & in); grammar_group parse_group(std::istream && in); std::ostream & operator<<(std::ostream & os, rule const & rule); std::ostream & operator<<(std::ostream & os, grammar_base const & grammar); std::ostream & operator<<(std::ostream & os, grammar const & grammar); template concept rule_part_like = detail::in_variant::value; template concept rule_like = std::is_constructible_v || std::is_same_v; }