// The Construct // // Copyright (C) The Construct Developers, Authors & Contributors // Copyright (C) 2016-2022 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_SPIRIT_QI_CHAR_H #if defined(__clang__) template struct [[clang::internal_linkage, gnu::visibility("internal")]] boost::spirit::qi::char_parser < Derived, typename boost::spirit::char_encoding::standard::char_type, typename boost::mpl::if_c::type > :primitive_parser < literal_char > { using CharEncoding = boost::spirit::char_encoding::standard; using char_type = typename CharEncoding::char_type; struct char_parser_id; template struct attribute { using type = char_type; }; template [[gnu::hot]] bool parse(Iterator &__restrict__ start, const Iterator &__restrict__ stop, Context &c, const Skipper &s, Attribute &a) const { qi::skip_over(start, stop, s); if(likely(start != stop)) { if(this->derived().test(*start, c)) { spirit::traits::assign_to(*start, a); ++start; return true; } else return false; } else return false; } }; #endif #if defined(__clang__) template<> struct [[clang::internal_linkage, gnu::visibility("internal")]] boost::spirit::qi::literal_char :char_parser < literal_char, typename char_encoding::standard::char_type, typename mpl::if_c::type > { using CharEncoding = boost::spirit::char_encoding::standard; using char_type = typename CharEncoding::char_type; using char_encoding = CharEncoding; template struct attribute { using type = typename mpl::if_c::type; }; private: char_type ch; public: template [[gnu::hot]] bool test(CharParam ch, Context &) const { static_assert(std::is_same::value); #ifndef NDEBUG ircd::always_assert(traits::ischar::call(ch)); #endif return this->ch == char_type(ch); } template info what(Context &) const { return info { "literal-char", char_encoding::toucs4(ch) }; } template literal_char(Char ch) :ch(static_cast(ch)) {} }; #endif