mirror of
https://github.com/matrix-construct/construct
synced 2024-06-20 10:58:20 +02:00
ircd::spirit: Add optimized interpositions for qi char_range / string_parse.
This commit is contained in:
parent
4d501569bc
commit
597b4d4afb
|
@ -82,13 +82,13 @@ boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, fa
|
|||
};
|
||||
|
||||
private:
|
||||
char_type ch;
|
||||
const char_type ch alignas(16);
|
||||
|
||||
public:
|
||||
template<class CharParam,
|
||||
class Context>
|
||||
[[gnu::hot]]
|
||||
bool test(CharParam ch, Context &) const
|
||||
bool test(const CharParam ch, Context &) const
|
||||
{
|
||||
static_assert(std::is_same<CharParam, char_type>::value);
|
||||
|
||||
|
@ -96,7 +96,7 @@ boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, fa
|
|||
ircd::always_assert(traits::ischar<CharParam, char_encoding>::call(ch));
|
||||
#endif
|
||||
|
||||
return this->ch == char_type(ch);
|
||||
return this->ch == ch;
|
||||
}
|
||||
|
||||
template<class Context>
|
||||
|
@ -108,9 +108,67 @@ boost::spirit::qi::literal_char<boost::spirit::char_encoding::standard, true, fa
|
|||
};
|
||||
}
|
||||
|
||||
template<class Char>
|
||||
literal_char(Char ch)
|
||||
:ch(static_cast<char_type>(ch))
|
||||
constexpr
|
||||
literal_char(const char ch)
|
||||
:ch(ch)
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
template<>
|
||||
struct [[clang::internal_linkage, gnu::visibility("internal")]]
|
||||
boost::spirit::qi::char_range<boost::spirit::char_encoding::standard, false>
|
||||
:char_parser
|
||||
<
|
||||
char_range<char_encoding::standard, false>,
|
||||
typename char_encoding::standard::char_type
|
||||
>
|
||||
{
|
||||
using CharEncoding = boost::spirit::char_encoding::standard;
|
||||
using char_type = typename CharEncoding::char_type;
|
||||
using char_encoding = CharEncoding;
|
||||
|
||||
private:
|
||||
const char_type from alignas(16);
|
||||
const char_type to alignas(16);
|
||||
|
||||
public:
|
||||
template<class CharParam,
|
||||
class Context>
|
||||
[[gnu::hot]]
|
||||
bool test(const CharParam ch_, Context &) const
|
||||
{
|
||||
using ischar = typename traits::ischar<CharParam, char_encoding>;
|
||||
using ircd::boolmask;
|
||||
|
||||
#ifndef NDEBUG
|
||||
ircd::always_assert(ischar::call(ch_));
|
||||
#endif
|
||||
|
||||
const char_type ch(ch_);
|
||||
const char_type res[2]
|
||||
{
|
||||
boolmask<char_type>(ch >= from),
|
||||
boolmask<char_type>(ch <= to),
|
||||
};
|
||||
|
||||
return res[0] & res[1];
|
||||
}
|
||||
|
||||
template<class Context>
|
||||
info what(Context &) const
|
||||
{
|
||||
return info {"char-range"};
|
||||
}
|
||||
|
||||
constexpr
|
||||
char_range(const char_type from,
|
||||
const char_type to)
|
||||
:from{from}
|
||||
,to{to}
|
||||
{
|
||||
assert(from <= to);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
46
include/ircd/spirit/qi_string.h
Normal file
46
include/ircd/spirit/qi_string.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2022 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// 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_STRING_H
|
||||
|
||||
#if defined(__clang__)
|
||||
namespace boost::spirit::qi::detail
|
||||
{
|
||||
template<class iterator,
|
||||
class attribute>
|
||||
[[gnu::always_inline]]
|
||||
inline bool
|
||||
string_parse(const char *str,
|
||||
iterator &first,
|
||||
const iterator &last,
|
||||
attribute &attr)
|
||||
{
|
||||
char ch;
|
||||
iterator it(first);
|
||||
#pragma clang loop unroll(disable) vectorize(enable)
|
||||
for(ch = *str; likely(ch != 0); ch = *str)
|
||||
{
|
||||
if(likely(it == last))
|
||||
return false;
|
||||
|
||||
if(unlikely(ch != *it))
|
||||
return false;
|
||||
|
||||
++it;
|
||||
++str;
|
||||
}
|
||||
|
||||
spirit::traits::assign_to(first, it, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
Reference in a new issue