Revert "Merge pull request #817 from saki7/modernize-char-string"

This reverts commit b6acdc57d3, reversing
changes made to 1ef37da85d.
This commit is contained in:
Nana Sakisaka
2025-09-13 08:56:57 +09:00
parent 385a9c3f06
commit 14dfeaffdc
57 changed files with 1873 additions and 13380 deletions
+23 -18
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,56 +7,62 @@
#if !defined(BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM
#include <boost/type_traits/extent.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp>
#include <boost/spirit/home/x3/char/char_set.hpp>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding>
struct any_char : char_parser<any_char<Encoding>>
{
using char_type = typename Encoding::char_type;
using encoding = Encoding;
using attribute_type = char_type;
static constexpr bool has_attribute = true;
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Context>
[[nodiscard]] static constexpr bool test(char_type ch, Context const&) noexcept
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
return encoding::ischar(ch);
return encoding::ischar(ch_);
}
[[nodiscard]] static constexpr literal_char<Encoding> operator()(char_type ch) noexcept
template <typename Char>
constexpr literal_char<Encoding> operator()(Char ch) const
{
return { ch };
}
[[nodiscard]] static constexpr literal_char<Encoding> operator()(char_type const (&ch)[2]) noexcept
template <typename Char>
constexpr literal_char<Encoding> operator()(const Char (&ch)[2]) const
{
return { ch[0] };
}
template <std::size_t N>
[[nodiscard]] static constexpr char_set<Encoding> operator()(char_type const (&ch)[N]) noexcept
template <typename Char, std::size_t N>
constexpr char_set<Encoding> operator()(const Char (&ch)[N]) const
{
return { ch };
}
[[nodiscard]] static constexpr char_range<Encoding> operator()(char_type from, char_type to) noexcept
template <typename Char>
constexpr char_range<Encoding> operator()(Char from, Char to) const
{
return { from, to };
}
[[nodiscard]] static constexpr char_range<Encoding> operator()(char_type const (&from)[2], char_type const (&to)[2]) noexcept
template <typename Char>
constexpr char_range<Encoding> operator()(Char (&from)[2], Char (&to)[2]) const
{
return { static_cast<char_type>(from[0]), static_cast<char_type>(to[0]) };
}
[[nodiscard]] static char_set<Encoding> operator()(std::basic_string_view<char_type> sv) noexcept
template <typename Char>
char_set<Encoding> operator()(std::basic_string<Char> const& s) const
{
return { std::move(sv) };
return { s };
}
};
} // boost::spirit::x3
}}}
#endif
+70 -117
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,143 +8,84 @@
#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM
#include <boost/spirit/home/x3/char/any_char.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/spirit/home/x3/char_encoding/ascii.hpp> // deprecated
#include <boost/spirit/home/x3/char_encoding/iso8859_1.hpp> // deprecated
#include <boost/spirit/home/x3/char_encoding/standard.hpp>
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
# include <boost/spirit/home/x3/char_encoding/standard_wide.hpp>
#endif
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/x3/char_encoding/unicode.hpp>
#endif
#include <type_traits>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
namespace standard
{
inline constexpr any_char<char_encoding::standard> char_{};
typedef any_char<char_encoding::standard> char_type;
constexpr auto char_ = char_type{};
inline namespace helpers
constexpr literal_char<char_encoding::standard, unused_type>
lit(char ch)
{
[[nodiscard]] constexpr literal_char<char_encoding::standard, unused_type>
lit(char ch) noexcept
{
return { ch };
}
return { ch };
}
[[nodiscard]] constexpr literal_char<char_encoding::standard, unused_type>
lit(traits::X3VagueArrayOf2Chars<char> auto const& ch) noexcept
{
return { ch[0] };
}
} // helpers
constexpr literal_char<char_encoding::standard, unused_type>
lit(wchar_t ch)
{
return { ch };
}
// If you see "no matching overload" on string literals (e.g. `"foo"`),
// you may need to include `x3/string/literal_string.hpp`.
// If you still see errors after the inclusion, that might be due to
// mixing incompatible string literals. Don't do that.
constexpr void lit(traits::CharIncompatibleWith<char> auto const*) = delete; // Mixing incompatible character types is not allowed
constexpr void lit(traits::CharIncompatibleWith<char> auto) = delete; // Mixing incompatible character types is not allowed
}
inline constexpr auto const& char_ = standard::char_; // TODO: this can't overload other character types
using standard::helpers::lit;
using standard::char_type;
using standard::char_;
using standard::lit;
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
inline constexpr any_char<char_encoding::standard_wide> char_{};
typedef any_char<char_encoding::standard_wide> char_type;
constexpr auto char_ = char_type{};
inline namespace helpers
constexpr literal_char<char_encoding::standard_wide, unused_type>
lit(wchar_t ch)
{
[[nodiscard]] constexpr literal_char<char_encoding::standard_wide, unused_type>
lit(wchar_t ch) noexcept
{
return { ch };
}
[[nodiscard]] constexpr literal_char<char_encoding::standard_wide, unused_type>
lit(traits::X3VagueArrayOf2Chars<wchar_t> auto const& ch) noexcept
{
return { ch[0] };
}
} // helpers
constexpr void lit(traits::CharIncompatibleWith<wchar_t> auto const*) = delete; // Mixing incompatible character types is not allowed
constexpr void lit(traits::CharIncompatibleWith<wchar_t> auto) = delete; // Mixing incompatible character types is not allowed
return { ch };
}
}
using standard_wide::helpers::lit;
#endif
#ifdef BOOST_SPIRIT_X3_UNICODE
namespace unicode
{
inline constexpr any_char<char_encoding::unicode> char_{};
inline namespace helpers
{
// TODO: add `char8_t` and `char16_t` overloads
[[nodiscard]] constexpr literal_char<char_encoding::unicode, unused_type>
lit(char32_t ch) noexcept
{
return { ch };
}
[[nodiscard]] constexpr literal_char<char_encoding::unicode, unused_type>
lit(traits::X3VagueArrayOf2Chars<char32_t> auto const& ch) noexcept
{
return { ch[0] };
}
} // helpers
constexpr void lit(traits::CharIncompatibleWith<char32_t> auto const*) = delete; // Mixing incompatible character types is not allowed
constexpr void lit(traits::CharIncompatibleWith<char32_t> auto) = delete; // Mixing incompatible character types is not allowed
}
using unicode::helpers::lit;
#endif
namespace ascii
{
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
inline constexpr any_char<char_encoding::ascii> char_{};
typedef any_char<char_encoding::ascii> char_type;
constexpr auto char_ = char_type{};
[[nodiscard, deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
constexpr literal_char<char_encoding::ascii, unused_type>
lit(char ch) noexcept
lit(char ch)
{
return { ch };
}
constexpr void lit(traits::CharIncompatibleWith<char> auto const*) = delete; // Mixing incompatible character types is not allowed
constexpr void lit(traits::CharIncompatibleWith<char> auto) = delete; // Mixing incompatible character types is not allowed
constexpr literal_char<char_encoding::ascii, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
namespace iso8859_1
{
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
inline constexpr any_char<char_encoding::iso8859_1> char_{};
typedef any_char<char_encoding::iso8859_1> char_type;
constexpr auto char_ = char_type{};
[[nodiscard, deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
constexpr literal_char<char_encoding::iso8859_1, unused_type>
lit(char ch) noexcept
lit(char ch)
{
return { ch };
}
constexpr void lit(traits::CharIncompatibleWith<char> auto const*) = delete; // Mixing incompatible character types is not allowed
constexpr void lit(traits::CharIncompatibleWith<char> auto) = delete; // Mixing incompatible character types is not allowed
constexpr literal_char<char_encoding::iso8859_1, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
namespace extension
@@ -153,23 +93,29 @@ namespace boost::spirit::x3
template <>
struct as_parser<char>
{
using type = literal_char<char_encoding::standard, unused_type>;
using value_type = type;
typedef literal_char<
char_encoding::standard, unused_type>
type;
[[nodiscard]] static constexpr type call(char ch) noexcept
typedef type value_type;
static constexpr type call(char ch)
{
return { ch };
}
};
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
template <>
struct as_parser<wchar_t>
{
using type = literal_char<char_encoding::standard_wide, unused_type>;
using value_type = type;
typedef literal_char<
char_encoding::standard_wide, unused_type>
type;
[[nodiscard]] static constexpr type call(wchar_t ch) noexcept
typedef type value_type;
static constexpr type call(wchar_t ch)
{
return { ch };
}
@@ -179,30 +125,37 @@ namespace boost::spirit::x3
template <>
struct as_parser<char [2]>
{
using type = literal_char<char_encoding::standard, unused_type>;
using value_type = type;
typedef literal_char<
char_encoding::standard, unused_type>
type;
[[nodiscard]] static constexpr type call(char const ch[]) noexcept
typedef type value_type;
static constexpr type call(char const ch[])
{
return { ch[0] };
}
};
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
template <>
struct as_parser<wchar_t [2]>
{
using type = literal_char<char_encoding::standard_wide, unused_type>;
using value_type = type;
typedef literal_char<
char_encoding::standard_wide, unused_type>
type;
[[nodiscard]] static constexpr type call(wchar_t const ch[]) noexcept
typedef type value_type;
static constexpr type call(wchar_t const ch[] )
{
return { ch[0] };
}
};
#endif
}
} // boost::spirit::x3
}}}
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,31 +8,30 @@
#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/spirit/home/x3/char_encoding/standard.hpp>
#include <boost/spirit/home/x3/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/x3/char_encoding/ascii.hpp>
#include <boost/spirit/home/x3/char_encoding/iso8859_1.hpp>
namespace boost::spirit::x3
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <typename Encoding>
struct char_class_base
{
using char_type = typename Encoding::classify_type;
typedef typename Encoding::classify_type char_type;
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
[[nodiscard]] static constexpr bool \
is(name##_tag, Char ch) noexcept \
static bool \
is(name##_tag, Char ch) \
{ \
return (Encoding::is##name) \
return Encoding::is##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
}
} \
/***/
BOOST_SPIRIT_X3_CLASSIFY(char)
BOOST_SPIRIT_X3_CLASSIFY(alnum)
@@ -53,26 +51,28 @@ namespace boost::spirit::x3
};
template <typename Encoding, typename Tag>
struct char_class : char_parser<char_class<Encoding, Tag>>
struct char_class
: char_parser<char_class<Encoding, Tag>>
{
using encoding = Encoding;
using tag = Tag;
using char_type = typename Encoding::char_type;
using attribute_type = char_type;
static constexpr bool has_attribute = true;
typedef Encoding encoding;
typedef Tag tag;
typedef typename Encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
[[nodiscard]] constexpr bool test(Char ch, Context const& context) const noexcept
bool test(Char ch, Context const& context) const
{
return encoding::ischar(ch)
&& char_class_base<Encoding>::is(
x3::get_case_compare<Encoding>(context).get_char_class_tag(tag()), ch);
get_case_compare<Encoding>(context).get_char_class_tag(tag()), ch);
}
};
#define BOOST_SPIRIT_X3_CHAR_CLASS(encoding, name) \
using name##_type = char_class<char_encoding::encoding, name##_tag>; \
inline constexpr name##_type name{};
typedef char_class<char_encoding::encoding, name##_tag> name##_type; \
constexpr name##_type name = name##_type(); \
/***/
#define BOOST_SPIRIT_X3_CHAR_CLASSES(encoding) \
namespace encoding \
@@ -89,46 +89,44 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, space) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, blank) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, upper) \
}
} \
/***/
BOOST_SPIRIT_X3_CHAR_CLASSES(standard)
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
BOOST_SPIRIT_X3_CHAR_CLASSES(standard_wide)
#endif
BOOST_SPIRIT_X3_CHAR_CLASSES(ascii)
BOOST_SPIRIT_X3_CHAR_CLASSES(iso8859_1)
#undef BOOST_SPIRIT_X3_CHAR_CLASS
#undef BOOST_SPIRIT_X3_CHAR_CLASSES
using alnum_type = standard::alnum_type;
using alpha_type = standard::alpha_type;
using digit_type = standard::digit_type;
using xdigit_type = standard::xdigit_type;
using cntrl_type = standard::cntrl_type;
using graph_type = standard::graph_type;
using lower_type = standard::lower_type;
using print_type = standard::print_type;
using punct_type = standard::punct_type;
using space_type = standard::space_type;
using blank_type = standard::blank_type;
using upper_type = standard::upper_type;
using standard::alnum_type;
using standard::alpha_type;
using standard::digit_type;
using standard::xdigit_type;
using standard::cntrl_type;
using standard::graph_type;
using standard::lower_type;
using standard::print_type;
using standard::punct_type;
using standard::space_type;
using standard::blank_type;
using standard::upper_type;
inline constexpr auto const& alnum = standard::alnum;
inline constexpr auto const& alpha = standard::alpha;
inline constexpr auto const& digit = standard::digit;
inline constexpr auto const& xdigit = standard::xdigit;
inline constexpr auto const& cntrl = standard::cntrl;
inline constexpr auto const& graph = standard::graph;
inline constexpr auto const& lower = standard::lower;
inline constexpr auto const& print = standard::print;
inline constexpr auto const& punct = standard::punct;
inline constexpr auto const& space = standard::space;
inline constexpr auto const& blank = standard::blank;
inline constexpr auto const& upper = standard::upper;
} // boost::spirit::x3
using standard::alnum;
using standard::alpha;
using standard::digit;
using standard::xdigit;
using standard::cntrl;
using standard::graph;
using standard::lower;
using standard::print;
using standard::punct;
using standard::space;
using standard::blank;
using standard::upper;
}}}
#endif
@@ -15,26 +15,29 @@
#include <iterator>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// The base char_parser
///////////////////////////////////////////////////////////////////////////
template <typename Derived>
struct char_parser : parser<Derived>
{
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Context, typename Attribute>
[[nodiscard]] constexpr bool parse(
It& first, Se const& last, Context const& context, unused_type, Attribute& attr
) const // I (saki7) don't think this can ever be noexcept, due to the nature of the operations below
template <typename Iterator, typename Context, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (first != last && this->derived().test(*first, context))
{
x3::traits::move_to(std::iter_value_t<It>{*first}, attr);
x3::traits::move_to(std::iter_value_t<Iterator>{*first}, attr);
++first;
return true;
}
return false;
}
};
} // boost::spirit::x3
}}}
#endif
+51 -54
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,73 +9,72 @@
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/x3/char/detail/basic_chset.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/support/char_set/basic_chset.hpp>
#include <ranges>
#include <string_view>
#include <type_traits>
#include <boost/type_traits/is_same.hpp>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Parser for a character range
///////////////////////////////////////////////////////////////////////////
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct char_range : char_parser<char_range<Encoding, Attribute>>
struct char_range
: char_parser< char_range<Encoding, Attribute> >
{
using char_type = typename Encoding::char_type;
using encoding = Encoding;
using attribute_type = Attribute;
static constexpr bool has_attribute = !std::is_same_v<unused_type, attribute_type>;
constexpr char_range(char_type from_, char_type to_) noexcept
: from(from_), to(to_)
{}
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
constexpr char_range(char_type from_, char_type to_)
: from(from_), to(to_) {}
template <typename Char, typename Context>
requires (std::is_convertible_v<std::remove_cvref_t<Char>, char_type>)
[[nodiscard]] constexpr bool test(Char ch_, Context const& context) const noexcept
bool test(Char ch_, Context const& context) const
{
char_type ch = static_cast<char_type>(ch_); // optimize for token based parsing
return (x3::get_case_compare<encoding>(context)(ch, from) >= 0)
&& (x3::get_case_compare<encoding>(context)(ch , to) <= 0);
char_type ch = char_type(ch_); // optimize for token based parsing
return (get_case_compare<encoding>(context)(ch, from) >= 0)
&& (get_case_compare<encoding>(context)(ch , to) <= 0);
}
char_type from, to;
};
///////////////////////////////////////////////////////////////////////////
// Parser for a character set
///////////////////////////////////////////////////////////////////////////
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct char_set : char_parser<char_set<Encoding, Attribute>>
{
using char_type = typename Encoding::char_type;
using encoding = Encoding;
using attribute_type = Attribute;
static constexpr bool has_attribute = !std::is_same_v<unused_type, attribute_type>;
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template<std::ranges::forward_range R>
constexpr char_set(R const& str)
noexcept(detail::cast_char_noexcept<std::ranges::range_value_t<R>, char_type>)
template <typename String>
char_set(String const& str)
{
static_assert(detail::cast_char_viable<std::ranges::range_value_t<R>, char_type>);
using spirit::x3::detail::cast_char;
using detail::cast_char; // ADL introduction
for (auto definition = std::ranges::begin(str); definition != std::ranges::end(str);)
auto* definition = traits::get_c_string(str);
auto ch = *definition++;
while (ch)
{
auto const ch = *definition;
auto next_definition = std::next(definition);
if (next_definition == std::ranges::end(str))
auto next = *definition++;
if (next == '-')
{
chset.set(cast_char<char_type>(ch));
break;
}
auto next_ch = *next_definition;
if (next_ch == '-')
{
next_definition = std::next(next_definition);
if (next_definition == std::ranges::end(str))
next = *definition++;
if (next == 0)
{
chset.set(cast_char<char_type>(ch));
chset.set('-');
@@ -84,47 +82,46 @@ namespace boost::spirit::x3
}
chset.set(
cast_char<char_type>(ch),
cast_char<char_type>(*next_definition)
cast_char<char_type>(next)
);
}
else
{
chset.set(cast_char<char_type>(ch));
}
definition = next_definition;
ch = next;
}
}
template <typename Char, typename Context>
[[nodiscard]] constexpr bool test(Char ch_, Context const& context) const noexcept
bool test(Char ch_, Context const& context) const
{
return x3::get_case_compare<encoding>(context).in_set(ch_, chset);
return get_case_compare<encoding>(context).in_set(ch_, chset);
}
detail::basic_chset<char_type> chset;
support::detail::basic_chset<char_type> chset;
};
template <typename Encoding, typename Attribute>
struct get_info<char_set<Encoding, Attribute>>
{
using result_type = std::string;
[[nodiscard]] constexpr std::string operator()(char_set<Encoding, Attribute> const& /* p */) const
typedef std::string result_type;
std::string operator()(char_set<Encoding, Attribute> const& /* p */) const
{
return "char-set"; // TODO: make more user-friendly
return "char-set";
}
};
template <typename Encoding, typename Attribute>
struct get_info<char_range<Encoding, Attribute>>
{
using result_type = std::string;
[[nodiscard]] constexpr std::string operator()(char_range<Encoding, Attribute> const& p) const
typedef std::string result_type;
std::string operator()(char_range<Encoding, Attribute> const& p) const
{
// TODO: make more user-friendly && make the format consistent with above
return "char_range \"" + x3::to_utf8(Encoding::toucs4(p.from)) + '-' + x3::to_utf8(Encoding::toucs4(p.to))+ '"';
return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"';
}
};
} // boost::spirit::x3
}}}
#endif
@@ -1,235 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2009 Daniel Nuffer
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_DETAIL_BASIC_CHSET_HPP
#define BOOST_SPIRIT_X3_CHAR_DETAIL_BASIC_CHSET_HPP
#include <boost/spirit/home/x3/char/detail/char_range_run.hpp>
#include <bitset>
#include <climits>
namespace boost::spirit::x3::detail
{
// basic character set implementation using char_range_run
template <typename CharT>
struct basic_chset
{
[[nodiscard]] constexpr bool
test(CharT v) const noexcept
{
return rr.test(v);
}
constexpr void
set(CharT from, CharT to) noexcept
{
rr.set(char_range<CharT>(from, to));
}
constexpr void
set(CharT c) noexcept
{
rr.set(char_range<CharT>(c, c));
}
constexpr void
clear(CharT from, CharT to) noexcept
{
rr.clear(char_range<CharT>(from, to));
}
constexpr void
clear(CharT c) noexcept
{
rr.clear(char_range<CharT>(c, c));
}
constexpr void
clear() noexcept
{
rr.clear();
}
constexpr void
inverse() noexcept
{
basic_chset inv;
inv.set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
inv -= *this;
swap(inv);
}
constexpr void
swap(basic_chset& x) noexcept
{
rr.swap(x.rr);
}
constexpr basic_chset&
operator|=(basic_chset const& x) noexcept
{
typedef typename char_range_run<CharT>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.set(*iter);
return *this;
}
constexpr basic_chset&
operator&=(basic_chset const& x) noexcept
{
basic_chset inv;
inv.set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
inv -= x;
*this -= inv;
return *this;
}
constexpr basic_chset&
operator-=(basic_chset const& x) noexcept
{
typedef typename char_range_run<CharT>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.clear(*iter);
return *this;
}
constexpr basic_chset&
operator^=(basic_chset const& x) noexcept
{
basic_chset bma = x;
bma -= *this;
*this -= x;
*this |= bma;
return *this;
}
private:
char_range_run<CharT> rr;
};
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
struct basic_chset_8bit
{
[[nodiscard]] constexpr bool
test(CharT v) const noexcept
{
return bset.test((unsigned char)v);
}
constexpr void
set(CharT from, CharT to) noexcept
{
for (int i = from; i <= to; ++i)
bset.set((unsigned char)i);
}
constexpr void
set(CharT c) noexcept
{
bset.set((unsigned char)c);
}
constexpr void
clear(CharT from, CharT to) noexcept
{
for (int i = from; i <= to; ++i)
bset.reset((unsigned char)i);
}
constexpr void
clear(CharT c) noexcept
{
bset.reset((unsigned char)c);
}
constexpr void
clear() noexcept
{
bset.reset();
}
constexpr void
inverse() noexcept
{
bset.flip();
}
constexpr void
swap(basic_chset_8bit& x) noexcept
{
std::swap(bset, x.bset);
}
constexpr basic_chset_8bit&
operator|=(basic_chset_8bit const& x) noexcept
{
bset |= x.bset;
return *this;
}
constexpr basic_chset_8bit&
operator&=(basic_chset_8bit const& x) noexcept
{
bset &= x.bset;
return *this;
}
constexpr basic_chset_8bit&
operator-=(basic_chset_8bit const& x) noexcept
{
bset &= ~x.bset;
return *this;
}
constexpr basic_chset_8bit&
operator^=(basic_chset_8bit const& x) noexcept
{
bset ^= x.bset;
return *this;
}
private:
std::bitset<256> bset;
};
/////////////////////////////////
template <>
struct basic_chset<char>
: basic_chset_8bit<char> {};
/////////////////////////////////
template <>
struct basic_chset<signed char>
: basic_chset_8bit<signed char> {};
/////////////////////////////////
template <>
struct basic_chset<unsigned char>
: basic_chset_8bit<unsigned char> {};
#endif // #if (CHAR_BIT == 8)
} // boost::spirit::x3::detail
#endif
@@ -1,18 +1,18 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
#if !defined(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)
#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
#include <type_traits>
#include <concepts>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/make_signed.hpp>
namespace boost::spirit::x3::detail
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// Here's the thing... typical encodings (except ASCII) deal with unsigned
// integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.
@@ -24,19 +24,25 @@ namespace boost::spirit::x3::detail
// optimizer will optimize the if-else branches}
template <typename TargetChar, typename SourceChar>
[[nodiscard]] constexpr TargetChar cast_char(SourceChar ch) noexcept
TargetChar cast_char(SourceChar ch)
{
if constexpr (std::is_signed_v<TargetChar> != std::is_signed_v<SourceChar>)
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
{
if constexpr (std::is_signed_v<SourceChar>)
if (is_signed<SourceChar>::value)
{
// source is signed, target is unsigned
return TargetChar(static_cast<std::make_unsigned_t<SourceChar>>(ch));
// source is signed, target is unsigned
typedef typename make_unsigned<SourceChar>::type USourceChar;
return TargetChar(USourceChar(ch));
}
else
{
// source is unsigned, target is signed
return TargetChar(static_cast<std::make_signed_t<SourceChar>>(ch));
// source is unsigned, target is signed
typedef typename make_signed<SourceChar>::type SSourceChar;
return TargetChar(SSourceChar(ch));
}
}
else
@@ -44,17 +50,12 @@ namespace boost::spirit::x3::detail
// source and target has same signedness
return TargetChar(ch); // just cast
}
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
}
template <typename SourceChar, typename TargetChar>
concept cast_char_viable = requires(SourceChar ch) {
{ cast_char<TargetChar>(ch) } -> std::convertible_to<TargetChar>;
};
template <typename SourceChar, typename TargetChar>
concept cast_char_noexcept = requires(SourceChar ch) {
{ cast_char<TargetChar>(ch) } noexcept -> std::convertible_to<TargetChar>;
};
} // boost::spirit::x3::detail
}}}}
#endif
@@ -1,40 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_HPP
#define BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_HPP
#include <type_traits>
#include <utility>
namespace boost::spirit::x3::detail
{
// A closed range [first, last]
template <typename CharT>
struct char_range
{
static_assert(std::is_default_constructible_v<CharT>);
static_assert(std::is_copy_constructible_v<CharT> && std::is_copy_assignable_v<CharT>);
using value_type = CharT;
constexpr char_range() noexcept(std::is_nothrow_default_constructible_v<CharT>) = default;
template<class A, class B>
requires std::is_constructible_v<CharT, A> && std::is_constructible_v<CharT, B>
constexpr char_range(A&& first, B&& last)
noexcept(std::is_nothrow_constructible_v<CharT, A> && std::is_nothrow_constructible_v<CharT, B>)
: first(std::forward<A>(first))
, last(std::forward<B>(last))
{}
CharT first{};
CharT last{};
};
} // boost::spirit::x3::detail
#endif
@@ -1,108 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_FUNCTIONS_HPP
#define BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_FUNCTIONS_HPP
#include <boost/spirit/home/x3/char/detail/char_range.hpp>
#include <limits>
#include <concepts>
namespace boost::spirit::x3::detail
{
template <typename CharT>
[[nodiscard]] constexpr bool
is_valid(char_range<CharT> const& range) noexcept
{
// test for valid ranges
return range.first <= range.last;
}
template <typename CharT>
[[nodiscard]] constexpr bool
includes(char_range<CharT> const& range, char_range<CharT> const& other) noexcept
{
// see if two ranges intersect
return (range.first <= other.first) && (range.last >= other.last);
}
template <typename CharT>
[[nodiscard]] constexpr bool
includes(char_range<CharT> const& range, CharT val) noexcept
{
// see if val is in range
return (range.first <= val) && (range.last >= val);
}
template <typename CharT>
[[nodiscard]] constexpr bool
can_merge(char_range<CharT> const& range, char_range<CharT> const& other) noexcept
{
// see if a 'range' overlaps, or is adjacent to
// another range 'other', so we can merge them
using limits = std::numeric_limits<CharT>;
CharT const decr_first =
range.first == (limits::min)()
? range.first : range.first-1;
CharT const incr_last =
range.last == (limits::max)()
? range.last : range.last+1;
return (decr_first <= other.last) && (incr_last >= other.first);
}
template <typename CharT>
constexpr void
merge(char_range<CharT>& result, char_range<CharT> const& other) noexcept
{
// merge two ranges
if (result.first > other.first)
{
result.first = other.first;
}
if (result.last < other.last)
{
result.last = other.last;
}
}
struct char_range_compare
{
using is_transparent = int;
template <typename CharT>
[[nodiscard]] constexpr bool operator()(char_range<CharT> const& x, CharT const y) const noexcept
{
return x.first < y;
}
template <typename CharT>
[[nodiscard]] constexpr bool operator()(CharT const x, char_range<CharT> const& y) const noexcept
{
return x < y.first;
}
template <typename CharT>
[[nodiscard]] constexpr bool operator()(char_range<CharT> const& x, char_range<CharT> const& y) const noexcept
{
return x.first < y.first;
}
// This overload is required to satsify `std::indirect_strict_weak_order`
template <std::integral CharT> // hack: minimal constraint to avoid obvious mistakes
[[nodiscard]] constexpr bool operator()(CharT const x, CharT const y) const noexcept
{
return x == y;
}
};
} // boost::spirit::x3::detail
#endif
@@ -1,193 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_RUN_HPP
#define BOOST_SPIRIT_X3_CHAR_DETAIL_CHAR_RANGE_RUN_HPP
#include <boost/spirit/home/x3/char/detail/char_range.hpp>
#include <boost/spirit/home/x3/char/detail/char_range_functions.hpp>
#include <boost/assert.hpp>
#include <algorithm>
#include <vector>
#include <iterator>
#include <ranges>
#include <utility>
namespace boost::spirit::x3::detail
{
// An implementation of a sparse bit (boolean) set. The set uses
// a sorted vector of disjoint ranges. This class implements the
// bare minimum essentials from which the full range of set
// operators can be implemented. The set is constructed from
// ranges. Internally, adjacent or overlapping ranges are
// coalesced.
//
// range_runs are very space-economical in situations where there
// are lots of ranges and a few individual disjoint values.
// Searching is O(log n) where n is the number of ranges.
template <typename CharT>
class char_range_run
{
public:
using range_type = char_range<CharT>;
using storage_type = std::vector<range_type>; // TODO: use default_init_allocator as soon as constexpr placement new is available
[[nodiscard]] static constexpr bool
try_merge(storage_type& run, typename storage_type::iterator iter, range_type const& range)
noexcept(std::is_nothrow_move_assignable_v<CharT>)
{
// *iter intersects with or is adjacent to 'range'?
if (!detail::can_merge(*iter, range)) return false;
// merge range and *iter
detail::merge(*iter, range);
// collapse all subsequent ranges that can merge with *iter:
auto it = std::next(iter);
// 1. skip subsequent ranges completely included in *iter
while (it != run.end() && it->last <= iter->last)
{
++it;
}
// 2. collapse next range if adjacent or overlapping with *iter
if (it != run.end() && it->first-1 <= iter->last)
{
iter->last = it->last;
++it;
}
// erase all ranges that were collapsed
run.erase(std::next(iter), it);
return true;
}
[[nodiscard]] constexpr bool test(CharT val) const noexcept
{
if (run_.empty()) return false;
// search the ranges for one that potentially includes val
auto const iter = std::ranges::upper_bound(
run_, val,
char_range_compare{}
);
// return true if *(iter-1) includes val
return iter != run_.begin() && detail::includes(*std::prev(iter), val);
}
constexpr void swap(char_range_run& other) noexcept
{
run_.swap(other.run_);
}
constexpr void set(range_type const& range)
{
BOOST_ASSERT(detail::is_valid(range));
if (run_.empty())
{
// the vector is empty, insert 'range'
run_.emplace_back(range);
return;
}
// search the ranges for one that potentially includes 'range'
auto iter = std::ranges::upper_bound(run_, range, char_range_compare{});
if (iter != run_.begin())
{
// if *(iter-1) includes 'range', return early
if (detail::includes(*std::prev(iter), range))
{
return;
}
// if *(iter-1) can merge with 'range', merge them and return
if (this->try_merge(run_, std::prev(iter), range))
{
return;
}
}
// if *iter can merge with with 'range', merge them
if (iter == run_.end() || !this->try_merge(run_, iter, range))
{
// no overlap, insert 'range'
run_.insert(iter, range);
}
}
constexpr void clear(range_type const& range)
{
BOOST_ASSERT(detail::is_valid(range));
if (run_.empty()) return;
// search the ranges for one that potentially includes 'range'
auto iter = std::ranges::upper_bound(run_, range, char_range_compare{});
// 'range' starts with or after another range:
if (iter != run_.begin())
{
auto const left_iter = std::prev(iter);
// 'range' starts after '*left_iter':
if (left_iter->first < range.first)
{
// if 'range' is completely included inside '*left_iter':
// need to break it apart into two ranges (punch a hole),
if (left_iter->last > range.last)
{
auto const last_save = left_iter->last;
left_iter->last = range.first-1;
run_.insert(iter, range_type(range.last+1, last_save));
return;
}
// if 'range' contains 'left_iter->last':
// truncate '*left_iter' (clip its right)
else if (left_iter->last >= range.first)
{
left_iter->last = range.first-1;
}
}
// 'range' has the same left bound as '*left_iter': it
// must be removed or truncated by the code below
else
{
iter = left_iter;
}
}
// remove or truncate subsequent ranges that overlap with 'range':
auto it = iter;
// 1. skip subsequent ranges completely included in 'range'
while (it != run_.end() && it->last <= range.last)
{
++it;
}
// 2. clip left of next range if overlapping with 'range'
if (it != run_.end() && it->first <= range.last)
{
it->first = range.last+1;
}
// erase all ranges that 'range' contained
run_.erase(iter, it);
}
constexpr void clear() noexcept
{
run_.clear();
}
private:
storage_type run_;
};
} // boost::spirit::x3::detail
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,33 +9,27 @@
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>
#include <concepts>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct literal_char : char_parser<literal_char<Encoding, Attribute>>
{
using char_type = typename Encoding::char_type;
using encoding = Encoding;
using attribute_type = Attribute;
static constexpr bool has_attribute = !std::is_same_v<unused_type, attribute_type>;
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template <typename Char>
requires std::convertible_to<Char, char_type>
constexpr literal_char(Char ch) noexcept
: ch(static_cast<char_type>(ch))
{
static_assert(std::same_as<char_type, Char>, "Mixing incompatible character types is not allowed");
}
constexpr literal_char(Char ch)
: ch(static_cast<char_type>(ch)) {}
template <typename Char, typename Context>
[[nodiscard]] constexpr bool test(Char ch_, Context const& context) const noexcept
bool test(Char ch_, Context const& context) const
{
static_assert(std::same_as<char_type, Char>, "Mixing incompatible character types is not allowed");
return x3::get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0;
return get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0;
}
char_type ch;
@@ -45,12 +38,12 @@ namespace boost::spirit::x3
template <typename Encoding, typename Attribute>
struct get_info<literal_char<Encoding, Attribute>>
{
using result_type = std::string;
[[nodiscard]] std::string operator()(literal_char<Encoding, Attribute> const& p) const
typedef std::string result_type;
std::string operator()(literal_char<Encoding, Attribute> const& p) const
{
return '\'' + x3::to_utf8(Encoding::toucs4(p.ch)) + '\'';
return '\'' + to_utf8(Encoding::toucs4(p.ch)) + '\'';
}
};
} // boost::spirit::x3
}}}
#endif
+66 -31
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,12 +8,15 @@
#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/x3/char_encoding/unicode.hpp>
#include <boost/spirit/home/support/char_encoding/unicode.hpp>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct char_tag;
struct alnum_tag;
struct alpha_tag;
@@ -29,7 +31,9 @@ namespace boost::spirit::x3
struct lower_tag;
struct upper_tag;
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct letter_tag {};
struct mark_tag {};
struct number_tag {};
@@ -38,7 +42,9 @@ namespace boost::spirit::x3
struct punctuation_tag {};
struct symbol_tag {};
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
struct uppercase_letter_tag {};
struct lowercase_letter_tag {};
struct titlecase_letter_tag {};
@@ -76,7 +82,9 @@ namespace boost::spirit::x3
struct modifier_symbol_tag {};
struct other_symbol_tag {};
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
struct alphabetic_tag {};
struct uppercase_tag {};
struct lowercase_tag {};
@@ -85,7 +93,9 @@ namespace boost::spirit::x3
struct noncharacter_code_point_tag {};
struct default_ignorable_code_point_tag {};
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
struct adlam_tag {};
struct caucasian_albanian_tag {};
struct ahom_tag {};
@@ -252,10 +262,11 @@ namespace boost::spirit::x3
struct common_tag {};
struct unknown_tag {};
///////////////////////////////////////////////////////////////////////////
struct unicode_char_class_base
{
using encoding = char_encoding::unicode;
using char_type = char_encoding::unicode::char_type;
typedef char_encoding::unicode encoding;
typedef char_encoding::unicode::char_type char_type;
#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name) \
template <typename Char> \
@@ -280,7 +291,9 @@ namespace boost::spirit::x3
/***/
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_BASIC_CLASSIFY(char)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alnum)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alpha)
@@ -295,7 +308,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_BASIC_CLASSIFY(blank)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(upper)
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(letter)
BOOST_SPIRIT_X3_CLASSIFY(mark)
BOOST_SPIRIT_X3_CLASSIFY(number)
@@ -304,7 +319,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CLASSIFY(punctuation)
BOOST_SPIRIT_X3_CLASSIFY(symbol)
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(uppercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(lowercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(titlecase_letter)
@@ -342,7 +359,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CLASSIFY(modifier_symbol)
BOOST_SPIRIT_X3_CLASSIFY(other_symbol)
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(alphabetic)
BOOST_SPIRIT_X3_CLASSIFY(uppercase)
BOOST_SPIRIT_X3_CLASSIFY(lowercase)
@@ -351,7 +370,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CLASSIFY(noncharacter_code_point)
BOOST_SPIRIT_X3_CLASSIFY(default_ignorable_code_point)
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(adlam)
BOOST_SPIRIT_X3_CLASSIFY(caucasian_albanian)
BOOST_SPIRIT_X3_CLASSIFY(ahom)
@@ -524,28 +545,34 @@ namespace boost::spirit::x3
template <typename Tag>
struct unicode_char_class
: char_parser<unicode_char_class<Tag>>
: char_parser<unicode_char_class<Tag>>
{
using encoding = char_encoding::unicode;
using tag = Tag;
using char_type = typename encoding::char_type;
using attribute_type = char_type;
static constexpr bool has_attribute = true;
typedef char_encoding::unicode encoding;
typedef Tag tag;
typedef typename encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
[[nodiscard]] constexpr bool test(Char ch, Context const&) const noexcept
bool test(Char ch, Context const&) const
{
return encoding::ischar(ch) && unicode_char_class_base::is(tag{}, ch);
return encoding::ischar(ch) && unicode_char_class_base::is(tag(), ch);
}
};
#define BOOST_SPIRIT_X3_CHAR_CLASS(name) \
using name##_type = unicode_char_class<name##_tag>; \
inline constexpr name##_type name{};
typedef unicode_char_class<name##_tag> name##_type; \
constexpr name##_type name = name##_type(); \
/***/
namespace unicode
{
// Unicode Major Categories
typedef any_char<char_encoding::unicode> char_type;
constexpr auto char_ = char_type{};
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alnum)
BOOST_SPIRIT_X3_CHAR_CLASS(alpha)
BOOST_SPIRIT_X3_CHAR_CLASS(digit)
@@ -559,7 +586,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CHAR_CLASS(blank)
BOOST_SPIRIT_X3_CHAR_CLASS(upper)
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(letter)
BOOST_SPIRIT_X3_CHAR_CLASS(mark)
BOOST_SPIRIT_X3_CHAR_CLASS(number)
@@ -568,7 +597,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CHAR_CLASS(punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(symbol)
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(titlecase_letter)
@@ -606,7 +637,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CHAR_CLASS(modifier_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(other_symbol)
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alphabetic)
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase)
@@ -615,7 +648,9 @@ namespace boost::spirit::x3
BOOST_SPIRIT_X3_CHAR_CLASS(noncharacter_code_point)
BOOST_SPIRIT_X3_CHAR_CLASS(default_ignorable_code_point)
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(adlam)
BOOST_SPIRIT_X3_CHAR_CLASS(caucasian_albanian)
BOOST_SPIRIT_X3_CHAR_CLASS(ahom)
@@ -785,6 +820,6 @@ namespace boost::spirit::x3
#undef BOOST_SPIRIT_X3_CHAR_CLASS
} // boost::spirit::x3
}}}
#endif
@@ -1,342 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_ASCII_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_ASCII_HPP
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/assert.hpp>
#include <climits>
#include <cstdint>
// constants used to classify the single characters
#define BOOST_SPIRIT_X3_CC_DIGIT 0x0001
#define BOOST_SPIRIT_X3_CC_XDIGIT 0x0002
#define BOOST_SPIRIT_X3_CC_ALPHA 0x0004
#define BOOST_SPIRIT_X3_CC_CTRL 0x0008
#define BOOST_SPIRIT_X3_CC_LOWER 0x0010
#define BOOST_SPIRIT_X3_CC_UPPER 0x0020
#define BOOST_SPIRIT_X3_CC_SPACE 0x0040
#define BOOST_SPIRIT_X3_CC_PUNCT 0x0080
namespace boost::spirit::x3::char_encoding
{
// The detection of isgraph(), isprint() and isblank() is done programmatically
// to keep the character type table small. Additionally, these functions are
// rather seldom used and the programmatic detection is very simple.
// Test characters for specified conditions (using ASCII)
struct ascii
{
using char_type = char;
using classify_type = unsigned char;
// ASCII character classification table
inline static constexpr unsigned char ascii_char_types[] =
{
/* NUL 0 0 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SOH 1 1 */ BOOST_SPIRIT_X3_CC_CTRL,
/* STX 2 2 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ETX 3 3 */ BOOST_SPIRIT_X3_CC_CTRL,
/* EOT 4 4 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ENQ 5 5 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ACK 6 6 */ BOOST_SPIRIT_X3_CC_CTRL,
/* BEL 7 7 */ BOOST_SPIRIT_X3_CC_CTRL,
/* BS 8 8 */ BOOST_SPIRIT_X3_CC_CTRL,
/* HT 9 9 */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* NL 10 a */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* VT 11 b */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* NP 12 c */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* CR 13 d */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* SO 14 e */ BOOST_SPIRIT_X3_CC_CTRL,
/* SI 15 f */ BOOST_SPIRIT_X3_CC_CTRL,
/* DLE 16 10 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC1 17 11 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC2 18 12 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC3 19 13 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC4 20 14 */ BOOST_SPIRIT_X3_CC_CTRL,
/* NAK 21 15 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SYN 22 16 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ETB 23 17 */ BOOST_SPIRIT_X3_CC_CTRL,
/* CAN 24 18 */ BOOST_SPIRIT_X3_CC_CTRL,
/* EM 25 19 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SUB 26 1a */ BOOST_SPIRIT_X3_CC_CTRL,
/* ESC 27 1b */ BOOST_SPIRIT_X3_CC_CTRL,
/* FS 28 1c */ BOOST_SPIRIT_X3_CC_CTRL,
/* GS 29 1d */ BOOST_SPIRIT_X3_CC_CTRL,
/* RS 30 1e */ BOOST_SPIRIT_X3_CC_CTRL,
/* US 31 1f */ BOOST_SPIRIT_X3_CC_CTRL,
/* SP 32 20 */ BOOST_SPIRIT_X3_CC_SPACE,
/* ! 33 21 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* " 34 22 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* # 35 23 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* $ 36 24 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* % 37 25 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* & 38 26 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ' 39 27 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ( 40 28 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ) 41 29 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* * 42 2a */ BOOST_SPIRIT_X3_CC_PUNCT,
/* + 43 2b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* , 44 2c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* - 45 2d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* . 46 2e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* / 47 2f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 0 48 30 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 1 49 31 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 2 50 32 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 3 51 33 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 4 52 34 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 5 53 35 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 6 54 36 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 7 55 37 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 8 56 38 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 9 57 39 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* : 58 3a */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ; 59 3b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* < 60 3c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* = 61 3d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* > 62 3e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ? 63 3f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* @ 64 40 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* A 65 41 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* B 66 42 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* C 67 43 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* D 68 44 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* E 69 45 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* F 70 46 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* G 71 47 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* H 72 48 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* I 73 49 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* J 74 4a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* K 75 4b */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* L 76 4c */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* M 77 4d */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* N 78 4e */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* O 79 4f */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* P 80 50 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Q 81 51 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* R 82 52 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* S 83 53 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* T 84 54 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* U 85 55 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* V 86 56 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* W 87 57 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* X 88 58 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Y 89 59 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Z 90 5a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* [ 91 5b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* \ 92 5c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ] 93 5d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ^ 94 5e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* _ 95 5f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ` 96 60 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* a 97 61 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* b 98 62 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* c 99 63 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* d 100 64 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* e 101 65 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* f 102 66 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* g 103 67 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* h 104 68 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* i 105 69 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* j 106 6a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* k 107 6b */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* l 108 6c */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* m 109 6d */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* n 110 6e */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* o 111 6f */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* p 112 70 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* q 113 71 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* r 114 72 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* s 115 73 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* t 116 74 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* u 117 75 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* v 118 76 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* w 119 77 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* x 120 78 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* y 121 79 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* z 122 7a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* { 123 7b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* | 124 7c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* } 125 7d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ~ 126 7e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* DEL 127 7f */ BOOST_SPIRIT_X3_CC_CTRL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static bool
isascii_(int ch)
{
return 0 == (ch & ~0x7f);
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
ischar(int ch)
{
return isascii_(ch);
}
// *** Note on assertions: The precondition is that the calls to
// these functions do not violate the required range of ch (type int)
// which is that strict_ischar(ch) should be true. It is the
// responsibility of the caller to make sure this precondition is not
// violated.
static bool
strict_ischar(int ch)
{
return ch >= 0 && ch <= 127;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isalnum(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_ALPHA)
|| (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_DIGIT);
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isalpha(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_ALPHA) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isdigit(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_DIGIT) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isxdigit(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_XDIGIT) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
iscntrl(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_CTRL) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isgraph(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return ('\x21' <= ch && ch <= '\x7e');
}
static bool
islower(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_LOWER) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isprint(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return ('\x20' <= ch && ch <= '\x7e');
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
ispunct(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_PUNCT) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isspace(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_SPACE) ? true : false;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
(isblank)(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return ('\x09' == ch || '\x20' == ch);
}
static bool
isupper(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return (ascii_char_types[ch] & BOOST_SPIRIT_X3_CC_UPPER) ? true : false;
}
// Simple character conversions
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static int
tolower(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return isupper(ch) ? (ch - 'A' + 'a') : ch;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static int
toupper(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return islower(ch) ? (ch - 'a' + 'A') : ch;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static std::uint32_t
toucs4(int ch)
{
BOOST_ASSERT(strict_ischar(ch));
return ch;
}
};
} // boost::spirit::x3::char_encoding
// undefine macros
#undef BOOST_SPIRIT_X3_CC_DIGIT
#undef BOOST_SPIRIT_X3_CC_XDIGIT
#undef BOOST_SPIRIT_X3_CC_ALPHA
#undef BOOST_SPIRIT_X3_CC_CTRL
#undef BOOST_SPIRIT_X3_CC_LOWER
#undef BOOST_SPIRIT_X3_CC_UPPER
#undef BOOST_SPIRIT_X3_CC_PUNCT
#undef BOOST_SPIRIT_X3_CC_SPACE
#endif
@@ -1,21 +0,0 @@
/*=============================================================================
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_DETAIL_ENCODING_WARNING_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_DETAIL_ENCODING_WARNING_HPP
#define BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING \
"Hard-coding ASCII or Latin-1 assumptions is almost always wrong " \
"in modern applications and can introduce security vulnerabilities. " \
"Unless the input is provably ASCII-only (e.g., fixed-format data from " \
"the 1980s), the only correct interpretation uses the data's *original* " \
"encoding. Prefer transcoding to Unicode or to the implementation-defined " \
"execution character set before passing text to general-purpose parsers. " \
"For more information, refer to authoritative sources on C++ character " \
"encodings and Unicode fundamentals."
#endif
@@ -1,734 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_ISO8859_1_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_ISO8859_1_HPP
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/assert.hpp>
#include <climits>
#include <cstdint>
// constants used to classify the single characters
#define BOOST_SPIRIT_X3_CC_DIGIT 0x0001
#define BOOST_SPIRIT_X3_CC_XDIGIT 0x0002
#define BOOST_SPIRIT_X3_CC_ALPHA 0x0004
#define BOOST_SPIRIT_X3_CC_CTRL 0x0008
#define BOOST_SPIRIT_X3_CC_LOWER 0x0010
#define BOOST_SPIRIT_X3_CC_UPPER 0x0020
#define BOOST_SPIRIT_X3_CC_SPACE 0x0040
#define BOOST_SPIRIT_X3_CC_PUNCT 0x0080
namespace boost::spirit::x3::char_encoding
{
// Test characters for specified conditions (using iso8859-1)
struct iso8859_1
{
using char_type = char;
using classify_type = char;
private:
// The detection of isgraph(), isprint() and isblank() is done programmatically
// to keep the character type table small. Additionally, these functions are
// rather seldom used and the programmatic detection is very simple.
// ISO 8859-1 character classification table
//
// the comments intentionally contain non-ascii characters
// boostinspect:noascii
inline static constexpr unsigned char iso8859_1_char_types[] =
{
/* NUL 0 0 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SOH 1 1 */ BOOST_SPIRIT_X3_CC_CTRL,
/* STX 2 2 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ETX 3 3 */ BOOST_SPIRIT_X3_CC_CTRL,
/* EOT 4 4 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ENQ 5 5 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ACK 6 6 */ BOOST_SPIRIT_X3_CC_CTRL,
/* BEL 7 7 */ BOOST_SPIRIT_X3_CC_CTRL,
/* BS 8 8 */ BOOST_SPIRIT_X3_CC_CTRL,
/* HT 9 9 */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* NL 10 a */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* VT 11 b */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* NP 12 c */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* CR 13 d */ BOOST_SPIRIT_X3_CC_CTRL|BOOST_SPIRIT_X3_CC_SPACE,
/* SO 14 e */ BOOST_SPIRIT_X3_CC_CTRL,
/* SI 15 f */ BOOST_SPIRIT_X3_CC_CTRL,
/* DLE 16 10 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC1 17 11 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC2 18 12 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC3 19 13 */ BOOST_SPIRIT_X3_CC_CTRL,
/* DC4 20 14 */ BOOST_SPIRIT_X3_CC_CTRL,
/* NAK 21 15 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SYN 22 16 */ BOOST_SPIRIT_X3_CC_CTRL,
/* ETB 23 17 */ BOOST_SPIRIT_X3_CC_CTRL,
/* CAN 24 18 */ BOOST_SPIRIT_X3_CC_CTRL,
/* EM 25 19 */ BOOST_SPIRIT_X3_CC_CTRL,
/* SUB 26 1a */ BOOST_SPIRIT_X3_CC_CTRL,
/* ESC 27 1b */ BOOST_SPIRIT_X3_CC_CTRL,
/* FS 28 1c */ BOOST_SPIRIT_X3_CC_CTRL,
/* GS 29 1d */ BOOST_SPIRIT_X3_CC_CTRL,
/* RS 30 1e */ BOOST_SPIRIT_X3_CC_CTRL,
/* US 31 1f */ BOOST_SPIRIT_X3_CC_CTRL,
/* SP 32 20 */ BOOST_SPIRIT_X3_CC_SPACE,
/* ! 33 21 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* " 34 22 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* # 35 23 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* $ 36 24 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* % 37 25 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* & 38 26 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ' 39 27 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ( 40 28 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ) 41 29 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* * 42 2a */ BOOST_SPIRIT_X3_CC_PUNCT,
/* + 43 2b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* , 44 2c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* - 45 2d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* . 46 2e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* / 47 2f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 0 48 30 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 1 49 31 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 2 50 32 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 3 51 33 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 4 52 34 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 5 53 35 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 6 54 36 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 7 55 37 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 8 56 38 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* 9 57 39 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_XDIGIT,
/* : 58 3a */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ; 59 3b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* < 60 3c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* = 61 3d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* > 62 3e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ? 63 3f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* @ 64 40 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* A 65 41 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* B 66 42 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* C 67 43 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* D 68 44 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* E 69 45 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* F 70 46 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_UPPER,
/* G 71 47 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* H 72 48 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* I 73 49 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* J 74 4a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* K 75 4b */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* L 76 4c */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* M 77 4d */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* N 78 4e */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* O 79 4f */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* P 80 50 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Q 81 51 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* R 82 52 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* S 83 53 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* T 84 54 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* U 85 55 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* V 86 56 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* W 87 57 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* X 88 58 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Y 89 59 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* Z 90 5a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* [ 91 5b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* \ 92 5c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ] 93 5d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ^ 94 5e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* _ 95 5f */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ` 96 60 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* a 97 61 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* b 98 62 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* c 99 63 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* d 100 64 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* e 101 65 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* f 102 66 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_XDIGIT|BOOST_SPIRIT_X3_CC_LOWER,
/* g 103 67 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* h 104 68 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* i 105 69 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* j 106 6a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* k 107 6b */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* l 108 6c */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* m 109 6d */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* n 110 6e */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* o 111 6f */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* p 112 70 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* q 113 71 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* r 114 72 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* s 115 73 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* t 116 74 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* u 117 75 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* v 118 76 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* w 119 77 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* x 120 78 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* y 121 79 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* z 122 7a */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* { 123 7b */ BOOST_SPIRIT_X3_CC_PUNCT,
/* | 124 7c */ BOOST_SPIRIT_X3_CC_PUNCT,
/* } 125 7d */ BOOST_SPIRIT_X3_CC_PUNCT,
/* ~ 126 7e */ BOOST_SPIRIT_X3_CC_PUNCT,
/* DEL 127 7f */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 128 80 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 129 81 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 130 82 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 131 83 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 132 84 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 133 85 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 134 86 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 135 87 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 136 88 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 137 89 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 138 8a */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 139 8b */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 140 8c */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 141 8d */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 142 8e */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 143 8f */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 144 90 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 145 91 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 146 92 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 147 93 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 148 94 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 149 95 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 150 96 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 151 97 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 152 98 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 153 99 */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 154 9a */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 155 9b */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 156 9c */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 157 9d */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 158 9e */ BOOST_SPIRIT_X3_CC_CTRL,
/* -- 159 9f */ BOOST_SPIRIT_X3_CC_CTRL,
/* 160 a0 */ BOOST_SPIRIT_X3_CC_SPACE,
/* 161 a1 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 162 a2 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 163 a3 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 164 a4 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 165 a5 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 166 a6 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 167 a7 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 168 a8 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 169 a9 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 170 aa */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 171 ab */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 172 ac */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 173 ad */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 174 ae */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 175 af */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 176 b0 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 177 b1 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 178 b2 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_PUNCT,
/* 179 b3 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_PUNCT,
/* 180 b4 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 181 b5 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 182 b6 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 183 b7 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 184 b8 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 185 b9 */ BOOST_SPIRIT_X3_CC_DIGIT|BOOST_SPIRIT_X3_CC_PUNCT,
/* 186 ba */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 187 bb */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 188 bc */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 189 bd */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 190 be */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 191 bf */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 192 c0 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 193 c1 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 194 c2 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 195 c3 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 196 c4 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 197 c5 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 198 c6 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 199 c7 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 200 c8 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 201 c9 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 202 ca */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 203 cb */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 204 cc */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 205 cd */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 206 ce */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 207 cf */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 208 d0 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 209 d1 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 210 d2 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 211 d3 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 212 d4 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 213 d5 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 214 d6 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 215 d7 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 216 d8 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 217 d9 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 218 da */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 219 db */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 220 dc */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 221 dd */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 222 de */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_UPPER,
/* 223 df */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 224 e0 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 225 e1 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 226 e2 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 227 e3 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 228 e4 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 229 e5 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 230 e6 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 231 e7 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 232 e8 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 233 e9 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 234 ea */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 235 eb */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 236 ec */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 237 ed */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 238 ee */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 239 ef */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 240 f0 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 241 f1 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 242 f2 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 243 f3 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 244 f4 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 245 f5 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 246 f6 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 247 f7 */ BOOST_SPIRIT_X3_CC_PUNCT,
/* 248 f8 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 249 f9 */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 250 fa */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 251 fb */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 252 fc */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 253 fd */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 254 fe */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
/* 255 ff */ BOOST_SPIRIT_X3_CC_ALPHA|BOOST_SPIRIT_X3_CC_LOWER,
};
// ISO 8859-1 character conversion table
inline static constexpr unsigned char iso8859_1_char_conversion[] =
{
/* NUL 0 0 */ '\0',
/* SOH 1 1 */ '\0',
/* STX 2 2 */ '\0',
/* ETX 3 3 */ '\0',
/* EOT 4 4 */ '\0',
/* ENQ 5 5 */ '\0',
/* ACK 6 6 */ '\0',
/* BEL 7 7 */ '\0',
/* BS 8 8 */ '\0',
/* HT 9 9 */ '\0',
/* NL 10 a */ '\0',
/* VT 11 b */ '\0',
/* NP 12 c */ '\0',
/* CR 13 d */ '\0',
/* SO 14 e */ '\0',
/* SI 15 f */ '\0',
/* DLE 16 10 */ '\0',
/* DC1 17 11 */ '\0',
/* DC2 18 12 */ '\0',
/* DC3 19 13 */ '\0',
/* DC4 20 14 */ '\0',
/* NAK 21 15 */ '\0',
/* SYN 22 16 */ '\0',
/* ETB 23 17 */ '\0',
/* CAN 24 18 */ '\0',
/* EM 25 19 */ '\0',
/* SUB 26 1a */ '\0',
/* ESC 27 1b */ '\0',
/* FS 28 1c */ '\0',
/* GS 29 1d */ '\0',
/* RS 30 1e */ '\0',
/* US 31 1f */ '\0',
/* SP 32 20 */ '\0',
/* ! 33 21 */ '\0',
/* " 34 22 */ '\0',
/* # 35 23 */ '\0',
/* $ 36 24 */ '\0',
/* % 37 25 */ '\0',
/* & 38 26 */ '\0',
/* ' 39 27 */ '\0',
/* ( 40 28 */ '\0',
/* ) 41 29 */ '\0',
/* * 42 2a */ '\0',
/* + 43 2b */ '\0',
/* , 44 2c */ '\0',
/* - 45 2d */ '\0',
/* . 46 2e */ '\0',
/* / 47 2f */ '\0',
/* 0 48 30 */ '\0',
/* 1 49 31 */ '\0',
/* 2 50 32 */ '\0',
/* 3 51 33 */ '\0',
/* 4 52 34 */ '\0',
/* 5 53 35 */ '\0',
/* 6 54 36 */ '\0',
/* 7 55 37 */ '\0',
/* 8 56 38 */ '\0',
/* 9 57 39 */ '\0',
/* : 58 3a */ '\0',
/* ; 59 3b */ '\0',
/* < 60 3c */ '\0',
/* = 61 3d */ '\0',
/* > 62 3e */ '\0',
/* ? 63 3f */ '\0',
/* @ 64 40 */ '\0',
/* A 65 41 */ 'a',
/* B 66 42 */ 'b',
/* C 67 43 */ 'c',
/* D 68 44 */ 'd',
/* E 69 45 */ 'e',
/* F 70 46 */ 'f',
/* G 71 47 */ 'g',
/* H 72 48 */ 'h',
/* I 73 49 */ 'i',
/* J 74 4a */ 'j',
/* K 75 4b */ 'k',
/* L 76 4c */ 'l',
/* M 77 4d */ 'm',
/* N 78 4e */ 'n',
/* O 79 4f */ 'o',
/* P 80 50 */ 'p',
/* Q 81 51 */ 'q',
/* R 82 52 */ 'r',
/* S 83 53 */ 's',
/* T 84 54 */ 't',
/* U 85 55 */ 'u',
/* V 86 56 */ 'v',
/* W 87 57 */ 'w',
/* X 88 58 */ 'x',
/* Y 89 59 */ 'y',
/* Z 90 5a */ 'z',
/* [ 91 5b */ '\0',
/* \ 92 5c */ '\0',
/* ] 93 5d */ '\0',
/* ^ 94 5e */ '\0',
/* _ 95 5f */ '\0',
/* ` 96 60 */ '\0',
/* a 97 61 */ 'A',
/* b 98 62 */ 'B',
/* c 99 63 */ 'C',
/* d 100 64 */ 'D',
/* e 101 65 */ 'E',
/* f 102 66 */ 'F',
/* g 103 67 */ 'G',
/* h 104 68 */ 'H',
/* i 105 69 */ 'I',
/* j 106 6a */ 'J',
/* k 107 6b */ 'K',
/* l 108 6c */ 'L',
/* m 109 6d */ 'M',
/* n 110 6e */ 'N',
/* o 111 6f */ 'O',
/* p 112 70 */ 'P',
/* q 113 71 */ 'Q',
/* r 114 72 */ 'R',
/* s 115 73 */ 'S',
/* t 116 74 */ 'T',
/* u 117 75 */ 'U',
/* v 118 76 */ 'V',
/* w 119 77 */ 'W',
/* x 120 78 */ 'X',
/* y 121 79 */ 'Y',
/* z 122 7a */ 'Z',
/* { 123 7b */ '\0',
/* | 124 7c */ '\0',
/* } 125 7d */ '\0',
/* ~ 126 7e */ '\0',
/* DEL 127 7f */ '\0',
/* -- 128 80 */ '\0',
/* -- 129 81 */ '\0',
/* -- 130 82 */ '\0',
/* -- 131 83 */ '\0',
/* -- 132 84 */ '\0',
/* -- 133 85 */ '\0',
/* -- 134 86 */ '\0',
/* -- 135 87 */ '\0',
/* -- 136 88 */ '\0',
/* -- 137 89 */ '\0',
/* -- 138 8a */ '\0',
/* -- 139 8b */ '\0',
/* -- 140 8c */ '\0',
/* -- 141 8d */ '\0',
/* -- 142 8e */ '\0',
/* -- 143 8f */ '\0',
/* -- 144 90 */ '\0',
/* -- 145 91 */ '\0',
/* -- 146 92 */ '\0',
/* -- 147 93 */ '\0',
/* -- 148 94 */ '\0',
/* -- 149 95 */ '\0',
/* -- 150 96 */ '\0',
/* -- 151 97 */ '\0',
/* -- 152 98 */ '\0',
/* -- 153 99 */ '\0',
/* -- 154 9a */ '\0',
/* -- 155 9b */ '\0',
/* -- 156 9c */ '\0',
/* -- 157 9d */ '\0',
/* -- 158 9e */ '\0',
/* -- 159 9f */ '\0',
/* 160 a0 */ '\0',
/* 161 a1 */ '\0',
/* 162 a2 */ '\0',
/* 163 a3 */ '\0',
/* 164 a4 */ '\0',
/* 165 a5 */ '\0',
/* 166 a6 */ '\0',
/* 167 a7 */ '\0',
/* 168 a8 */ '\0',
/* 169 a9 */ '\0',
/* 170 aa */ '\0',
/* 171 ab */ '\0',
/* 172 ac */ '\0',
/* 173 ad */ '\0',
/* 174 ae */ '\0',
/* 175 af */ '\0',
/* 176 b0 */ '\0',
/* 177 b1 */ '\0',
/* 178 b2 */ '\0',
/* 179 b3 */ '\0',
/* 180 b4 */ '\0',
/* 181 b5 */ '\0',
/* 182 b6 */ '\0',
/* 183 b7 */ '\0',
/* 184 b8 */ '\0',
/* 185 b9 */ '\0',
/* 186 ba */ '\0',
/* 187 bb */ '\0',
/* 188 bc */ '\0',
/* 189 bd */ '\0',
/* 190 be */ '\0',
/* 191 bf */ '\0',
/* 192 c0 */ 0xe0,
/* 193 c1 */ 0xe1,
/* 194 c2 */ 0xe2,
/* 195 c3 */ 0xe3,
/* 196 c4 */ 0xe4,
/* 197 c5 */ 0xe5,
/* 198 c6 */ 0xe6,
/* 199 c7 */ 0xe7,
/* 200 c8 */ 0xe8,
/* 201 c9 */ 0xe9,
/* 202 ca */ 0xea,
/* 203 cb */ 0xeb,
/* 204 cc */ 0xec,
/* 205 cd */ 0xed,
/* 206 ce */ 0xee,
/* 207 cf */ 0xef,
/* 208 d0 */ 0xf0,
/* 209 d1 */ 0xf1,
/* 210 d2 */ 0xf2,
/* 211 d3 */ 0xf3,
/* 212 d4 */ 0xf4,
/* 213 d5 */ 0xf5,
/* 214 d6 */ 0xf6,
/* 215 d7 */ '\0',
/* 216 d8 */ 0xf8,
/* 217 d9 */ 0xf9,
/* 218 da */ 0xfa,
/* 219 db */ 0xfb,
/* 220 dc */ 0xfc,
/* 221 dd */ 0xfd,
/* 222 de */ 0xfe,
/* 223 df */ '\0',
/* 224 e0 */ 0xc0,
/* 225 e1 */ 0xc1,
/* 226 e2 */ 0xc2,
/* 227 e3 */ 0xc3,
/* 228 e4 */ 0xc4,
/* 229 e5 */ 0xc5,
/* 230 e6 */ 0xc6,
/* 231 e7 */ 0xc7,
/* 232 e8 */ 0xc8,
/* 233 e9 */ 0xc9,
/* 234 ea */ 0xca,
/* 235 eb */ 0xcb,
/* 236 ec */ 0xcc,
/* 237 ed */ 0xcd,
/* 238 ee */ 0xce,
/* 239 ef */ 0xcf,
/* 240 f0 */ 0xd0,
/* 241 f1 */ 0xd1,
/* 242 f2 */ 0xd2,
/* 243 f3 */ 0xd3,
/* 244 f4 */ 0xd4,
/* 245 f5 */ 0xd5,
/* 246 f6 */ 0xd6,
/* 247 f7 */ '\0',
/* 248 f8 */ 0xd8,
/* 249 f9 */ 0xd9,
/* 250 fa */ 0xda,
/* 251 fb */ 0xdb,
/* 252 fc */ 0xdc,
/* 253 fd */ 0xdd,
/* 254 fe */ 0xde,
/* 255 ff */ '\0',
};
public:
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isascii_(int ch)
{
return 0 == (ch & ~0x7f);
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
ischar(int ch)
{
// iso8859.1 uses all 8 bits
// we have to watch out for sign extensions
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) != 0;
}
// *** Note on assertions: The precondition is that the calls to
// these functions do not violate the required range of ch (type int)
// which is that strict_ischar(ch) should be true. It is the
// responsibility of the caller to make sure this precondition is not
// violated.
static bool
strict_ischar(int ch)
{
return ch >= 0 && ch <= 255;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isalnum(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_ALPHA)
|| (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_DIGIT);
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isalpha(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_ALPHA) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isdigit(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_DIGIT) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isxdigit(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_XDIGIT) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
iscntrl(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_CTRL) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isgraph(int ch)
{
return ('\x21' <= ch && ch <= '\x7e') || ('\xa1' <= ch && ch <= '\xff');
}
static bool
islower(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_LOWER) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isprint(int ch)
{
return ('\x20' <= ch && ch <= '\x7e') || ('\xa0' <= ch && ch <= '\xff');
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
ispunct(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_PUNCT) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
isspace(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_SPACE) != 0;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static bool
(isblank)(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return ('\x09' == ch || '\x20' == ch || '\xa0' == ch);
}
static bool
isupper(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return (iso8859_1_char_types[ch] & BOOST_SPIRIT_X3_CC_UPPER) != 0;
}
// Simple character conversions
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static int
tolower(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return iso8859_1::isupper(ch) && '\0' != iso8859_1_char_conversion[ch] ?
iso8859_1_char_conversion[ch] : ch;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static int
toupper(int ch)
{
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return iso8859_1::islower(ch) && '\0' != iso8859_1_char_conversion[ch] ?
iso8859_1_char_conversion[ch] : ch;
}
[[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]]
static std::uint32_t
toucs4(int ch)
{
// The first 256 characters in Unicode and the UCS are
// identical to those in ISO/IEC-8859-1.
BOOST_ASSERT(iso8859_1::strict_ischar(ch));
return ch;
}
};
} // boost::spirit::x3::char_encoding
// undefine macros
#undef BOOST_SPIRIT_X3_CC_DIGIT
#undef BOOST_SPIRIT_X3_CC_XDIGIT
#undef BOOST_SPIRIT_X3_CC_ALPHA
#undef BOOST_SPIRIT_X3_CC_CTRL
#undef BOOST_SPIRIT_X3_CC_LOWER
#undef BOOST_SPIRIT_X3_CC_UPPER
#undef BOOST_SPIRIT_X3_CC_PUNCT
#undef BOOST_SPIRIT_X3_CC_SPACE
#endif
@@ -1,162 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_STANDARD_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_STANDARD_HPP
#include <boost/assert.hpp>
#include <cstdint>
#include <cctype>
#include <climits>
namespace boost::spirit::x3::char_encoding
{
// Test characters for specified conditions (using std functions)
struct standard
{
using char_type = char;
using classify_type = unsigned char;
[[nodiscard]] static constexpr bool
isascii_(int ch) noexcept
{
return 0 == (ch & ~0x7f);
}
[[nodiscard]] static constexpr bool
ischar(int ch) noexcept
{
// uses all 8 bits
// we have to watch out for sign extensions
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) != 0;
}
// *** Note on assertions: The precondition is that the calls to
// these functions do not violate the required range of ch (int)
// which is that strict_ischar(ch) should be true. It is the
// responsibility of the caller to make sure this precondition is not
// violated.
[[nodiscard]] static constexpr bool
strict_ischar(int ch) noexcept
{
// ch should be representable as an unsigned char
return ch >= 0 && ch <= UCHAR_MAX;
}
[[nodiscard]] static bool // TODO: constexpr
isalnum(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isalnum(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isalpha(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isalpha(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isdigit(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isdigit(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isxdigit(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isxdigit(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
iscntrl(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::iscntrl(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isgraph(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isgraph(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
islower(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::islower(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isprint(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isprint(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
ispunct(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::ispunct(ch) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isspace(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isspace(ch) != 0;
}
[[nodiscard]] static constexpr bool
(isblank)(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return (ch == ' ' || ch == '\t');
}
[[nodiscard]] static bool // TODO: constexpr
isupper(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::isupper(ch) != 0;
}
// Simple character conversions
[[nodiscard]] static int // TODO: constexpr
tolower(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::tolower(ch);
}
[[nodiscard]] static int // TODO: constexpr
toupper(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return std::toupper(ch);
}
[[nodiscard]] static constexpr std::uint32_t
toucs4(int ch) noexcept
{
BOOST_ASSERT(standard::strict_ischar(ch));
return static_cast<std::uint32_t>(ch);
}
};
} // boost::spirit::x3::char_encoding
#endif
@@ -1,162 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_STANDARD_WIDE_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_STANDARD_WIDE_HPP
#include <boost/assert.hpp>
#include <string>
#include <type_traits>
#include <cstdint>
#include <cwctype>
namespace boost::spirit::x3::char_encoding
{
// Test characters for specified conditions (using std wchar_t functions)
struct standard_wide
{
using char_type = wchar_t;
using classify_type = wchar_t;
template <typename Char>
[[nodiscard]] static constexpr typename std::char_traits<Char>::int_type
to_int_type(Char ch) noexcept
{
return std::char_traits<Char>::to_int_type(ch);
}
template <typename Char>
[[nodiscard]] static constexpr Char
to_char_type(typename std::char_traits<Char>::int_type ch) noexcept
{
return std::char_traits<Char>::to_char_type(ch);
}
[[nodiscard]] static constexpr bool
ischar(int ch) noexcept
{
static_assert(
sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4,
"Unsupported wchar_t size"
);
constexpr unsigned mask =
sizeof(wchar_t) == 4 ? 0xffffffffu :
sizeof(wchar_t) == 2 ? 0xffffu :
0xffu;
// we have to watch out for sign extensions (casting is there to
// silence certain compilers complaining about signed/unsigned
// mismatch)
return (
std::size_t(0) ==
std::size_t(ch & ~mask) ||
std::size_t(~0) ==
std::size_t(ch | mask)
) != 0; // any wchar_t, but no other bits set
}
[[nodiscard]] static bool // TODO: constexpr
isalnum(wchar_t ch) noexcept
{
return std::iswalnum(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isalpha(wchar_t ch) noexcept
{
return std::iswalpha(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
iscntrl(wchar_t ch) noexcept
{
return std::iswcntrl(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isdigit(wchar_t ch) noexcept
{
return std::iswdigit(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isgraph(wchar_t ch) noexcept
{
return std::iswgraph(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
islower(wchar_t ch) noexcept
{
return std::iswlower(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isprint(wchar_t ch) noexcept
{
return std::iswprint(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
ispunct(wchar_t ch) noexcept
{
return std::iswpunct(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isspace(wchar_t ch) noexcept
{
return std::iswspace(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isupper(wchar_t ch) noexcept
{
return std::iswupper(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static bool // TODO: constexpr
isxdigit(wchar_t ch) noexcept
{
return std::iswxdigit(standard_wide::to_int_type(ch)) != 0;
}
[[nodiscard]] static constexpr bool
(isblank)(wchar_t ch) noexcept
{
return (ch == L' ' || ch == L'\t');
}
// Simple character conversions
[[nodiscard]] static wchar_t // TODO: constexpr
tolower(wchar_t ch) noexcept
{
return standard_wide::isupper(ch) ?
standard_wide::to_char_type<wchar_t>(std::towlower(standard_wide::to_int_type(ch))) : ch;
}
[[nodiscard]] static wchar_t // TODO: constexpr
toupper(wchar_t ch) noexcept
{
return std::islower(ch) ?
standard_wide::to_char_type<wchar_t>(std::towupper(standard_wide::to_int_type(ch))) : ch;
}
[[nodiscard]] static constexpr std::uint32_t
toucs4(wchar_t ch) noexcept
{
return static_cast<std::make_unsigned_t<wchar_t>>(ch);
}
};
} // boost::spirit::x3::char_encoding
#endif
@@ -1,435 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_UNICODE_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_UNICODE_HPP
#include <boost/spirit/home/x3/char_encoding/unicode/classification.hpp>
#include <cstdint>
namespace boost::spirit::x3::char_encoding
{
struct unicode
{
using char_type = char32_t;
using classify_type = std::uint32_t;
[[nodiscard]] static constexpr bool
isascii_(char_type ch) noexcept
{
return 0 == (ch & ~0x7f);
}
[[nodiscard]] static constexpr bool
ischar(char_type ch) noexcept
{
// unicode code points in the range 0x00 to 0x10FFFF
return ch <= 0x10FFFF;
}
[[nodiscard]] static constexpr bool
isalnum(char_type ch) noexcept
{
return x3::unicode::is_alphanumeric(ch);
}
[[nodiscard]] static constexpr bool
isalpha(char_type ch) noexcept
{
return x3::unicode::is_alphabetic(ch);
}
[[nodiscard]] static constexpr bool
isdigit(char_type ch) noexcept
{
return x3::unicode::is_decimal_number(ch);
}
[[nodiscard]] static constexpr bool
isxdigit(char_type ch) noexcept
{
return x3::unicode::is_hex_digit(ch);
}
[[nodiscard]] static constexpr bool
iscntrl(char_type ch) noexcept
{
return x3::unicode::is_control(ch);
}
[[nodiscard]] static constexpr bool
isgraph(char_type ch) noexcept
{
return x3::unicode::is_graph(ch);
}
[[nodiscard]] static constexpr bool
islower(char_type ch) noexcept
{
return x3::unicode::is_lowercase(ch);
}
[[nodiscard]] static constexpr bool
isprint(char_type ch) noexcept
{
return x3::unicode::is_print(ch);
}
[[nodiscard]] static constexpr bool
ispunct(char_type ch) noexcept
{
return x3::unicode::is_punctuation(ch);
}
[[nodiscard]] static constexpr bool
isspace(char_type ch) noexcept
{
return x3::unicode::is_white_space(ch);
}
[[nodiscard]] static constexpr bool
(isblank)(char_type ch) noexcept
{
return x3::unicode::is_blank(ch);
}
[[nodiscard]] static constexpr bool
isupper(char_type ch) noexcept
{
return x3::unicode::is_uppercase(ch);
}
// Mixing character encodings is semantically wrong
static constexpr void isascii_(char) = delete;
static constexpr void isascii_(wchar_t) = delete;
static constexpr void ischar(char) = delete;
static constexpr void ischar(wchar_t) = delete;
static constexpr void isalnum(char) = delete;
static constexpr void isalnum(wchar_t) = delete;
static constexpr void isalpha(char) = delete;
static constexpr void isalpha(wchar_t) = delete;
static constexpr void isdigit(char) = delete;
static constexpr void isdigit(wchar_t) = delete;
static constexpr void isxdigit(char) = delete;
static constexpr void isxdigit(wchar_t) = delete;
static constexpr void iscntrl(char) = delete;
static constexpr void iscntrl(wchar_t) = delete;
static constexpr void isgraph(char) = delete;
static constexpr void isgraph(wchar_t) = delete;
static constexpr void islower(char) = delete;
static constexpr void islower(wchar_t) = delete;
static constexpr void isprint(char) = delete;
static constexpr void isprint(wchar_t) = delete;
static constexpr void ispunct(char) = delete;
static constexpr void ispunct(wchar_t) = delete;
static constexpr void isspace(char) = delete;
static constexpr void isspace(wchar_t) = delete;
static constexpr void isblank(char) = delete;
static constexpr void isblank(wchar_t) = delete;
static constexpr void isupper(char) = delete;
static constexpr void isupper(wchar_t) = delete;
// Simple character conversions
[[nodiscard]] static constexpr char_type
tolower(char_type ch) noexcept
{
return x3::unicode::to_lowercase(ch);
}
[[nodiscard]] static constexpr char_type
toupper(char_type ch) noexcept
{
return x3::unicode::to_uppercase(ch);
}
[[nodiscard]] static constexpr std::uint32_t
toucs4(char_type ch) noexcept
{
return ch;
}
static constexpr void tolower(char) = delete;
static constexpr void tolower(wchar_t) = delete;
static constexpr void toupper(char) = delete;
static constexpr void toupper(wchar_t) = delete;
static constexpr void toucs4(char) = delete;
static constexpr void toucs4(wchar_t) = delete;
// Major Categories
#define BOOST_SPIRIT_X3_MAJOR_CATEGORY(name) \
[[nodiscard]] static constexpr bool \
is_##name(char_type ch) noexcept \
{ \
return x3::unicode::get_major_category(ch) == x3::unicode::properties::name; \
} \
static constexpr void is_##name(char) = delete; \
static constexpr void is_##name(wchar_t) = delete;
BOOST_SPIRIT_X3_MAJOR_CATEGORY(letter)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(mark)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(number)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(separator)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(other)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(punctuation)
BOOST_SPIRIT_X3_MAJOR_CATEGORY(symbol)
#undef BOOST_SPIRIT_X3_MAJOR_CATEGORY
// General Categories
#define BOOST_SPIRIT_X3_CATEGORY(name) \
[[nodiscard]] static constexpr bool \
is_##name(char_type ch) noexcept \
{ \
return x3::unicode::get_category(ch) == x3::unicode::properties::name; \
} \
static constexpr void is_##name(char) = delete; \
static constexpr void is_##name(wchar_t) = delete;
BOOST_SPIRIT_X3_CATEGORY(uppercase_letter)
BOOST_SPIRIT_X3_CATEGORY(lowercase_letter)
BOOST_SPIRIT_X3_CATEGORY(titlecase_letter)
BOOST_SPIRIT_X3_CATEGORY(modifier_letter)
BOOST_SPIRIT_X3_CATEGORY(other_letter)
BOOST_SPIRIT_X3_CATEGORY(nonspacing_mark)
BOOST_SPIRIT_X3_CATEGORY(enclosing_mark)
BOOST_SPIRIT_X3_CATEGORY(spacing_mark)
BOOST_SPIRIT_X3_CATEGORY(decimal_number)
BOOST_SPIRIT_X3_CATEGORY(letter_number)
BOOST_SPIRIT_X3_CATEGORY(other_number)
BOOST_SPIRIT_X3_CATEGORY(space_separator)
BOOST_SPIRIT_X3_CATEGORY(line_separator)
BOOST_SPIRIT_X3_CATEGORY(paragraph_separator)
BOOST_SPIRIT_X3_CATEGORY(control)
BOOST_SPIRIT_X3_CATEGORY(format)
BOOST_SPIRIT_X3_CATEGORY(private_use)
BOOST_SPIRIT_X3_CATEGORY(surrogate)
BOOST_SPIRIT_X3_CATEGORY(unassigned)
BOOST_SPIRIT_X3_CATEGORY(dash_punctuation)
BOOST_SPIRIT_X3_CATEGORY(open_punctuation)
BOOST_SPIRIT_X3_CATEGORY(close_punctuation)
BOOST_SPIRIT_X3_CATEGORY(connector_punctuation)
BOOST_SPIRIT_X3_CATEGORY(other_punctuation)
BOOST_SPIRIT_X3_CATEGORY(initial_punctuation)
BOOST_SPIRIT_X3_CATEGORY(final_punctuation)
BOOST_SPIRIT_X3_CATEGORY(math_symbol)
BOOST_SPIRIT_X3_CATEGORY(currency_symbol)
BOOST_SPIRIT_X3_CATEGORY(modifier_symbol)
BOOST_SPIRIT_X3_CATEGORY(other_symbol)
#undef BOOST_SPIRIT_X3_CATEGORY
// Derived Categories
#define BOOST_SPIRIT_X3_DERIVED_CATEGORY(name) \
[[nodiscard]] static constexpr bool \
is_##name(char_type ch) noexcept \
{ \
return x3::unicode::is_##name(ch); \
} \
static constexpr void is_##name(char) = delete; \
static constexpr void is_##name(wchar_t) = delete;
BOOST_SPIRIT_X3_DERIVED_CATEGORY(alphabetic)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(uppercase)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(lowercase)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(white_space)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(hex_digit)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(noncharacter_code_point)
BOOST_SPIRIT_X3_DERIVED_CATEGORY(default_ignorable_code_point)
#undef BOOST_SPIRIT_X3_DERIVED_CATEGORY
// Scripts
#define BOOST_SPIRIT_X3_SCRIPT(name) \
[[nodiscard]] static constexpr bool \
is_##name(char_type ch) noexcept \
{ \
return x3::unicode::get_script(ch) == x3::unicode::properties::name; \
} \
static constexpr void is_##name(char) = delete; \
static constexpr void is_##name(wchar_t) = delete;
BOOST_SPIRIT_X3_SCRIPT(adlam)
BOOST_SPIRIT_X3_SCRIPT(caucasian_albanian)
BOOST_SPIRIT_X3_SCRIPT(ahom)
BOOST_SPIRIT_X3_SCRIPT(arabic)
BOOST_SPIRIT_X3_SCRIPT(imperial_aramaic)
BOOST_SPIRIT_X3_SCRIPT(armenian)
BOOST_SPIRIT_X3_SCRIPT(avestan)
BOOST_SPIRIT_X3_SCRIPT(balinese)
BOOST_SPIRIT_X3_SCRIPT(bamum)
BOOST_SPIRIT_X3_SCRIPT(bassa_vah)
BOOST_SPIRIT_X3_SCRIPT(batak)
BOOST_SPIRIT_X3_SCRIPT(bengali)
BOOST_SPIRIT_X3_SCRIPT(bhaiksuki)
BOOST_SPIRIT_X3_SCRIPT(bopomofo)
BOOST_SPIRIT_X3_SCRIPT(brahmi)
BOOST_SPIRIT_X3_SCRIPT(braille)
BOOST_SPIRIT_X3_SCRIPT(buginese)
BOOST_SPIRIT_X3_SCRIPT(buhid)
BOOST_SPIRIT_X3_SCRIPT(chakma)
BOOST_SPIRIT_X3_SCRIPT(canadian_aboriginal)
BOOST_SPIRIT_X3_SCRIPT(carian)
BOOST_SPIRIT_X3_SCRIPT(cham)
BOOST_SPIRIT_X3_SCRIPT(cherokee)
BOOST_SPIRIT_X3_SCRIPT(chorasmian)
BOOST_SPIRIT_X3_SCRIPT(coptic)
BOOST_SPIRIT_X3_SCRIPT(cypro_minoan)
BOOST_SPIRIT_X3_SCRIPT(cypriot)
BOOST_SPIRIT_X3_SCRIPT(cyrillic)
BOOST_SPIRIT_X3_SCRIPT(devanagari)
BOOST_SPIRIT_X3_SCRIPT(dives_akuru)
BOOST_SPIRIT_X3_SCRIPT(dogra)
BOOST_SPIRIT_X3_SCRIPT(deseret)
BOOST_SPIRIT_X3_SCRIPT(duployan)
BOOST_SPIRIT_X3_SCRIPT(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_SCRIPT(elbasan)
BOOST_SPIRIT_X3_SCRIPT(elymaic)
BOOST_SPIRIT_X3_SCRIPT(ethiopic)
BOOST_SPIRIT_X3_SCRIPT(georgian)
BOOST_SPIRIT_X3_SCRIPT(glagolitic)
BOOST_SPIRIT_X3_SCRIPT(gunjala_gondi)
BOOST_SPIRIT_X3_SCRIPT(masaram_gondi)
BOOST_SPIRIT_X3_SCRIPT(gothic)
BOOST_SPIRIT_X3_SCRIPT(grantha)
BOOST_SPIRIT_X3_SCRIPT(greek)
BOOST_SPIRIT_X3_SCRIPT(gujarati)
BOOST_SPIRIT_X3_SCRIPT(gurmukhi)
BOOST_SPIRIT_X3_SCRIPT(hangul)
BOOST_SPIRIT_X3_SCRIPT(han)
BOOST_SPIRIT_X3_SCRIPT(hanunoo)
BOOST_SPIRIT_X3_SCRIPT(hatran)
BOOST_SPIRIT_X3_SCRIPT(hebrew)
BOOST_SPIRIT_X3_SCRIPT(hiragana)
BOOST_SPIRIT_X3_SCRIPT(anatolian_hieroglyphs)
BOOST_SPIRIT_X3_SCRIPT(pahawh_hmong)
BOOST_SPIRIT_X3_SCRIPT(nyiakeng_puachue_hmong)
BOOST_SPIRIT_X3_SCRIPT(katakana_or_hiragana)
BOOST_SPIRIT_X3_SCRIPT(old_hungarian)
BOOST_SPIRIT_X3_SCRIPT(old_italic)
BOOST_SPIRIT_X3_SCRIPT(javanese)
BOOST_SPIRIT_X3_SCRIPT(kayah_li)
BOOST_SPIRIT_X3_SCRIPT(katakana)
BOOST_SPIRIT_X3_SCRIPT(kawi)
BOOST_SPIRIT_X3_SCRIPT(kharoshthi)
BOOST_SPIRIT_X3_SCRIPT(khmer)
BOOST_SPIRIT_X3_SCRIPT(khojki)
BOOST_SPIRIT_X3_SCRIPT(khitan_small_script)
BOOST_SPIRIT_X3_SCRIPT(kannada)
BOOST_SPIRIT_X3_SCRIPT(kaithi)
BOOST_SPIRIT_X3_SCRIPT(tai_tham)
BOOST_SPIRIT_X3_SCRIPT(lao)
BOOST_SPIRIT_X3_SCRIPT(latin)
BOOST_SPIRIT_X3_SCRIPT(lepcha)
BOOST_SPIRIT_X3_SCRIPT(limbu)
BOOST_SPIRIT_X3_SCRIPT(linear_a)
BOOST_SPIRIT_X3_SCRIPT(linear_b)
BOOST_SPIRIT_X3_SCRIPT(lisu)
BOOST_SPIRIT_X3_SCRIPT(lycian)
BOOST_SPIRIT_X3_SCRIPT(lydian)
BOOST_SPIRIT_X3_SCRIPT(mahajani)
BOOST_SPIRIT_X3_SCRIPT(makasar)
BOOST_SPIRIT_X3_SCRIPT(mandaic)
BOOST_SPIRIT_X3_SCRIPT(manichaean)
BOOST_SPIRIT_X3_SCRIPT(marchen)
BOOST_SPIRIT_X3_SCRIPT(medefaidrin)
BOOST_SPIRIT_X3_SCRIPT(mende_kikakui)
BOOST_SPIRIT_X3_SCRIPT(meroitic_cursive)
BOOST_SPIRIT_X3_SCRIPT(meroitic_hieroglyphs)
BOOST_SPIRIT_X3_SCRIPT(malayalam)
BOOST_SPIRIT_X3_SCRIPT(modi)
BOOST_SPIRIT_X3_SCRIPT(mongolian)
BOOST_SPIRIT_X3_SCRIPT(mro)
BOOST_SPIRIT_X3_SCRIPT(meetei_mayek)
BOOST_SPIRIT_X3_SCRIPT(multani)
BOOST_SPIRIT_X3_SCRIPT(myanmar)
BOOST_SPIRIT_X3_SCRIPT(nag_mundari)
BOOST_SPIRIT_X3_SCRIPT(nandinagari)
BOOST_SPIRIT_X3_SCRIPT(old_north_arabian)
BOOST_SPIRIT_X3_SCRIPT(nabataean)
BOOST_SPIRIT_X3_SCRIPT(newa)
BOOST_SPIRIT_X3_SCRIPT(nko)
BOOST_SPIRIT_X3_SCRIPT(nushu)
BOOST_SPIRIT_X3_SCRIPT(ogham)
BOOST_SPIRIT_X3_SCRIPT(ol_chiki)
BOOST_SPIRIT_X3_SCRIPT(old_turkic)
BOOST_SPIRIT_X3_SCRIPT(oriya)
BOOST_SPIRIT_X3_SCRIPT(osage)
BOOST_SPIRIT_X3_SCRIPT(osmanya)
BOOST_SPIRIT_X3_SCRIPT(old_uyghur)
BOOST_SPIRIT_X3_SCRIPT(palmyrene)
BOOST_SPIRIT_X3_SCRIPT(pau_cin_hau)
BOOST_SPIRIT_X3_SCRIPT(old_permic)
BOOST_SPIRIT_X3_SCRIPT(phags_pa)
BOOST_SPIRIT_X3_SCRIPT(inscriptional_pahlavi)
BOOST_SPIRIT_X3_SCRIPT(psalter_pahlavi)
BOOST_SPIRIT_X3_SCRIPT(phoenician)
BOOST_SPIRIT_X3_SCRIPT(miao)
BOOST_SPIRIT_X3_SCRIPT(inscriptional_parthian)
BOOST_SPIRIT_X3_SCRIPT(rejang)
BOOST_SPIRIT_X3_SCRIPT(hanifi_rohingya)
BOOST_SPIRIT_X3_SCRIPT(runic)
BOOST_SPIRIT_X3_SCRIPT(samaritan)
BOOST_SPIRIT_X3_SCRIPT(old_south_arabian)
BOOST_SPIRIT_X3_SCRIPT(saurashtra)
BOOST_SPIRIT_X3_SCRIPT(signwriting)
BOOST_SPIRIT_X3_SCRIPT(shavian)
BOOST_SPIRIT_X3_SCRIPT(sharada)
BOOST_SPIRIT_X3_SCRIPT(siddham)
BOOST_SPIRIT_X3_SCRIPT(khudawadi)
BOOST_SPIRIT_X3_SCRIPT(sinhala)
BOOST_SPIRIT_X3_SCRIPT(sogdian)
BOOST_SPIRIT_X3_SCRIPT(old_sogdian)
BOOST_SPIRIT_X3_SCRIPT(sora_sompeng)
BOOST_SPIRIT_X3_SCRIPT(soyombo)
BOOST_SPIRIT_X3_SCRIPT(sundanese)
BOOST_SPIRIT_X3_SCRIPT(syloti_nagri)
BOOST_SPIRIT_X3_SCRIPT(syriac)
BOOST_SPIRIT_X3_SCRIPT(tagbanwa)
BOOST_SPIRIT_X3_SCRIPT(takri)
BOOST_SPIRIT_X3_SCRIPT(tai_le)
BOOST_SPIRIT_X3_SCRIPT(new_tai_lue)
BOOST_SPIRIT_X3_SCRIPT(tamil)
BOOST_SPIRIT_X3_SCRIPT(tangut)
BOOST_SPIRIT_X3_SCRIPT(tai_viet)
BOOST_SPIRIT_X3_SCRIPT(telugu)
BOOST_SPIRIT_X3_SCRIPT(tifinagh)
BOOST_SPIRIT_X3_SCRIPT(tagalog)
BOOST_SPIRIT_X3_SCRIPT(thaana)
BOOST_SPIRIT_X3_SCRIPT(thai)
BOOST_SPIRIT_X3_SCRIPT(tibetan)
BOOST_SPIRIT_X3_SCRIPT(tirhuta)
BOOST_SPIRIT_X3_SCRIPT(tangsa)
BOOST_SPIRIT_X3_SCRIPT(toto)
BOOST_SPIRIT_X3_SCRIPT(ugaritic)
BOOST_SPIRIT_X3_SCRIPT(vai)
BOOST_SPIRIT_X3_SCRIPT(vithkuqi)
BOOST_SPIRIT_X3_SCRIPT(warang_citi)
BOOST_SPIRIT_X3_SCRIPT(wancho)
BOOST_SPIRIT_X3_SCRIPT(old_persian)
BOOST_SPIRIT_X3_SCRIPT(cuneiform)
BOOST_SPIRIT_X3_SCRIPT(yezidi)
BOOST_SPIRIT_X3_SCRIPT(yi)
BOOST_SPIRIT_X3_SCRIPT(zanabazar_square)
BOOST_SPIRIT_X3_SCRIPT(inherited)
BOOST_SPIRIT_X3_SCRIPT(common)
BOOST_SPIRIT_X3_SCRIPT(unknown)
#undef BOOST_SPIRIT_X3_SCRIPT
};
} // boost::spirit::x3::char_encoding
#endif
@@ -1,377 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Autogenerated by MultiStageTable.py (Unicode multi-stage
table builder) (c) Peter Kankowski, 2008
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_CHAR_ENCODING_UNICODE_CLASSIFICATION_HPP
#define BOOST_SPIRIT_X3_CHAR_ENCODING_UNICODE_CLASSIFICATION_HPP
#include <boost/spirit/home/x3/char_encoding/unicode/detail/category_table.hpp>
#include <boost/spirit/home/x3/char_encoding/unicode/detail/script_table.hpp>
#include <boost/spirit/home/x3/char_encoding/unicode/detail/lowercase_table.hpp>
#include <boost/spirit/home/x3/char_encoding/unicode/detail/uppercase_table.hpp>
#include <cstdint>
namespace boost::spirit::x3::unicode
{
// This header provides Basic (Level 1) Unicode Support
// See http://unicode.org/reports/tr18/ for details
namespace properties
{
// bit pattern: xxMMMCCC
// MMM: major_category
// CCC: category
enum major_category
{
letter,
mark,
number,
separator,
other,
punctuation,
symbol
};
enum category
{
uppercase_letter = 0, // [Lu] an uppercase letter
lowercase_letter, // [Ll] a lowercase letter
titlecase_letter, // [Lt] a digraphic character, with first part uppercase
modifier_letter, // [Lm] a modifier letter
other_letter, // [Lo] other letters, including syllables and ideographs
nonspacing_mark = 8, // [Mn] a nonspacing combining mark (zero advance width)
enclosing_mark, // [Me] an enclosing combining mark
spacing_mark, // [Mc] a spacing combining mark (positive advance width)
decimal_number = 16, // [Nd] a decimal digit
letter_number, // [Nl] a letterlike numeric character
other_number, // [No] a numeric character of other type
space_separator = 24, // [Zs] a space character (of various non-zero widths)
line_separator, // [Zl] U+2028 LINE SEPARATOR only
paragraph_separator, // [Zp] U+2029 PARAGRAPH SEPARATOR only
control = 32, // [Cc] a C0 or C1 control code
format, // [Cf] a format control character
private_use, // [Co] a private-use character
surrogate, // [Cs] a surrogate code point
unassigned, // [Cn] a reserved unassigned code point or a noncharacter
dash_punctuation = 40, // [Pd] a dash or hyphen punctuation mark
open_punctuation, // [Ps] an opening punctuation mark (of a pair)
close_punctuation, // [Pe] a closing punctuation mark (of a pair)
connector_punctuation, // [Pc] a connecting punctuation mark, like a tie
other_punctuation, // [Po] a punctuation mark of other type
initial_punctuation, // [Pi] an initial quotation mark
final_punctuation, // [Pf] a final quotation mark
math_symbol = 48, // [Sm] a symbol of primarily mathematical use
currency_symbol, // [Sc] a currency sign
modifier_symbol, // [Sk] a non-letterlike modifier symbol
other_symbol // [So] a symbol of other type
};
enum derived_properties
{
alphabetic = 64,
uppercase = 128,
lowercase = 256,
white_space = 512,
hex_digit = 1024,
noncharacter_code_point = 2048,
default_ignorable_code_point = 4096
};
enum script
{
adlam,
caucasian_albanian,
ahom,
arabic,
imperial_aramaic,
armenian,
avestan,
balinese,
bamum,
bassa_vah,
batak,
bengali,
bhaiksuki,
bopomofo,
brahmi,
braille,
buginese,
buhid,
chakma,
canadian_aboriginal,
carian,
cham,
cherokee,
chorasmian,
coptic,
cypro_minoan,
cypriot,
cyrillic,
devanagari,
dives_akuru,
dogra,
deseret,
duployan,
egyptian_hieroglyphs,
elbasan,
elymaic,
ethiopic,
georgian,
glagolitic,
gunjala_gondi,
masaram_gondi,
gothic,
grantha,
greek,
gujarati,
gurmukhi,
hangul,
han,
hanunoo,
hatran,
hebrew,
hiragana,
anatolian_hieroglyphs,
pahawh_hmong,
nyiakeng_puachue_hmong,
katakana_or_hiragana,
old_hungarian,
old_italic,
javanese,
kayah_li,
katakana,
kawi,
kharoshthi,
khmer,
khojki,
khitan_small_script,
kannada,
kaithi,
tai_tham,
lao,
latin,
lepcha,
limbu,
linear_a,
linear_b,
lisu,
lycian,
lydian,
mahajani,
makasar,
mandaic,
manichaean,
marchen,
medefaidrin,
mende_kikakui,
meroitic_cursive,
meroitic_hieroglyphs,
malayalam,
modi,
mongolian,
mro,
meetei_mayek,
multani,
myanmar,
nag_mundari,
nandinagari,
old_north_arabian,
nabataean,
newa,
nko,
nushu,
ogham,
ol_chiki,
old_turkic,
oriya,
osage,
osmanya,
old_uyghur,
palmyrene,
pau_cin_hau,
old_permic,
phags_pa,
inscriptional_pahlavi,
psalter_pahlavi,
phoenician,
miao,
inscriptional_parthian,
rejang,
hanifi_rohingya,
runic,
samaritan,
old_south_arabian,
saurashtra,
signwriting,
shavian,
sharada,
siddham,
khudawadi,
sinhala,
sogdian,
old_sogdian,
sora_sompeng,
soyombo,
sundanese,
syloti_nagri,
syriac,
tagbanwa,
takri,
tai_le,
new_tai_lue,
tamil,
tangut,
tai_viet,
telugu,
tifinagh,
tagalog,
thaana,
thai,
tibetan,
tirhuta,
tangsa,
toto,
ugaritic,
vai,
vithkuqi,
warang_citi,
wancho,
old_persian,
cuneiform,
yezidi,
yi,
zanabazar_square,
inherited,
common,
unknown
};
} // properties
[[nodiscard]] constexpr properties::category get_category(std::uint32_t ch) noexcept
{
return static_cast<properties::category>(detail::category_lookup(ch) & 0x3F);
}
[[nodiscard]] constexpr properties::major_category get_major_category(std::uint32_t ch) noexcept
{
return static_cast<properties::major_category>(unicode::get_category(ch) >> 3);
}
[[nodiscard]] constexpr bool is_punctuation(std::uint32_t ch) noexcept
{
return unicode::get_major_category(ch) == properties::punctuation;
}
[[nodiscard]] constexpr bool is_decimal_number(std::uint32_t ch) noexcept
{
return unicode::get_category(ch) == properties::decimal_number;
}
[[nodiscard]] constexpr bool is_hex_digit(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::hex_digit) != 0;
}
[[nodiscard]] constexpr bool is_control(std::uint32_t ch) noexcept
{
return unicode::get_category(ch) == properties::control;
}
[[nodiscard]] constexpr bool is_alphabetic(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::alphabetic) != 0;
}
[[nodiscard]] constexpr bool is_alphanumeric(std::uint32_t ch) noexcept
{
return unicode::is_decimal_number(ch) || unicode::is_alphabetic(ch);
}
[[nodiscard]] constexpr bool is_uppercase(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::uppercase) != 0;
}
[[nodiscard]] constexpr bool is_lowercase(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::lowercase) != 0;
}
[[nodiscard]] constexpr bool is_white_space(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::white_space) != 0;
}
[[nodiscard]] constexpr bool is_blank(std::uint32_t ch) noexcept
{
switch (ch)
{
case '\n': case '\v': case '\f': case '\r':
return false;
default:
return unicode::is_white_space(ch)
&& !( unicode::get_category(ch) == properties::line_separator
|| unicode::get_category(ch) == properties::paragraph_separator
);
}
}
[[nodiscard]] constexpr bool is_graph(std::uint32_t ch) noexcept
{
return !( unicode::is_white_space(ch)
|| unicode::get_category(ch) == properties::control
|| unicode::get_category(ch) == properties::surrogate
|| unicode::get_category(ch) == properties::unassigned
);
}
[[nodiscard]] constexpr bool is_print(std::uint32_t ch) noexcept
{
return (unicode::is_graph(ch) || unicode::is_blank(ch)) && !unicode::is_control(ch);
}
[[nodiscard]] constexpr bool is_noncharacter_code_point(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::noncharacter_code_point) != 0;
}
[[nodiscard]] constexpr bool is_default_ignorable_code_point(std::uint32_t ch) noexcept
{
return (detail::category_lookup(ch) & properties::default_ignorable_code_point) != 0;
}
[[nodiscard]] constexpr properties::script get_script(std::uint32_t ch) noexcept
{
return static_cast<properties::script>(detail::script_lookup(ch));
}
[[nodiscard]] constexpr std::uint32_t to_lowercase(std::uint32_t ch) noexcept
{
// The table returns 0 to signal that this code maps to itself
std::uint32_t r = detail::lowercase_lookup(ch);
return (r == 0)? ch : r;
}
[[nodiscard]] constexpr std::uint32_t to_uppercase(std::uint32_t ch) noexcept
{
// The table returns 0 to signal that this code maps to itself
std::uint32_t r = detail::uppercase_lookup(ch);
return (r == 0)? ch : r;
}
} // boost::spirit::x3::unicode
#endif
File diff suppressed because it is too large Load Diff
@@ -1,754 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
AUTOGENERATED. DO NOT EDIT!!!
==============================================================================*/
#include <cstdint>
namespace boost::spirit::x3::unicode::detail
{
inline constexpr std::uint8_t lowercase_stage1[] = {
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 10, 11,
6, 12, 6, 6, 13, 6, 6, 6, 6, 6, 6, 6, 14, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 15, 16, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 17,
6, 6, 6, 6, 18, 19, 6, 6, 6, 6, 6, 6, 20, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 21, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 22, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 23, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
};
inline constexpr std::uint32_t lowercase_stage2[] = {
// block 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 0, 248, 249, 250, 251, 252, 253, 254, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 1
257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 0, 271, 0,
273, 0, 275, 0, 277, 0, 279, 0, 281, 0, 283, 0, 285, 0, 287, 0,
289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 0, 303, 0,
105, 0, 307, 0, 309, 0, 311, 0, 0, 314, 0, 316, 0, 318, 0, 320,
0, 322, 0, 324, 0, 326, 0, 328, 0, 0, 331, 0, 333, 0, 335, 0,
337, 0, 339, 0, 341, 0, 343, 0, 345, 0, 347, 0, 349, 0, 351, 0,
353, 0, 355, 0, 357, 0, 359, 0, 361, 0, 363, 0, 365, 0, 367, 0,
369, 0, 371, 0, 373, 0, 375, 0, 255, 378, 0, 380, 0, 382, 0, 0,
0, 595, 387, 0, 389, 0, 596, 392, 0, 598, 599, 396, 0, 0, 477, 601,
603, 402, 0, 608, 611, 0, 617, 616, 409, 0, 0, 0, 623, 626, 0, 629,
417, 0, 419, 0, 421, 0, 640, 424, 0, 643, 0, 0, 429, 0, 648, 432,
0, 650, 651, 436, 0, 438, 0, 658, 441, 0, 0, 0, 445, 0, 0, 0,
0, 0, 0, 0, 454, 454, 0, 457, 457, 0, 460, 460, 0, 462, 0, 464,
0, 466, 0, 468, 0, 470, 0, 472, 0, 474, 0, 476, 0, 0, 479, 0,
481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0,
0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0,
// block 2
513, 0, 515, 0, 517, 0, 519, 0, 521, 0, 523, 0, 525, 0, 527, 0,
529, 0, 531, 0, 533, 0, 535, 0, 537, 0, 539, 0, 541, 0, 543, 0,
414, 0, 547, 0, 549, 0, 551, 0, 553, 0, 555, 0, 557, 0, 559, 0,
561, 0, 563, 0, 0, 0, 0, 0, 0, 0, 11365, 572, 0, 410, 11366, 0,
0, 578, 0, 384, 649, 652, 583, 0, 585, 0, 587, 0, 589, 0, 591, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
881, 0, 883, 0, 0, 0, 887, 0, 0, 0, 0, 0, 0, 0, 0, 1011,
0, 0, 0, 0, 0, 0, 940, 0, 941, 942, 943, 0, 972, 0, 973, 974,
0, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959,
960, 961, 0, 963, 964, 965, 966, 967, 968, 969, 970, 971, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983,
0, 0, 0, 0, 0, 0, 0, 0, 985, 0, 987, 0, 989, 0, 991, 0,
993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0,
0, 0, 0, 0, 952, 0, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893,
// block 4
1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119,
1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1121, 0, 1123, 0, 1125, 0, 1127, 0, 1129, 0, 1131, 0, 1133, 0, 1135, 0,
1137, 0, 1139, 0, 1141, 0, 1143, 0, 1145, 0, 1147, 0, 1149, 0, 1151, 0,
1153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1163, 0, 1165, 0, 1167, 0,
1169, 0, 1171, 0, 1173, 0, 1175, 0, 1177, 0, 1179, 0, 1181, 0, 1183, 0,
1185, 0, 1187, 0, 1189, 0, 1191, 0, 1193, 0, 1195, 0, 1197, 0, 1199, 0,
1201, 0, 1203, 0, 1205, 0, 1207, 0, 1209, 0, 1211, 0, 1213, 0, 1215, 0,
1231, 1218, 0, 1220, 0, 1222, 0, 1224, 0, 1226, 0, 1228, 0, 1230, 0, 0,
1233, 0, 1235, 0, 1237, 0, 1239, 0, 1241, 0, 1243, 0, 1245, 0, 1247, 0,
1249, 0, 1251, 0, 1253, 0, 1255, 0, 1257, 0, 1259, 0, 1261, 0, 1263, 0,
1265, 0, 1267, 0, 1269, 0, 1271, 0, 1273, 0, 1275, 0, 1277, 0, 1279, 0,
// block 5
1281, 0, 1283, 0, 1285, 0, 1287, 0, 1289, 0, 1291, 0, 1293, 0, 1295, 0,
1297, 0, 1299, 0, 1301, 0, 1303, 0, 1305, 0, 1307, 0, 1309, 0, 1311, 0,
1313, 0, 1315, 0, 1317, 0, 1319, 0, 1321, 0, 1323, 0, 1325, 0, 1327, 0,
0, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407,
1408, 1409, 1410, 1411, 1412, 1413, 1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11520, 11521, 11522, 11523, 11524, 11525, 11526, 11527, 11528, 11529, 11530, 11531, 11532, 11533, 11534, 11535,
11536, 11537, 11538, 11539, 11540, 11541, 11542, 11543, 11544, 11545, 11546, 11547, 11548, 11549, 11550, 11551,
11552, 11553, 11554, 11555, 11556, 11557, 0, 11559, 0, 0, 0, 0, 0, 11565, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43888, 43889, 43890, 43891, 43892, 43893, 43894, 43895, 43896, 43897, 43898, 43899, 43900, 43901, 43902, 43903,
43904, 43905, 43906, 43907, 43908, 43909, 43910, 43911, 43912, 43913, 43914, 43915, 43916, 43917, 43918, 43919,
43920, 43921, 43922, 43923, 43924, 43925, 43926, 43927, 43928, 43929, 43930, 43931, 43932, 43933, 43934, 43935,
43936, 43937, 43938, 43939, 43940, 43941, 43942, 43943, 43944, 43945, 43946, 43947, 43948, 43949, 43950, 43951,
43952, 43953, 43954, 43955, 43956, 43957, 43958, 43959, 43960, 43961, 43962, 43963, 43964, 43965, 43966, 43967,
5112, 5113, 5114, 5115, 5116, 5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319,
4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335,
4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 0, 0, 4349, 4350, 4351,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 10
7681, 0, 7683, 0, 7685, 0, 7687, 0, 7689, 0, 7691, 0, 7693, 0, 7695, 0,
7697, 0, 7699, 0, 7701, 0, 7703, 0, 7705, 0, 7707, 0, 7709, 0, 7711, 0,
7713, 0, 7715, 0, 7717, 0, 7719, 0, 7721, 0, 7723, 0, 7725, 0, 7727, 0,
7729, 0, 7731, 0, 7733, 0, 7735, 0, 7737, 0, 7739, 0, 7741, 0, 7743, 0,
7745, 0, 7747, 0, 7749, 0, 7751, 0, 7753, 0, 7755, 0, 7757, 0, 7759, 0,
7761, 0, 7763, 0, 7765, 0, 7767, 0, 7769, 0, 7771, 0, 7773, 0, 7775, 0,
7777, 0, 7779, 0, 7781, 0, 7783, 0, 7785, 0, 7787, 0, 7789, 0, 7791, 0,
7793, 0, 7795, 0, 7797, 0, 7799, 0, 7801, 0, 7803, 0, 7805, 0, 7807, 0,
7809, 0, 7811, 0, 7813, 0, 7815, 0, 7817, 0, 7819, 0, 7821, 0, 7823, 0,
7825, 0, 7827, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0,
7841, 0, 7843, 0, 7845, 0, 7847, 0, 7849, 0, 7851, 0, 7853, 0, 7855, 0,
7857, 0, 7859, 0, 7861, 0, 7863, 0, 7865, 0, 7867, 0, 7869, 0, 7871, 0,
7873, 0, 7875, 0, 7877, 0, 7879, 0, 7881, 0, 7883, 0, 7885, 0, 7887, 0,
7889, 0, 7891, 0, 7893, 0, 7895, 0, 7897, 0, 7899, 0, 7901, 0, 7903, 0,
7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0,
7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0,
// block 11
0, 0, 0, 0, 0, 0, 0, 0, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943,
0, 0, 0, 0, 0, 0, 0, 0, 7952, 7953, 7954, 7955, 7956, 7957, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975,
0, 0, 0, 0, 0, 0, 0, 0, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991,
0, 0, 0, 0, 0, 0, 0, 0, 8000, 8001, 8002, 8003, 8004, 8005, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8017, 0, 8019, 0, 8021, 0, 8023,
0, 0, 0, 0, 0, 0, 0, 0, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071,
0, 0, 0, 0, 0, 0, 0, 0, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087,
0, 0, 0, 0, 0, 0, 0, 0, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103,
0, 0, 0, 0, 0, 0, 0, 0, 8112, 8113, 8048, 8049, 8115, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8050, 8051, 8052, 8053, 8131, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8144, 8145, 8054, 8055, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0,
// block 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 969, 0, 0, 0, 107, 229, 0, 0, 0, 0,
0, 0, 8526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8560, 8561, 8562, 8563, 8564, 8565, 8566, 8567, 8568, 8569, 8570, 8571, 8572, 8573, 8574, 8575,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, 9433,
9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 14
11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327,
11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343,
11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 11359,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11361, 0, 619, 7549, 637, 0, 0, 11368, 0, 11370, 0, 11372, 0, 593, 625, 592,
594, 0, 11379, 0, 0, 11382, 0, 0, 0, 0, 0, 0, 0, 0, 575, 576,
11393, 0, 11395, 0, 11397, 0, 11399, 0, 11401, 0, 11403, 0, 11405, 0, 11407, 0,
11409, 0, 11411, 0, 11413, 0, 11415, 0, 11417, 0, 11419, 0, 11421, 0, 11423, 0,
11425, 0, 11427, 0, 11429, 0, 11431, 0, 11433, 0, 11435, 0, 11437, 0, 11439, 0,
11441, 0, 11443, 0, 11445, 0, 11447, 0, 11449, 0, 11451, 0, 11453, 0, 11455, 0,
11457, 0, 11459, 0, 11461, 0, 11463, 0, 11465, 0, 11467, 0, 11469, 0, 11471, 0,
11473, 0, 11475, 0, 11477, 0, 11479, 0, 11481, 0, 11483, 0, 11485, 0, 11487, 0,
11489, 0, 11491, 0, 0, 0, 0, 0, 0, 0, 0, 11500, 0, 11502, 0, 0,
0, 0, 11507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42561, 0, 42563, 0, 42565, 0, 42567, 0, 42569, 0, 42571, 0, 42573, 0, 42575, 0,
42577, 0, 42579, 0, 42581, 0, 42583, 0, 42585, 0, 42587, 0, 42589, 0, 42591, 0,
42593, 0, 42595, 0, 42597, 0, 42599, 0, 42601, 0, 42603, 0, 42605, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42625, 0, 42627, 0, 42629, 0, 42631, 0, 42633, 0, 42635, 0, 42637, 0, 42639, 0,
42641, 0, 42643, 0, 42645, 0, 42647, 0, 42649, 0, 42651, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 16
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 42787, 0, 42789, 0, 42791, 0, 42793, 0, 42795, 0, 42797, 0, 42799, 0,
0, 0, 42803, 0, 42805, 0, 42807, 0, 42809, 0, 42811, 0, 42813, 0, 42815, 0,
42817, 0, 42819, 0, 42821, 0, 42823, 0, 42825, 0, 42827, 0, 42829, 0, 42831, 0,
42833, 0, 42835, 0, 42837, 0, 42839, 0, 42841, 0, 42843, 0, 42845, 0, 42847, 0,
42849, 0, 42851, 0, 42853, 0, 42855, 0, 42857, 0, 42859, 0, 42861, 0, 42863, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 42874, 0, 42876, 0, 7545, 42879, 0,
42881, 0, 42883, 0, 42885, 0, 42887, 0, 0, 0, 0, 42892, 0, 613, 0, 0,
42897, 0, 42899, 0, 0, 0, 42903, 0, 42905, 0, 42907, 0, 42909, 0, 42911, 0,
42913, 0, 42915, 0, 42917, 0, 42919, 0, 42921, 0, 614, 604, 609, 620, 618, 0,
670, 647, 669, 43859, 42933, 0, 42935, 0, 42937, 0, 42939, 0, 42941, 0, 42943, 0,
42945, 0, 42947, 0, 42900, 642, 7566, 42952, 0, 42954, 0, 0, 0, 0, 0, 0,
42961, 0, 0, 0, 0, 0, 42967, 0, 42969, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 42998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 17
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359,
65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 18
66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,
66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627, 66628, 66629, 66630, 66631,
66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66776, 66777, 66778, 66779, 66780, 66781, 66782, 66783, 66784, 66785, 66786, 66787, 66788, 66789, 66790, 66791,
66792, 66793, 66794, 66795, 66796, 66797, 66798, 66799, 66800, 66801, 66802, 66803, 66804, 66805, 66806, 66807,
66808, 66809, 66810, 66811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 19
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66967, 66968, 66969, 66970, 66971, 66972, 66973, 66974, 66975, 66976, 66977, 0, 66979, 66980, 66981, 66982,
66983, 66984, 66985, 66986, 66987, 66988, 66989, 66990, 66991, 66992, 66993, 0, 66995, 66996, 66997, 66998,
66999, 67000, 67001, 0, 67003, 67004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 20
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68800, 68801, 68802, 68803, 68804, 68805, 68806, 68807, 68808, 68809, 68810, 68811, 68812, 68813, 68814, 68815,
68816, 68817, 68818, 68819, 68820, 68821, 68822, 68823, 68824, 68825, 68826, 68827, 68828, 68829, 68830, 68831,
68832, 68833, 68834, 68835, 68836, 68837, 68838, 68839, 68840, 68841, 68842, 68843, 68844, 68845, 68846, 68847,
68848, 68849, 68850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 21
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71872, 71873, 71874, 71875, 71876, 71877, 71878, 71879, 71880, 71881, 71882, 71883, 71884, 71885, 71886, 71887,
71888, 71889, 71890, 71891, 71892, 71893, 71894, 71895, 71896, 71897, 71898, 71899, 71900, 71901, 71902, 71903,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 22
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93792, 93793, 93794, 93795, 93796, 93797, 93798, 93799, 93800, 93801, 93802, 93803, 93804, 93805, 93806, 93807,
93808, 93809, 93810, 93811, 93812, 93813, 93814, 93815, 93816, 93817, 93818, 93819, 93820, 93821, 93822, 93823,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 23
125218, 125219, 125220, 125221, 125222, 125223, 125224, 125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233,
125234, 125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244, 125245, 125246, 125247, 125248, 125249,
125250, 125251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
[[nodiscard]] constexpr std::uint32_t lowercase_lookup(std::uint32_t ch) noexcept
{
std::uint32_t block_offset = lowercase_stage1[ch / 256] * 256;
return lowercase_stage2[block_offset + ch % 256];
}
} // boost::spirit::x3::unicode::detail
File diff suppressed because it is too large Load Diff
@@ -1,811 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
AUTOGENERATED. DO NOT EDIT!!!
==============================================================================*/
#include <cstdint>
namespace boost::spirit::x3::unicode::detail
{
inline constexpr std::uint8_t uppercase_stage1[] = {
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 9, 10, 11, 12,
6, 13, 6, 6, 14, 6, 6, 6, 6, 6, 6, 6, 15, 16, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 17, 18, 6, 6, 6, 19, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 20,
6, 6, 6, 6, 21, 22, 6, 6, 6, 6, 6, 6, 23, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 24, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 26, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
};
inline constexpr std::uint32_t uppercase_stage2[] = {
// block 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 0, 216, 217, 218, 219, 220, 221, 222, 376,
// block 1
0, 256, 0, 258, 0, 260, 0, 262, 0, 264, 0, 266, 0, 268, 0, 270,
0, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286,
0, 288, 0, 290, 0, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302,
0, 73, 0, 306, 0, 308, 0, 310, 0, 0, 313, 0, 315, 0, 317, 0,
319, 0, 321, 0, 323, 0, 325, 0, 327, 0, 0, 330, 0, 332, 0, 334,
0, 336, 0, 338, 0, 340, 0, 342, 0, 344, 0, 346, 0, 348, 0, 350,
0, 352, 0, 354, 0, 356, 0, 358, 0, 360, 0, 362, 0, 364, 0, 366,
0, 368, 0, 370, 0, 372, 0, 374, 0, 0, 377, 0, 379, 0, 381, 83,
579, 0, 0, 386, 0, 388, 0, 0, 391, 0, 0, 0, 395, 0, 0, 0,
0, 0, 401, 0, 0, 502, 0, 0, 0, 408, 573, 0, 0, 0, 544, 0,
0, 416, 0, 418, 0, 420, 0, 0, 423, 0, 0, 0, 0, 428, 0, 0,
431, 0, 0, 0, 435, 0, 437, 0, 0, 440, 0, 0, 0, 444, 0, 503,
0, 0, 0, 0, 0, 452, 452, 0, 455, 455, 0, 458, 458, 0, 461, 0,
463, 0, 465, 0, 467, 0, 469, 0, 471, 0, 473, 0, 475, 398, 0, 478,
0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494,
0, 0, 497, 497, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510,
// block 2
0, 512, 0, 514, 0, 516, 0, 518, 0, 520, 0, 522, 0, 524, 0, 526,
0, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 0, 540, 0, 542,
0, 0, 0, 546, 0, 548, 0, 550, 0, 552, 0, 554, 0, 556, 0, 558,
0, 560, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 11390,
11391, 0, 577, 0, 0, 0, 0, 582, 0, 584, 0, 586, 0, 588, 0, 590,
11375, 11373, 11376, 385, 390, 0, 393, 394, 0, 399, 0, 400, 42923, 0, 0, 0,
403, 42924, 0, 404, 0, 42893, 42922, 0, 407, 406, 42926, 11362, 42925, 0, 0, 412,
0, 11374, 413, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 11364, 0, 0,
422, 0, 42949, 425, 0, 0, 0, 42929, 430, 580, 433, 434, 581, 0, 0, 0,
0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42930, 42928, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 880, 0, 882, 0, 0, 0, 886, 0, 0, 0, 1021, 1022, 1023, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 902, 904, 905, 906,
0, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927,
928, 929, 931, 931, 932, 933, 934, 935, 936, 937, 938, 939, 908, 910, 911, 0,
914, 920, 0, 0, 0, 934, 928, 975, 0, 984, 0, 986, 0, 988, 0, 990,
0, 992, 0, 994, 0, 996, 0, 998, 0, 1000, 0, 1002, 0, 1004, 0, 1006,
922, 929, 1017, 895, 0, 917, 0, 0, 1015, 0, 0, 1018, 0, 0, 0, 0,
// block 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071,
1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
0, 1120, 0, 1122, 0, 1124, 0, 1126, 0, 1128, 0, 1130, 0, 1132, 0, 1134,
0, 1136, 0, 1138, 0, 1140, 0, 1142, 0, 1144, 0, 1146, 0, 1148, 0, 1150,
0, 1152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 1164, 0, 1166,
0, 1168, 0, 1170, 0, 1172, 0, 1174, 0, 1176, 0, 1178, 0, 1180, 0, 1182,
0, 1184, 0, 1186, 0, 1188, 0, 1190, 0, 1192, 0, 1194, 0, 1196, 0, 1198,
0, 1200, 0, 1202, 0, 1204, 0, 1206, 0, 1208, 0, 1210, 0, 1212, 0, 1214,
0, 0, 1217, 0, 1219, 0, 1221, 0, 1223, 0, 1225, 0, 1227, 0, 1229, 1216,
0, 1232, 0, 1234, 0, 1236, 0, 1238, 0, 1240, 0, 1242, 0, 1244, 0, 1246,
0, 1248, 0, 1250, 0, 1252, 0, 1254, 0, 1256, 0, 1258, 0, 1260, 0, 1262,
0, 1264, 0, 1266, 0, 1268, 0, 1270, 0, 1272, 0, 1274, 0, 1276, 0, 1278,
// block 5
0, 1280, 0, 1282, 0, 1284, 0, 1286, 0, 1288, 0, 1290, 0, 1292, 0, 1294,
0, 1296, 0, 1298, 0, 1300, 0, 1302, 0, 1304, 0, 1306, 0, 1308, 0, 1310,
0, 1312, 0, 1314, 0, 1316, 0, 1318, 0, 1320, 0, 1322, 0, 1324, 0, 1326,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343,
1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359,
1360, 1361, 1362, 1363, 1364, 1365, 1366, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7312, 7313, 7314, 7315, 7316, 7317, 7318, 7319, 7320, 7321, 7322, 7323, 7324, 7325, 7326, 7327,
7328, 7329, 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 7342, 7343,
7344, 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, 0, 0, 7357, 7358, 7359,
// block 8
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 5104, 5105, 5106, 5107, 5108, 5109, 0, 0,
// block 9
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1042, 1044, 1054, 1057, 1058, 1058, 1066, 1122, 42570, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 42877, 0, 0, 0, 11363, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42950, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 11
0, 7680, 0, 7682, 0, 7684, 0, 7686, 0, 7688, 0, 7690, 0, 7692, 0, 7694,
0, 7696, 0, 7698, 0, 7700, 0, 7702, 0, 7704, 0, 7706, 0, 7708, 0, 7710,
0, 7712, 0, 7714, 0, 7716, 0, 7718, 0, 7720, 0, 7722, 0, 7724, 0, 7726,
0, 7728, 0, 7730, 0, 7732, 0, 7734, 0, 7736, 0, 7738, 0, 7740, 0, 7742,
0, 7744, 0, 7746, 0, 7748, 0, 7750, 0, 7752, 0, 7754, 0, 7756, 0, 7758,
0, 7760, 0, 7762, 0, 7764, 0, 7766, 0, 7768, 0, 7770, 0, 7772, 0, 7774,
0, 7776, 0, 7778, 0, 7780, 0, 7782, 0, 7784, 0, 7786, 0, 7788, 0, 7790,
0, 7792, 0, 7794, 0, 7796, 0, 7798, 0, 7800, 0, 7802, 0, 7804, 0, 7806,
0, 7808, 0, 7810, 0, 7812, 0, 7814, 0, 7816, 0, 7818, 0, 7820, 0, 7822,
0, 7824, 0, 7826, 0, 7828, 0, 0, 0, 0, 0, 7776, 0, 0, 0, 0,
0, 7840, 0, 7842, 0, 7844, 0, 7846, 0, 7848, 0, 7850, 0, 7852, 0, 7854,
0, 7856, 0, 7858, 0, 7860, 0, 7862, 0, 7864, 0, 7866, 0, 7868, 0, 7870,
0, 7872, 0, 7874, 0, 7876, 0, 7878, 0, 7880, 0, 7882, 0, 7884, 0, 7886,
0, 7888, 0, 7890, 0, 7892, 0, 7894, 0, 7896, 0, 7898, 0, 7900, 0, 7902,
0, 7904, 0, 7906, 0, 7908, 0, 7910, 0, 7912, 0, 7914, 0, 7916, 0, 7918,
0, 7920, 0, 7922, 0, 7924, 0, 7926, 0, 7928, 0, 7930, 0, 7932, 0, 7934,
// block 12
7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 0, 0, 0, 0, 0, 0, 0, 0,
7960, 7961, 7962, 7963, 7964, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 0, 0, 0, 0, 0, 0, 0, 0,
7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 0, 0, 0, 0, 0, 0, 0, 0,
8008, 8009, 8010, 8011, 8012, 8013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8025, 0, 8027, 0, 8029, 0, 8031, 0, 0, 0, 0, 0, 0, 0, 0,
8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 0, 0, 0, 0, 0, 0, 0, 0,
8122, 8123, 8136, 8137, 8138, 8139, 8154, 8155, 8184, 8185, 8170, 8171, 8186, 8187, 0, 0,
8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 0, 0, 0, 0, 0, 0, 0, 0,
8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 0, 0, 0, 0, 0, 0, 0, 0,
8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 0, 0, 0, 0, 0, 0, 0, 0,
8120, 8121, 0, 8124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, 0,
0, 0, 0, 8140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8152, 8153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8168, 8169, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8498, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8544, 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 8558, 8559,
0, 0, 0, 0, 8579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413,
9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, 11278, 11279,
11280, 11281, 11282, 11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, 11294, 11295,
11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 11307, 11308, 11309, 11310, 11311,
0, 11360, 0, 0, 0, 570, 574, 0, 11367, 0, 11369, 0, 11371, 0, 0, 0,
0, 0, 0, 11378, 0, 0, 11381, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 11392, 0, 11394, 0, 11396, 0, 11398, 0, 11400, 0, 11402, 0, 11404, 0, 11406,
0, 11408, 0, 11410, 0, 11412, 0, 11414, 0, 11416, 0, 11418, 0, 11420, 0, 11422,
0, 11424, 0, 11426, 0, 11428, 0, 11430, 0, 11432, 0, 11434, 0, 11436, 0, 11438,
0, 11440, 0, 11442, 0, 11444, 0, 11446, 0, 11448, 0, 11450, 0, 11452, 0, 11454,
0, 11456, 0, 11458, 0, 11460, 0, 11462, 0, 11464, 0, 11466, 0, 11468, 0, 11470,
0, 11472, 0, 11474, 0, 11476, 0, 11478, 0, 11480, 0, 11482, 0, 11484, 0, 11486,
0, 11488, 0, 11490, 0, 0, 0, 0, 0, 0, 0, 0, 11499, 0, 11501, 0,
0, 0, 0, 11506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 16
4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271,
4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287,
4288, 4289, 4290, 4291, 4292, 4293, 0, 4295, 0, 0, 0, 0, 0, 4301, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 17
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 42560, 0, 42562, 0, 42564, 0, 42566, 0, 42568, 0, 42570, 0, 42572, 0, 42574,
0, 42576, 0, 42578, 0, 42580, 0, 42582, 0, 42584, 0, 42586, 0, 42588, 0, 42590,
0, 42592, 0, 42594, 0, 42596, 0, 42598, 0, 42600, 0, 42602, 0, 42604, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 42624, 0, 42626, 0, 42628, 0, 42630, 0, 42632, 0, 42634, 0, 42636, 0, 42638,
0, 42640, 0, 42642, 0, 42644, 0, 42646, 0, 42648, 0, 42650, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 18
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 42786, 0, 42788, 0, 42790, 0, 42792, 0, 42794, 0, 42796, 0, 42798,
0, 0, 0, 42802, 0, 42804, 0, 42806, 0, 42808, 0, 42810, 0, 42812, 0, 42814,
0, 42816, 0, 42818, 0, 42820, 0, 42822, 0, 42824, 0, 42826, 0, 42828, 0, 42830,
0, 42832, 0, 42834, 0, 42836, 0, 42838, 0, 42840, 0, 42842, 0, 42844, 0, 42846,
0, 42848, 0, 42850, 0, 42852, 0, 42854, 0, 42856, 0, 42858, 0, 42860, 0, 42862,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42873, 0, 42875, 0, 0, 42878,
0, 42880, 0, 42882, 0, 42884, 0, 42886, 0, 0, 0, 0, 42891, 0, 0, 0,
0, 42896, 0, 42898, 42948, 0, 0, 42902, 0, 42904, 0, 42906, 0, 42908, 0, 42910,
0, 42912, 0, 42914, 0, 42916, 0, 42918, 0, 42920, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 42932, 0, 42934, 0, 42936, 0, 42938, 0, 42940, 0, 42942,
0, 42944, 0, 42946, 0, 0, 0, 0, 42951, 0, 42953, 0, 0, 0, 0, 0,
0, 42960, 0, 0, 0, 0, 0, 42966, 0, 42968, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 42997, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 19
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 42931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034, 5035, 5036, 5037, 5038, 5039,
5040, 5041, 5042, 5043, 5044, 5045, 5046, 5047, 5048, 5049, 5050, 5051, 5052, 5053, 5054, 5055,
5056, 5057, 5058, 5059, 5060, 5061, 5062, 5063, 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
5072, 5073, 5074, 5075, 5076, 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 5087,
5088, 5089, 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099, 5100, 5101, 5102, 5103,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 20
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326, 65327,
65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 65337, 65338, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 21
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 66560, 66561, 66562, 66563, 66564, 66565, 66566, 66567,
66568, 66569, 66570, 66571, 66572, 66573, 66574, 66575, 66576, 66577, 66578, 66579, 66580, 66581, 66582, 66583,
66584, 66585, 66586, 66587, 66588, 66589, 66590, 66591, 66592, 66593, 66594, 66595, 66596, 66597, 66598, 66599,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 66736, 66737, 66738, 66739, 66740, 66741, 66742, 66743,
66744, 66745, 66746, 66747, 66748, 66749, 66750, 66751, 66752, 66753, 66754, 66755, 66756, 66757, 66758, 66759,
66760, 66761, 66762, 66763, 66764, 66765, 66766, 66767, 66768, 66769, 66770, 66771, 0, 0, 0, 0,
// block 22
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 66928, 66929, 66930, 66931, 66932, 66933, 66934, 66935, 66936,
66937, 66938, 0, 66940, 66941, 66942, 66943, 66944, 66945, 66946, 66947, 66948, 66949, 66950, 66951, 66952,
66953, 66954, 0, 66956, 66957, 66958, 66959, 66960, 66961, 66962, 0, 66964, 66965, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 23
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68736, 68737, 68738, 68739, 68740, 68741, 68742, 68743, 68744, 68745, 68746, 68747, 68748, 68749, 68750, 68751,
68752, 68753, 68754, 68755, 68756, 68757, 68758, 68759, 68760, 68761, 68762, 68763, 68764, 68765, 68766, 68767,
68768, 68769, 68770, 68771, 68772, 68773, 68774, 68775, 68776, 68777, 68778, 68779, 68780, 68781, 68782, 68783,
68784, 68785, 68786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 24
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71840, 71841, 71842, 71843, 71844, 71845, 71846, 71847, 71848, 71849, 71850, 71851, 71852, 71853, 71854, 71855,
71856, 71857, 71858, 71859, 71860, 71861, 71862, 71863, 71864, 71865, 71866, 71867, 71868, 71869, 71870, 71871,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 25
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
93760, 93761, 93762, 93763, 93764, 93765, 93766, 93767, 93768, 93769, 93770, 93771, 93772, 93773, 93774, 93775,
93776, 93777, 93778, 93779, 93780, 93781, 93782, 93783, 93784, 93785, 93786, 93787, 93788, 93789, 93790, 93791,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 26
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 125184, 125185, 125186, 125187, 125188, 125189, 125190, 125191, 125192, 125193, 125194, 125195, 125196, 125197,
125198, 125199, 125200, 125201, 125202, 125203, 125204, 125205, 125206, 125207, 125208, 125209, 125210, 125211, 125212, 125213,
125214, 125215, 125216, 125217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
[[nodiscard]] constexpr std::uint32_t uppercase_lookup(std::uint32_t ch) noexcept
{
std::uint32_t block_offset = uppercase_stage1[ch / 256] * 256;
return uppercase_stage2[block_offset + ch % 256];
}
} // boost::spirit::x3::unicode::detail
@@ -1,45 +0,0 @@
/*=============================================================================
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_X3_CORE_CONFIG_HPP
#define BOOST_SPIRIT_X3_CORE_CONFIG_HPP
#include <boost/config.hpp>
#include <cstddef>
#if _MSC_VER
# include <CppCoreCheck/Warnings.h>
# pragma warning(default: CPPCORECHECK_LIFETIME_WARNINGS)
#endif
// <https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#c++20-[[no_unique_address]]>
#if _MSC_VER && _MSC_VER < 1929 // VS 2019 v16.9 or before
# error "Too old MSVC version; we don't support this because it leads to ODR violation regarding the existence of [[(msvc::)no_unique_address]]"
#endif
#if _MSC_VER && __INTELLISENSE__ // Memory Layout view shows wrong layout without this workaround
# define BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS [[msvc::no_unique_address, no_unique_address]]
#elif _MSC_VER // normal MSVC
# define BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#else // other compilers
# define BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS [[no_unique_address]]
#endif
#ifndef BOOST_SPIRIT_X3_LIFETIMEBOUND
# if defined(__clang__)
# define BOOST_SPIRIT_X3_LIFETIMEBOUND [[clang::lifetimebound]]
# elif defined(_MSC_VER)
# define BOOST_SPIRIT_X3_LIFETIMEBOUND [[msvc::lifetimebound]]
# else
# define BOOST_SPIRIT_X3_LIFETIMEBOUND
# endif
#endif
#endif
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -55,7 +54,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>
struct literal_bool_parser : parser<literal_bool_parser<T, Encoding, BoolPolicies>>
struct literal_bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>
{
typedef Encoding encoding;
typedef T attribute_type;
@@ -115,7 +114,7 @@ namespace boost { namespace spirit { namespace x3
constexpr false_type false_ = { false };
}
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
typedef bool_parser<bool, char_encoding::standard_wide> bool_type;
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,22 +11,19 @@
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <string_view>
#include <iterator>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Default boolean policies
///////////////////////////////////////////////////////////////////////////
template <typename T = bool>
struct bool_policies
{
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename CaseCompare>
[[nodiscard]] static constexpr bool
parse_true(It& first, Se const& last, Attribute& attr_, CaseCompare const& case_compare)
noexcept(std::is_nothrow_constructible_v<Attribute, T>)
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
parse_true(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
using namespace std::string_view_literals;
if (detail::string_parse("true"sv, first, last, unused, case_compare))
if (detail::string_parse("true", first, last, unused, case_compare))
{
traits::move_to(T(true), attr_); // result is true
return true;
@@ -35,13 +31,11 @@ namespace boost::spirit::x3
return false;
}
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename CaseCompare>
[[nodiscard]] static constexpr bool
parse_false(It& first, Se const& last, Attribute& attr_, CaseCompare const& case_compare)
noexcept(std::is_nothrow_constructible_v<Attribute, T>)
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
parse_false(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
using namespace std::string_view_literals;
if (detail::string_parse("false"sv, first, last, unused, case_compare))
if (detail::string_parse("false", first, last, unused, case_compare))
{
traits::move_to(T(false), attr_); // result is false
return true;
@@ -49,6 +43,6 @@ namespace boost::spirit::x3
return false;
}
};
} // boost::spirit::x3
}}}
#endif
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,11 +11,11 @@
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
#include <string_view>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
// Default (unsigned) real number policies
///////////////////////////////////////////////////////////////////////////
// Default (unsigned) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct ureal_policies
{
@@ -73,24 +72,24 @@ namespace boost::spirit::x3
return extract_int<int, 10, 1, -1>::call(first, last, attr_);
}
// The parse_nan() and parse_inf() functions get called whenever
// a number to parse does not start with a digit (after having
// successfully parsed an optional sign).
///////////////////////////////////////////////////////////////////////
// The parse_nan() and parse_inf() functions get called whenever
// a number to parse does not start with a digit (after having
// successfully parsed an optional sign).
//
// The functions should return true if a Nan or Inf has been found. In
// this case the attr should be set to the matched value (NaN or
// Inf). The optional sign will be automatically applied afterwards.
// The functions should return true if a Nan or Inf has been found. In
// this case the attr should be set to the matched value (NaN or
// Inf). The optional sign will be automatically applied afterwards.
//
// The default implementation below recognizes representations of NaN
// and Inf as mandated by the C99 Standard and as proposed for
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
// (the matching is performed case-insensitively).
// The default implementation below recognizes representations of NaN
// and Inf as mandated by the C99 Standard and as proposed for
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
// (the matching is performed case-insensitively).
///////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Attribute>
static bool
parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
{
using namespace std::string_view_literals;
if (first == last)
return false; // end of input reached
@@ -98,7 +97,7 @@ namespace boost::spirit::x3
return false; // not "nan"
// nan[(...)] ?
if (detail::string_parse("nan"sv, "NAN"sv, first, last, unused))
if (detail::string_parse("nan", "NAN", first, last, unused))
{
if (first != last && *first == '(')
{
@@ -122,8 +121,6 @@ namespace boost::spirit::x3
static bool
parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
{
using namespace std::string_view_literals;
if (first == last)
return false; // end of input reached
@@ -131,10 +128,10 @@ namespace boost::spirit::x3
return false; // not "inf"
// inf or infinity ?
if (detail::string_parse("inf"sv, "INF"sv, first, last, unused))
if (detail::string_parse("inf", "INF", first, last, unused))
{
// skip allowed 'inity' part of infinity
(void)detail::string_parse("inity"sv, "INITY"sv, first, last, unused);
detail::string_parse("inity", "INITY", first, last, unused);
attr_ = std::numeric_limits<T>::infinity();
return true;
}
@@ -142,7 +139,9 @@ namespace boost::spirit::x3
}
};
// Default (signed) real number policies
///////////////////////////////////////////////////////////////////////////
// Default (signed) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct real_policies : ureal_policies<T>
{
@@ -165,6 +164,6 @@ namespace boost::spirit::x3
{
static bool const expect_dot = true;
};
} // boost::spirit::x3
}}}
#endif
-2
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,7 +8,6 @@
#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM
#include <boost/spirit/home/x3/string/literal_string.hpp>
#include <boost/spirit/home/x3/string/string.hpp>
#include <boost/spirit/home/x3/string/symbols.hpp>
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,22 +9,36 @@
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <string_view>
#include <iterator>
namespace boost::spirit::x3::detail
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename CharT, typename CharTraitsT, std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename CaseCompareFunc>
[[nodiscard]] constexpr bool
string_parse(
std::basic_string_view<CharT, CharTraitsT> const str,
It& first, Se const& last,
Attribute& attr, CaseCompareFunc const& compare
) noexcept(std::is_same_v<std::remove_const_t<Attribute>, unused_type>)
template <typename Char, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
Char const* str
, Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
It i = first;
auto stri = str.begin();
auto str_last = str.end();
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
if (i == last || (compare(ch, *i) != 0))
return false;
ch = *++str;
}
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
if (i == last || (compare(*stri, *i) != 0))
@@ -35,29 +48,30 @@ namespace boost::spirit::x3::detail
return true;
}
template <typename CharT, typename CharTraitsT, std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename CaseCompareFunc>
[[nodiscard]] constexpr bool
string_parse(
std::basic_string<CharT, CharTraitsT> const& str,
It& first, Se const& last,
Attribute& attr, CaseCompareFunc const& compare
) noexcept(std::is_same_v<std::remove_const_t<Attribute>, unused_type>)
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* uc_i, Char const* lc_i
, Iterator& first, Iterator const& last, Attribute& attr)
{
return detail::string_parse(std::basic_string_view{str}, first, last, attr, compare);
Iterator i = first;
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename CharT, typename CharTraitsT, std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute>
[[nodiscard]] constexpr bool
string_parse(
std::basic_string_view<CharT, CharTraitsT> const ucstr,
std::basic_string_view<CharT, CharTraitsT> const lcstr,
It& first, Se const& last, Attribute& attr
) noexcept(std::is_same_v<std::remove_const_t<Attribute>, unused_type>)
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& ucstr, String const& lcstr
, Iterator& first, Iterator const& last, Attribute& attr)
{
auto uc_i = ucstr.begin();
auto uc_last = ucstr.end();
auto lc_i = lcstr.begin();
It i = first;
typename String::const_iterator uc_i = ucstr.begin();
typename String::const_iterator uc_last = ucstr.end();
typename String::const_iterator lc_i = lcstr.begin();
Iterator i = first;
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
@@ -66,17 +80,6 @@ namespace boost::spirit::x3::detail
first = i;
return true;
}
template <typename CharT, typename CharTraitsT, std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute>
[[nodiscard]] constexpr bool
string_parse(
std::basic_string<CharT, CharTraitsT> const& ucstr,
std::basic_string<CharT, CharTraitsT> const& lcstr,
It& first, Se const& last, Attribute& attr
) noexcept(std::is_same_v<std::remove_const_t<Attribute>, unused_type>)
{
return detail::string_parse(std::basic_string_view{ucstr}, std::basic_string_view{lcstr}, first, last, attr);
}
} // boost::spirit::x3::detail
}}}}
#endif
@@ -0,0 +1,202 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
#include <boost/call_traits.hpp>
#include <boost/assert.hpp>
#include <string>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// This file contains low level TST routines, not for
// public consumption.
template <typename Char, typename T>
struct tst_node
{
tst_node(Char id)
: id(id), data(0), lt(0), eq(0), gt(0)
{
}
template <typename Alloc>
static void
destruct_node(tst_node* p, Alloc* alloc)
{
if (p)
{
if (p->data)
alloc->delete_data(p->data);
destruct_node(p->lt, alloc);
destruct_node(p->eq, alloc);
destruct_node(p->gt, alloc);
alloc->delete_node(p);
}
}
template <typename Alloc>
static tst_node*
clone_node(tst_node* p, Alloc* alloc)
{
if (p)
{
tst_node* clone = alloc->new_node(p->id);
if (p->data)
clone->data = alloc->new_data(*p->data);
clone->lt = clone_node(p->lt, alloc);
clone->eq = clone_node(p->eq, alloc);
clone->gt = clone_node(p->gt, alloc);
return clone;
}
return 0;
}
template <typename Iterator, typename CaseCompare>
static T*
find(tst_node* start, Iterator& first, Iterator last, CaseCompare comp)
{
if (first == last)
return 0;
Iterator i = first;
Iterator latest = first;
tst_node* p = start;
T* found = 0;
while (p && i != last)
{
int32_t c = comp(*i,p->id);
if (c == 0)
{
if (p->data)
{
found = p->data;
latest = i;
}
p = p->eq;
i++;
}
else if (c < 0)
{
p = p->lt;
}
else
{
p = p->gt;
}
}
if (found)
first = ++latest; // one past the last matching char
return found;
}
template <typename Iterator, typename Alloc>
static T*
add(
tst_node*& start
, Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val
, Alloc* alloc)
{
if (first == last)
return 0;
tst_node** pp = &start;
for (;;)
{
auto c = *first;
if (*pp == 0)
*pp = alloc->new_node(c);
tst_node* p = *pp;
if (c == p->id)
{
if (++first == last)
{
if (p->data == 0)
p->data = alloc->new_data(val);
return p->data;
}
pp = &p->eq;
}
else if (c < p->id)
{
pp = &p->lt;
}
else
{
pp = &p->gt;
}
}
}
template <typename Iterator, typename Alloc>
static void
remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
{
if (p == 0 || first == last)
return;
auto c = *first;
if (c == p->id)
{
if (++first == last)
{
if (p->data)
{
alloc->delete_data(p->data);
p->data = 0;
}
}
remove(p->eq, first, last, alloc);
}
else if (c < p->id)
{
remove(p->lt, first, last, alloc);
}
else
{
remove(p->gt, first, last, alloc);
}
if (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)
{
alloc->delete_node(p);
p = 0;
}
}
template <typename F>
static void
for_each(tst_node* p, std::basic_string<Char> prefix, F f)
{
if (p)
{
for_each(p->lt, prefix, f);
std::basic_string<Char> s = prefix + p->id;
for_each(p->eq, s, f);
if (p->data)
f(s, *p->data);
for_each(p->gt, prefix, f);
}
}
Char id; // the node's identity character
T* data; // optional data
tst_node* lt; // left pointer
tst_node* eq; // middle pointer
tst_node* gt; // right pointer
};
}}}}
#endif
@@ -1,175 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
#include <boost/spirit/home/x3/core/config.hpp>
#include <boost/spirit/home/x3/support/allocator.hpp>
#include <boost/assert.hpp>
#include <iterator>
#include <memory>
#include <string_view>
#include <string>
#include <utility>
namespace boost::spirit::x3::detail
{
// This file contains low level TST routines, not for
// public consumption.
template <typename Char, typename T, typename Alloc = std::allocator<T>>
struct tst_node
{
using allocator_type = Alloc;
using node_allocator_type = std::allocator_traits<Alloc>::template rebind_alloc<tst_node>;
constexpr explicit tst_node(Char id, Alloc const& alloc = {}) noexcept
: alloc(alloc)
, node_alloc(this->alloc)
, id(id)
{
}
constexpr tst_node(tst_node const& rhs)
: alloc(std::allocator_traits<Alloc>::select_on_container_copy_construction(rhs.alloc))
, node_alloc(std::allocator_traits<node_allocator_type>::select_on_container_copy_construction(rhs.node_alloc))
, id(rhs.id)
, data(allocator_ops<tst_node>::template copy_construct<&tst_node::alloc, &tst_node::data>(*this, rhs))
, lt(allocator_ops<tst_node>::template copy_construct<&tst_node::node_alloc, &tst_node::lt>(*this, rhs))
, eq(allocator_ops<tst_node>::template copy_construct<&tst_node::node_alloc, &tst_node::eq>(*this, rhs))
, gt(allocator_ops<tst_node>::template copy_construct<&tst_node::node_alloc, &tst_node::gt>(*this, rhs))
{
}
constexpr tst_node(tst_node&& rhs) noexcept
: alloc(std::move(rhs.alloc))
, node_alloc(std::move(rhs.node_alloc))
, id(std::move(rhs.id))
, data(std::exchange(rhs.data, nullptr))
, lt(std::exchange(rhs.lt, nullptr))
, eq(std::exchange(rhs.eq, nullptr))
, gt(std::exchange(rhs.gt, nullptr))
{
}
constexpr ~tst_node() noexcept
{
allocator_ops<tst_node>::template destroy_deallocate<
&tst_node::alloc, &tst_node::data
>(*this);
allocator_ops<tst_node>::template destroy_deallocate<
&tst_node::node_alloc,
&tst_node::lt, &tst_node::eq, &tst_node::gt
>(*this);
}
constexpr tst_node& operator=(tst_node const& rhs)
{
if (std::addressof(rhs) == this) return *this;
id = rhs.id;
allocator_ops<tst_node>::template copy_assign<
&tst_node::alloc, &tst_node::data
>(*this, rhs);
allocator_ops<tst_node>::template copy_assign<
&tst_node::node_alloc,
&tst_node::lt, &tst_node::eq, &tst_node::gt
>(*this, rhs);
}
constexpr tst_node& operator=(tst_node&& rhs)
noexcept(allocator_ops<tst_node>::template move_assign_noexcept<allocator_type, node_allocator_type>)
{
if (std::addressof(rhs) == this) return *this;
id = std::move(rhs.id);
allocator_ops<tst_node>::template move_assign<
&tst_node::alloc, &tst_node::data
>(*this, std::move(rhs));
allocator_ops<tst_node>::template move_assign<
&tst_node::node_alloc,
&tst_node::lt, &tst_node::eq, &tst_node::gt
>(*this, std::move(rhs));
}
template <std::forward_iterator Iterator, typename CaseCompare>
[[nodiscard]] static constexpr T*
find(tst_node* start, Iterator& first, Iterator last, CaseCompare const& comp) noexcept
{
if (first == last) return nullptr;
Iterator i = first;
Iterator latest = first;
tst_node* p = start;
T* found = nullptr;
while (p && i != last)
{
auto c = comp(*i,p->id);
if (c == 0) {
if (p->data)
{
found = p->data;
latest = i;
}
p = p->eq;
++i;
}
else if (c < 0)
{
p = p->lt;
}
else
{
p = p->gt;
}
}
if (found)
{
first = ++latest; // one past the last matching char
}
return found;
}
template <typename F>
static void
for_each(tst_node* const p, std::basic_string_view<Char> const prefix, F&& f)
{
if (!p) return;
tst_node::for_each(p->lt, prefix, f);
std::basic_string<Char> s = std::basic_string<Char>(prefix) + p->id;
tst_node::for_each(p->eq, s, f);
if (p->data)
{
f(s, *p->data);
}
tst_node::for_each(p->gt, prefix, f);
}
friend struct allocator_ops<tst_node>;
BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS Alloc alloc;
BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS node_allocator_type node_alloc;
Char id; // the node's identity character
T* data = nullptr; // optional data
tst_node* lt = nullptr; // left pointer
tst_node* eq = nullptr; // middle pointer
tst_node* gt = nullptr; // right pointer
};
}
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,66 +7,276 @@
#if !defined(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
template <typename String, typename Encoding, typename Attribute = std::basic_string<typename Encoding::char_type>>
template <typename String, typename Encoding,
typename Attribute = std::basic_string<typename Encoding::char_type>>
struct literal_string : parser<literal_string<String, Encoding, Attribute>>
{
static_assert(
!std::is_pointer_v<std::decay_t<String>>,
"`literal_string` for raw character pointer/array is banned; it has an undetectable risk of holding a dangling pointer."
);
static_assert(std::is_convertible_v<String, std::basic_string_view<typename String::value_type>>);
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = has_attribute;
using char_type = typename Encoding::char_type;
using encoding = Encoding;
using attribute_type = Attribute;
static constexpr bool has_attribute = !std::is_same_v<unused_type, attribute_type>;
static constexpr bool handles_container = has_attribute;
template<class... Args>
requires std::is_constructible_v<String, Args...>
constexpr literal_string(Args&&... args)
noexcept(std::is_nothrow_constructible_v<String, Args...>)
: str(std::forward<Args>(args)...)
constexpr literal_string(typename add_reference< typename add_const<String>::type >::type str)
: str(str)
{}
template <typename Iterator, typename Context, typename Attribute_>
[[nodiscard]] constexpr bool parse(
Iterator& first, Iterator const& last,
Context const& context, unused_type, Attribute_& attr
) const
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
x3::skip_over(first, last, context);
return detail::string_parse(str, first, last, attr, x3::get_case_compare<encoding>(context));
return detail::string_parse(str, first, last, attr, get_case_compare<encoding>(context));
}
String str;
};
namespace standard
{
constexpr literal_string<char const*, char_encoding::standard>
string(char const* s)
{
return { s };
}
inline literal_string<std::basic_string<char>, char_encoding::standard>
string(std::basic_string<char> const& s)
{
return { s };
}
inline constexpr literal_string<char const*, char_encoding::standard, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::standard, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
constexpr literal_string<wchar_t const*, char_encoding::standard_wide>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
constexpr literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
lit(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide, unused_type>
lit(std::basic_string<wchar_t> const& s)
{
return { s };
}
}
#endif
#if defined(BOOST_SPIRIT_X3_UNICODE)
namespace unicode
{
constexpr literal_string<char32_t const*, char_encoding::unicode>
string(char32_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<char32_t>, char_encoding::unicode>
string(std::basic_string<char32_t> const& s)
{
return { s };
}
constexpr literal_string<char32_t const*, char_encoding::unicode, unused_type>
lit(char32_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<char32_t>, char_encoding::unicode, unused_type>
lit(std::basic_string<char32_t> const& s)
{
return { s };
}
}
#endif
namespace ascii
{
constexpr literal_string<wchar_t const*, char_encoding::ascii>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::ascii>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
constexpr literal_string<char const*, char_encoding::ascii, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::ascii, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
namespace iso8859_1
{
constexpr literal_string<wchar_t const*, char_encoding::iso8859_1>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::iso8859_1>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
constexpr literal_string<char const*, char_encoding::iso8859_1, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::iso8859_1, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
using standard::string;
using standard::lit;
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
using standard_wide::string;
using standard_wide::lit;
#endif
namespace extension
{
template <int N>
struct as_parser<char[N]>
{
typedef literal_string<
char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static constexpr type call(char const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<char const[N]> : as_parser<char[N]> {};
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
template <int N>
struct as_parser<wchar_t[N]>
{
typedef literal_string<
wchar_t const*, char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static constexpr type call(wchar_t const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
#endif
template <>
struct as_parser<char const*>
{
typedef literal_string<
char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static constexpr type call(char const* s)
{
return type(s);
}
};
template <typename Char>
struct as_parser< std::basic_string<Char> >
{
typedef literal_string<
Char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(std::basic_string<Char> const& s)
{
return type(s.c_str());
}
};
}
template <typename String, typename Encoding, typename Attribute>
struct get_info<literal_string<String, Encoding, Attribute>>
{
using result_type = std::string;
[[nodiscard]] constexpr std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
typedef std::string result_type;
std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
{
return '"' + x3::to_utf8(p.str) + '"';
return '"' + to_utf8(p.str) + '"';
}
};
} // boost::spirit::x3
}}}
#endif
@@ -1,298 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_STRING_STRING_HPP
#define BOOST_SPIRIT_X3_STRING_STRING_HPP
#include <boost/spirit/home/x3/string/literal_string.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp> // required for "c" -> 'c' optimization
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/spirit/home/x3/char_encoding/standard.hpp>
#include <boost/spirit/home/x3/char_encoding/standard_wide.hpp>
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/x3/char_encoding/unicode.hpp>
#endif
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
namespace boost::spirit::x3
{
namespace standard
{
inline namespace helpers
{
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::standard>
string(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::standard>, T>)
{
return {std::forward<T>(string_like)};
}
// Optimize `literal_string{'c'}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::standard, std::basic_string<char>>
string(char ch) noexcept
{
return { ch };
}
// Optimize `literal_string{"c"}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::standard, std::basic_string<char>>
string(traits::X3VagueArrayOf2Chars<char> auto const& ch) noexcept
{
return { ch[0] };
}
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::standard, unused_type>
lit(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::standard, unused_type>, T>)
{
return {std::forward<T>(string_like)};
}
} // helpers
template <typename T>
requires traits::CharIncompatibleWith<T, char> || traits::StringLikeIncompatibleWith<T, char>
constexpr void string(T&&) = delete; // Mixing incompatible character types is not allowed
} // standard
using standard::helpers::string;
using standard::helpers::lit;
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
namespace standard_wide
{
inline namespace helpers
{
template <traits::CppStringLike<wchar_t> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::standard_wide>
string(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::standard_wide>, T>)
{
return {std::forward<T>(string_like)};
}
// Optimize `literal_string{'c'}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::standard_wide, std::basic_string<wchar_t>>
string(wchar_t ch) noexcept
{
return { ch };
}
// Optimize `literal_string{L"c"}` into `literal_char{L'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::standard_wide, std::basic_string<wchar_t>>
string(traits::X3VagueArrayOf2Chars<wchar_t> auto const& ch) noexcept
{
return { ch[0] };
}
template <traits::CppStringLike<wchar_t> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::standard_wide, unused_type>
lit(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::standard_wide, unused_type>, T>)
{
return {std::forward<T>(string_like)};
}
} // helpers
template <typename T>
requires traits::CharIncompatibleWith<T, wchar_t> || traits::StringLikeIncompatibleWith<T, wchar_t>
constexpr void string(T&&) = delete; // Mixing incompatible character types is not allowed
} // standard_wide
using standard_wide::helpers::string;
using standard_wide::helpers::lit;
#endif
#ifdef BOOST_SPIRIT_X3_UNICODE
namespace unicode
{
inline namespace helpers
{
// TODO: add `char8_t` and `char16_t` overloads
template <traits::CppStringLike<char32_t> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::unicode>
string(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::unicode>, T>)
{
return {std::forward<T>(string_like)};
}
// Optimize `literal_string{'c'}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::unicode, std::basic_string<char32_t>>
string(char32_t ch) noexcept
{
return { ch };
}
// Optimize `literal_string{U"c"}` into `literal_char{U'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::unicode, std::basic_string<char32_t>>
string(traits::X3VagueArrayOf2Chars<char32_t> auto const& ch) noexcept
{
return { ch[0] };
}
template <traits::CppStringLike<char32_t> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::unicode, unused_type>
lit(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::unicode, unused_type>, T>)
{
return {std::forward<T>(string_like)};
}
} // helpers
template <typename T>
requires traits::CharIncompatibleWith<T, char32_t> || traits::StringLikeIncompatibleWith<T, char32_t>
constexpr void string(T&&) = delete; // Mixing incompatible character types is not allowed
}
using unicode::helpers::string;
using unicode::helpers::lit;
#endif
namespace [[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]] ascii
{
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::ascii>
string(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::ascii>, T>)
{
return {std::forward<T>(string_like)};
}
// Optimize `literal_string{'c'}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::ascii, std::basic_string<char>>
string(char ch) noexcept
{
return { ch };
}
// Optimize `literal_string{"c"}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::ascii, std::basic_string<char>>
string(traits::X3VagueArrayOf2Chars<char> auto const& ch) noexcept
{
return { ch[0] };
}
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::ascii, unused_type>
lit(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::ascii, unused_type>, T>)
{
return {std::forward<T>(string_like)};
}
template <typename T>
requires traits::CharIncompatibleWith<T, char> || traits::StringLikeIncompatibleWith<T, char>
constexpr void string(T&&) = delete; // Mixing incompatible character types is not allowed
} // ascii
namespace [[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]] iso8859_1
{
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::iso8859_1>
string(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::iso8859_1>, T>)
{
return {std::forward<T>(string_like)};
}
// Optimize `literal_string{'c'}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::iso8859_1, std::basic_string<char>>
string(char ch) noexcept
{
return { ch };
}
// Optimize `literal_string{"c"}` into `literal_char{'c'}`
[[nodiscard]] constexpr literal_char<char_encoding::iso8859_1, std::basic_string<char>>
string(traits::X3VagueArrayOf2Chars<char> auto const& ch) noexcept
{
return { ch[0] };
}
template <traits::CppStringLike<char> T>
[[nodiscard]] constexpr literal_string<traits::maybe_owning_string<T>, char_encoding::iso8859_1, unused_type>
lit(T&& string_like)
noexcept(std::is_nothrow_constructible_v<literal_string<traits::maybe_owning_string<T>, char_encoding::iso8859_1, unused_type>, T>)
{
return {std::forward<T>(string_like)};
}
template <typename T>
requires traits::CharIncompatibleWith<T, char> || traits::StringLikeIncompatibleWith<T, char>
constexpr void string(T&&) = delete; // Mixing incompatible character types is not allowed
} // iso8859_1
namespace extension
{
template <traits::CharLike CharT, std::size_t N>
struct as_parser<CharT[N]>
{
using type = literal_string<std::basic_string_view<CharT>, traits::char_encoding_for<CharT>, unused_type>;
using value_type = type;
[[nodiscard]] static constexpr type call(CharT const* s)
{
return type(s);
}
};
template <traits::CharLike CharT, std::size_t N>
struct as_parser<CharT const[N]> : as_parser<CharT[N]> {};
template <traits::CharLike CharT>
struct as_parser<CharT const*>
{
using type = literal_string<std::basic_string_view<CharT>, traits::char_encoding_for<CharT>, unused_type>;
using value_type = type;
[[nodiscard]] static constexpr type call(CharT const* s)
{
return type(std::basic_string_view<CharT>{s});
}
};
template <traits::CharLike CharT>
struct as_parser<std::basic_string<CharT>>
{
using type = literal_string<std::basic_string<CharT>, traits::char_encoding_for<CharT>, unused_type>;
using value_type = type;
template <typename T>
[[nodiscard]] static constexpr type call(T&& str)
noexcept(std::is_nothrow_constructible_v<type, T>)
{
return type(std::forward<T>(str));
}
};
template <traits::CharLike CharT>
struct as_parser<std::basic_string_view<CharT>>
{
using type = literal_string<std::basic_string_view<CharT>, traits::char_encoding_for<CharT>, unused_type>;
using value_type = type;
template <typename T>
[[nodiscard]] static constexpr type call(T&& str)
noexcept(std::is_nothrow_constructible_v<type, T>)
{
return type(std::forward<T>(str));
}
};
} // extension
} // boost::spirit::x3
#endif
+159 -306
View File
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Carl Barron
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,161 +16,99 @@
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/x3/char_encoding/detail/encoding_warning.hpp>
#include <boost/spirit/home/x3/char_encoding/ascii.hpp>
#include <boost/spirit/home/x3/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/x3/char_encoding/standard.hpp>
#include <boost/spirit/home/x3/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/x3/char_encoding/unicode.hpp>
#endif
#include <string>
#include <string_view>
#include <ranges>
#include <iterator>
#include <initializer_list>
#include <iterator> // std::begin
#include <memory> // std::shared_ptr
#include <type_traits>
#include <utility>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
#define BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING(old_api) \
"Use `shared_" old_api "` instead. `" old_api "` has had a " \
"*implicit* trait where the underlying storage is shared via " \
"`std::shared_ptr`. This disallows `constexpr` usage in generic " \
"scenarios where the sharing is not actually needed at all. Even " \
"for non-`constexpr` usage, the old name `" old_api "` does not " \
"represent this trait, so the usage of the old API is strongly " \
"discouraged."
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
namespace detail
{
template <typename Derived, bool IsShared, typename Encoding, typename T, typename Lookup>
struct symbols_parser_impl : parser<Derived>
template <
typename Encoding
, typename T = unused_type
, typename Lookup = tst<typename Encoding::char_type, T> >
struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
{
using char_type = typename Encoding::char_type; // the character type
using encoding = Encoding;
using value_type = T; // the value associated with each entry
using attribute_type = value_type;
typedef typename Encoding::char_type char_type; // the character type
typedef Encoding encoding;
typedef T value_type; // the value associated with each entry
typedef value_type attribute_type;
static constexpr bool has_attribute = !std::is_same_v<unused_type, attribute_type>;
static constexpr bool handles_container = traits::is_container_v<attribute_type>;
static bool const has_attribute =
!std::is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<attribute_type>::value;
constexpr symbols_parser_impl(std::string_view name = "symbols")
requires(IsShared)
: add{*this}
, remove{*this}
, lookup(std::make_shared<Lookup>())
, name_(name)
symbols_parser(std::string const& name = "symbols")
: add{*this}
, remove{*this}
, lookup(std::make_shared<Lookup>())
, name_(name)
{
}
constexpr symbols_parser_impl(std::string_view name = "symbols")
requires(!IsShared)
: add{*this}
, remove{*this}
, lookup(std::make_unique<Lookup>())
, name_(name)
symbols_parser(symbols_parser const& syms)
: add{*this}
, remove{*this}
, lookup(syms.lookup)
, name_(syms.name_)
{
}
constexpr symbols_parser_impl(symbols_parser_impl const& syms)
requires(IsShared)
: add{*this}
, remove{*this}
, lookup(syms.lookup)
, name_(syms.name_)
template <typename Symbols>
symbols_parser(Symbols const& syms, std::string const& name = "symbols")
: symbols_parser(name)
{
for (auto& sym : syms)
add(sym);
}
constexpr symbols_parser_impl(symbols_parser_impl const& syms)
requires(!IsShared)
: add{*this}
, remove{*this}
, lookup(std::make_unique<Lookup>(*syms.lookup))
, name_(syms.name_)
template <typename Symbols, typename Data>
symbols_parser(Symbols const& syms, Data const& data
, std::string const& name = "symbols")
: symbols_parser(name)
{
using std::begin;
auto di = begin(data);
for (auto& sym : syms)
add(sym, *di++);
}
constexpr symbols_parser_impl(symbols_parser_impl&&) noexcept = default;
template <std::ranges::forward_range Symbols>
requires std::convertible_to<std::ranges::range_value_t<Symbols>, std::basic_string_view<char_type>>
constexpr symbols_parser_impl(Symbols const& syms, std::string const& name = "symbols")
: symbols_parser_impl(name)
symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
, std::string const & name="symbols")
: symbols_parser(name)
{
for (auto const& sym : syms)
{
this->add(sym);
}
}
template <std::ranges::forward_range Symbols, std::ranges::forward_range Data>
requires
std::convertible_to<std::ranges::range_value_t<Symbols>, std::basic_string_view<char_type>> &&
std::convertible_to<std::ranges::range_value_t<Data>, T>
constexpr symbols_parser_impl(
Symbols const& syms, Data const& data, std::string const& name = "symbols"
)
: symbols_parser_impl(name)
{
auto di = std::ranges::begin(data);
for (auto const& sym : syms)
{
this->add(sym, *di++);
}
}
constexpr symbols_parser_impl(
std::initializer_list<std::pair<char_type const*, T>> syms,
std::string const & name="symbols"
)
: symbols_parser_impl(name)
{
for (auto const& sym : syms)
{
for (auto& sym : syms)
add(sym.first, sym.second);
}
}
constexpr symbols_parser_impl(
std::initializer_list<char_type const*> syms,
std::string const &name="symbols"
)
: symbols_parser_impl(name)
symbols_parser(std::initializer_list<char_type const*> syms
, std::string const &name="symbols")
: symbols_parser(name)
{
for (auto const& str : syms)
{
for (auto str : syms)
add(str);
}
}
constexpr symbols_parser_impl& operator=(symbols_parser_impl const& rhs)
symbols_parser&
operator=(symbols_parser const& rhs)
{
name_ = rhs.name_;
if constexpr (IsShared)
{
lookup = rhs.lookup;
}
else
{
*lookup = *rhs.lookup;
}
lookup = rhs.lookup;
return *this;
}
constexpr symbols_parser_impl& operator=(symbols_parser_impl&&) = default;
constexpr void clear() noexcept
void clear()
{
lookup->clear();
}
@@ -179,87 +116,93 @@ namespace detail
struct adder;
struct remover;
constexpr symbols_parser_impl& operator=(std::initializer_list<char_type const*> const& syms)
template <typename Str>
adder const&
operator=(Str const& str)
{
lookup->clear();
for (auto const& sym : syms)
{
this->add(sym);
}
return *this;
return add(str);
}
constexpr adder const&
operator=(std::basic_string_view<char_type> const s)
template <typename Str>
friend adder const&
operator+=(symbols_parser& sym, Str const& str)
{
lookup->clear();
return this->add(s);
return sym.add(str);
}
friend constexpr adder const&
operator+=(symbols_parser_impl& sym, std::basic_string_view<char_type> const s)
template <typename Str>
friend remover const&
operator-=(symbols_parser& sym, Str const& str)
{
return sym.add(s);
}
friend constexpr remover const&
operator-=(symbols_parser_impl& sym, std::basic_string_view<char_type> const s)
{
return sym.remove(s);
return sym.remove(str);
}
template <typename F>
constexpr void for_each(F&& f) const
void for_each(F f) const
{
lookup->for_each(std::forward<F>(f));
lookup->for_each(f);
}
template <typename F>
constexpr void for_each(F&& f)
template <typename Str>
value_type& at(Str const& str)
{
lookup->for_each(std::forward<F>(f));
return *lookup->add(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str), T());
}
[[nodiscard]] constexpr value_type& at(std::basic_string_view<char_type> const s)
{
return *lookup->add(s.begin(), s.end(), T{});
}
template <std::forward_iterator Iterator>
[[nodiscard]] constexpr value_type* prefix_find(Iterator& first, Iterator const& last) noexcept
template <typename Iterator>
value_type* prefix_find(Iterator& first, Iterator const& last)
{
return lookup->find(first, last, case_compare<Encoding>());
}
template <std::forward_iterator Iterator>
[[nodiscard]] constexpr value_type const* prefix_find(Iterator& first, Iterator const& last) const noexcept
template <typename Iterator>
value_type const* prefix_find(Iterator& first, Iterator const& last) const
{
return lookup->find(first, last, case_compare<Encoding>());
}
[[nodiscard]] constexpr value_type* find(std::basic_string_view<char_type> const s) noexcept
template <typename Str>
value_type* find(Str const& str)
{
return this->find_impl(s.begin(), s.end());
return find_impl(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str));
}
[[nodiscard]] constexpr value_type const* find(std::basic_string_view<char_type> const s) const noexcept
template <typename Str>
value_type const* find(Str const& str) const
{
return this->find_impl(s.begin(), s.end());
return find_impl(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str));
}
template <std::forward_iterator Iterator, typename Context, typename Attribute>
[[nodiscard]] constexpr bool parse(
Iterator& first, Iterator const& last, Context const& context, unused_type, Attribute& attr
) const noexcept(
noexcept(x3::skip_over(first, last, context)) &&
noexcept(x3::traits::move_to(std::declval<value_type const&>(), attr))
)
private:
template <typename Iterator>
value_type* find_impl(Iterator begin, Iterator end)
{
value_type* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
template <typename Iterator>
value_type const* find_impl(Iterator begin, Iterator end) const
{
value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
public:
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (value_type const* val_ptr = lookup->find(first, last, x3::get_case_compare<Encoding>(context)))
if (value_type const* val_ptr
= lookup->find(first, last, get_case_compare<Encoding>(context)))
{
x3::traits::move_to(*val_ptr, attr);
return true;
@@ -267,214 +210,124 @@ namespace detail
return false;
}
constexpr void name(std::string const &str)
void name(std::string const &str)
{
name_ = str;
}
[[nodiscard]] constexpr std::string const& name() const noexcept
std::string const &name() const
{
return name_;
}
struct [[maybe_unused]] adder
struct adder
{
template <std::forward_iterator Iterator>
[[maybe_unused]] constexpr adder const&
template <typename Iterator>
adder const&
operator()(Iterator first, Iterator last, T const& val) const
{
sym.lookup->add(first, last, val);
return *this;
}
[[maybe_unused]] constexpr adder const&
operator()(std::basic_string_view<char_type> const s, T const& val = T{}) const
template <typename Str>
adder const&
operator()(Str const& s, T const& val = T()) const
{
sym.lookup->add(s.begin(), s.end(), val);
sym.lookup->add(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s), val);
return *this;
}
[[maybe_unused, deprecated("Don't rely on overloaded comma operator. It's the leftover from the black magic in the 2000s.")]]
constexpr adder const&
operator,(std::basic_string_view<char_type> const s) const
template <typename Str>
adder const&
operator,(Str const& s) const
{
sym.lookup->add(s.begin(), s.end(), T{});
sym.lookup->add(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s), T());
return *this;
}
symbols_parser_impl& sym;
symbols_parser& sym;
};
struct [[maybe_unused]] remover
struct remover
{
template <std::forward_iterator Iterator>
[[maybe_unused]] constexpr remover const&
template <typename Iterator>
remover const&
operator()(Iterator const& first, Iterator const& last) const
{
sym.lookup->remove(first, last);
return *this;
}
[[maybe_unused]] constexpr remover const&
operator()(std::basic_string_view<char_type> const s) const
template <typename Str>
remover const&
operator()(Str const& s) const
{
sym.lookup->remove(s.begin(), s.end());
sym.lookup->remove(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s));
return *this;
}
[[maybe_unused, deprecated("Don't rely on overloaded comma operator. It's the leftover from the black magic in the 2000s.")]]
constexpr remover const&
operator,(std::basic_string_view<char_type> const s) const
template <typename Str>
remover const&
operator,(Str const& s) const
{
sym.lookup->remove(s.begin(), s.end());
sym.lookup->remove(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s));
return *this;
}
symbols_parser_impl& sym;
symbols_parser& sym;
};
[[maybe_unused]] adder add;
[[maybe_unused]] remover remove;
private:
template <std::forward_iterator Iterator>
[[nodiscard]] constexpr value_type* find_impl(Iterator begin, Iterator end) noexcept
{
value_type* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
template <std::forward_iterator Iterator>
[[nodiscard]] constexpr value_type const* find_impl(Iterator begin, Iterator end) const noexcept
{
value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
std::conditional_t<IsShared, std::shared_ptr<Lookup>, std::unique_ptr<Lookup>> lookup;
adder add;
remover remove;
std::shared_ptr<Lookup> lookup;
std::string name_;
};
} // detail
template <typename Encoding, typename T = unused_type, typename Lookup = tst<typename Encoding::char_type, T>>
struct shared_symbols_parser
: detail::symbols_parser_impl<shared_symbols_parser<Encoding, T, Lookup>, true, Encoding, T, Lookup>
{
using base_type = detail::symbols_parser_impl<shared_symbols_parser<Encoding, T, Lookup>, true, Encoding, T, Lookup>;
using base_type::base_type;
using base_type::operator=;
};
template <typename Encoding, typename T = unused_type, typename Lookup = tst<typename Encoding::char_type, T>>
struct [[deprecated(BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING("symbols_parser"))]]
symbols_parser : shared_symbols_parser<Encoding, T, Lookup>
{
using base_type = shared_symbols_parser<Encoding, T, Lookup>;
using base_type::base_type;
using base_type::operator=;
};
template <typename Encoding, typename T = unused_type, typename Lookup = tst<typename Encoding::char_type, T>>
struct unique_symbols_parser
: detail::symbols_parser_impl<unique_symbols_parser<Encoding, T, Lookup>, false, Encoding, T, Lookup>
{
using base_type = detail::symbols_parser_impl<unique_symbols_parser<Encoding, T, Lookup>, false, Encoding, T, Lookup>;
using base_type::base_type;
using base_type::operator=;
};
template <typename Encoding, typename T, typename Lookup>
struct get_info<shared_symbols_parser<Encoding, T, Lookup>>
struct get_info<symbols_parser<Encoding, T, Lookup>>
{
using result_type = std::string const&;
[[nodiscard]] constexpr result_type operator()(shared_symbols_parser<Encoding, T, Lookup> const& symbols) const noexcept
{
return symbols.name();
}
};
template <typename Encoding, typename T, typename Lookup>
struct get_info<unique_symbols_parser<Encoding, T, Lookup>>
{
using result_type = std::string const&;
[[nodiscard]] constexpr result_type operator()(unique_symbols_parser<Encoding, T, Lookup> const& symbols) const noexcept
{
return symbols.name();
}
typedef std::string result_type;
result_type operator()(symbols_parser< Encoding, T
, Lookup
> const& symbols) const
{
return symbols.name();
}
};
namespace standard
{
template <typename T = unused_type>
using symbols [[deprecated(BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING("symbols"))]]
= x3::shared_symbols_parser<char_encoding::standard, T>;
template <typename T = unused_type>
using shared_symbols = x3::shared_symbols_parser<char_encoding::standard, T>;
template <typename T = unused_type>
using unique_symbols = x3::unique_symbols_parser<char_encoding::standard, T>;
} // standard
using symbols = symbols_parser<char_encoding::standard, T>;
}
using standard::symbols;
using standard::shared_symbols;
using standard::unique_symbols;
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
template <typename T = unused_type>
using symbols [[deprecated(BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING("symbols"))]]
= x3::shared_symbols_parser<char_encoding::standard_wide, T>;
template <typename T = unused_type>
using shared_symbols = x3::shared_symbols_parser<char_encoding::standard_wide, T>;
template <typename T = unused_type>
using unique_symbols = x3::unique_symbols_parser<char_encoding::standard_wide, T>;
} // standard_wide
using symbols = symbols_parser<char_encoding::standard_wide, T>;
}
#endif
namespace [[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]] ascii
namespace ascii
{
template <typename T = unused_type>
using symbols [[deprecated(BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING("symbols"))]]
= x3::shared_symbols_parser<char_encoding::ascii, T>;
using symbols = symbols_parser<char_encoding::ascii, T>;
}
template <typename T = unused_type>
using shared_symbols = x3::shared_symbols_parser<char_encoding::ascii, T>;
template <typename T = unused_type>
using unique_symbols = x3::unique_symbols_parser<char_encoding::ascii, T>;
} // ascii
namespace [[deprecated(BOOST_SPIRIT_X3_WRONG_ENCODING_ASSUMPTION_WARNING)]] iso8859_1
namespace iso8859_1
{
template <typename T = unused_type>
using symbols [[deprecated(BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING("symbols"))]]
= x3::shared_symbols_parser<char_encoding::iso8859_1, T>;
using symbols = symbols_parser<char_encoding::iso8859_1, T>;
}
template <typename T = unused_type>
using shared_symbols = x3::shared_symbols_parser<char_encoding::iso8859_1, T>;
template <typename T = unused_type>
using unique_symbols = x3::unique_symbols_parser<char_encoding::iso8859_1, T>;
} // iso8859_1
#ifdef BOOST_SPIRIT_X3_UNICODE
namespace unicode {
template <typename T = unused_type>
using shared_symbols = x3::shared_symbols_parser<char_encoding::unicode, T>;
template <typename T = unused_type>
using unique_symbols = x3::unique_symbols_parser<char_encoding::unicode, T>;
} // unicode
#endif
} // boost::spirit::x3
#undef BOOST_SPIRIT_X3_IMPLICIT_SHARED_SYMBOLS_WARNING
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
+70 -150
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,208 +7,129 @@
#if !defined(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)
#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM
#include <boost/spirit/home/x3/core/config.hpp>
#include <boost/spirit/home/x3/string/detail/tst_node.hpp>
#include <boost/spirit/home/x3/support/allocator.hpp>
#include <boost/assert.hpp>
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <iterator>
#include <memory>
#include <string>
#include <type_traits>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through
{
template <typename Char>
[[nodiscard]] constexpr Char operator()(Char ch) const noexcept
Char operator()(Char ch) const
{
return ch;
}
};
template <typename Char, typename T, typename Alloc = std::allocator<T>>
template <typename Char, typename T>
struct tst
{
using char_type = Char; // the character type
using value_type = T; // the value associated with each entry
using allocator_type = Alloc;
using node = detail::tst_node<Char, T>;
using node_allocator_type = std::allocator_traits<Alloc>::template rebind_alloc<node>;
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
constexpr tst() noexcept(std::is_nothrow_default_constructible_v<Alloc>) = default;
constexpr explicit tst(Alloc const& alloc) noexcept
: alloc_(alloc)
, node_alloc_(alloc_)
{}
constexpr ~tst() noexcept
{
detail::allocator_ops<tst>::template destroy_deallocate<&tst::node_alloc_, &tst::root_>(*this);
}
constexpr tst(tst const& other)
: alloc_(std::allocator_traits<Alloc>::select_on_container_copy_construction(other.alloc_))
, node_alloc_(std::allocator_traits<node_allocator_type>::select_on_container_copy_construction(other.node_alloc_))
, root_(detail::allocator_ops<tst>::template copy_construct<&tst::node_alloc_, &tst::root_>(*this, other))
tst()
: root(0)
{
}
constexpr tst(tst&& other) noexcept
: alloc_(std::move(other.alloc_))
, node_alloc_(std::move(other.node_alloc_))
, root_(std::exchange(other.root_, nullptr))
~tst()
{
clear();
}
constexpr tst& operator=(tst const& other)
tst(tst const& rhs)
: root(0)
{
if (this == std::addressof(other)) return *this;
detail::allocator_ops<tst>::template copy_assign<&tst::node_alloc_, &tst::root_>(*this, other);
detail::allocator_ops<tst>::template copy_assign<&tst::alloc_>(*this, other);
return *this;
copy(rhs);
}
constexpr tst& operator=(tst&& other)
noexcept(detail::allocator_ops<tst>::template move_assign_noexcept<allocator_type, node_allocator_type>)
tst& operator=(tst const& rhs)
{
if (this == std::addressof(other)) return *this;
detail::allocator_ops<tst>::template move_assign<&tst::node_alloc_, &tst::root_>(*this, std::move(other));
detail::allocator_ops<tst>::template move_assign<&tst::alloc_>(*this, std::move(other));
return *this;
return assign(rhs);
}
template <std::forward_iterator Iterator, typename CaseCompare>
[[nodiscard]] constexpr T* find(Iterator& first, Iterator last, CaseCompare caseCompare) const noexcept
template <typename Iterator, typename CaseCompare>
T* find(Iterator& first, Iterator last, CaseCompare caseCompare) const
{
return node::find(root_, first, last, caseCompare);
return node::find(root, first, last, caseCompare);
}
template <std::forward_iterator Iterator, typename Val>
constexpr T* add(Iterator first, Iterator last, Val&& val)
/*template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
if (first == last) return nullptr;
if (!root_)
{
root_ = std::allocator_traits<node_allocator_type>::allocate(node_alloc_, 1);
std::allocator_traits<node_allocator_type>::construct(node_alloc_, root_, *first, alloc_);
}
return find(first, last, case_compare<tst_pass_through());
}*/
return this->add(root_, first, last, std::forward<Val>(val));
template <typename Iterator>
T* add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
return node::add(root, first, last, val, this);
}
template <std::forward_iterator Iterator>
constexpr void remove(Iterator first, Iterator last) noexcept
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
this->remove(root_, first, last);
node::remove(root, first, last, this);
}
constexpr void clear() noexcept
void clear()
{
if (!root_) return;
std::allocator_traits<node_allocator_type>::destroy(node_alloc_, root_);
std::allocator_traits<node_allocator_type>::deallocate(node_alloc_, root_, 1);
root_ = nullptr;
node::destruct_node(root, this);
root = 0;
}
template <typename F>
constexpr void for_each(F&& f) const
void for_each(F f) const
{
node::for_each(root_, {}, std::forward<F>(f));
node::for_each(root, std::basic_string<Char>(), f);
}
friend struct detail::allocator_ops<tst>;
private:
template <std::forward_iterator Iterator, typename Val>
[[nodiscard]] constexpr T*
add(node* root, Iterator first, Iterator last, Val&& val)
friend struct detail::tst_node<Char, T>;
void copy(tst const& rhs)
{
BOOST_ASSERT(root != nullptr);
BOOST_ASSERT(first != last);
node** pp = &root;
auto c = *first;
while (true)
{
node* const p = *pp;
if (c == p->id)
{
if (++first == last)
{
if (!p->data)
{
p->data = std::allocator_traits<Alloc>::allocate(alloc_, 1);
std::allocator_traits<Alloc>::construct(alloc_, p->data, std::forward<Val>(val));
}
return p->data;
}
pp = &p->eq;
c = *first;
}
else if (c < p->id)
{
pp = &p->lt;
}
else
{
pp = &p->gt;
}
if (!*pp)
{
*pp = std::allocator_traits<node_allocator_type>::allocate(node_alloc_, 1);
std::allocator_traits<node_allocator_type>::construct(node_alloc_, *pp, c);
}
}
root = node::clone_node(rhs.root, this);
}
template <std::forward_iterator Iterator>
constexpr void
remove(node*& p, Iterator first, Iterator last) noexcept
tst& assign(tst const& rhs)
{
if (!p || first == last) return;
auto c = *first;
if (c == p->id)
if (this != &rhs)
{
if (++first == last)
{
if (p->data)
{
std::allocator_traits<Alloc>::destroy(alloc_, p->data);
std::allocator_traits<Alloc>::deallocate(alloc_, p->data, 1);
p->data = nullptr;
}
}
this->remove(p->eq, first, last);
}
else if (c < p->id)
{
this->remove(p->lt, first, last);
}
else
{
this->remove(p->gt, first, last);
}
if (!p->data && !p->lt && !p->eq && !p->gt)
{
std::allocator_traits<node_allocator_type>::destroy(node_alloc_, p);
std::allocator_traits<node_allocator_type>::deallocate(node_alloc_, p, 1);
p = nullptr;
clear();
copy(rhs);
}
return *this;
}
BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS Alloc alloc_;
BOOST_SPIRIT_X3_NO_UNIQUE_ADDRESS node_allocator_type node_alloc_;
node* root_ = nullptr;
node* root;
node* new_node(Char id)
{
return new node(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return new T(val);
}
void delete_node(node* p)
{
delete p;
}
void delete_data(T* p)
{
delete p;
}
};
}
}}}
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -8,10 +7,9 @@
#if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
#include <boost/spirit/home/x3/string/tst.hpp>
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <unordered_map>
#include <boost/pool/object_pool.hpp>
#include <boost/call_traits.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -1,252 +0,0 @@
/*=============================================================================
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SUPPORT_ALLOCATOR_HPP)
#define BOOST_SPIRIT_X3_SUPPORT_ALLOCATOR_HPP
#include <boost/assert.hpp>
#include <memory>
#include <type_traits>
#include <utility>
namespace boost::spirit::x3::detail {
template <typename Klass>
struct allocator_ops
{
template <typename... Allocs>
static constexpr bool move_assign_noexcept = std::conjunction_v<
std::disjunction<
typename std::allocator_traits<Allocs>::propagate_on_container_move_assignment,
typename std::allocator_traits<Allocs>::is_always_equal
>...
>;
template <auto AllocMem, auto Mem>
[[nodiscard]] static constexpr auto copy_construct(Klass& self, Klass const& other)
-> std::remove_reference_t<decltype(self.*Mem)>
{
if (!(other.*Mem)) return nullptr;
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
auto& alloc = self.*AllocMem;
auto* data = std::allocator_traits<Alloc>::allocate(alloc, 1);
std::allocator_traits<Alloc>::construct(alloc, data, *(other.*Mem));
return data;
}
template <auto AllocMem, auto... Mems>
static constexpr void destroy_deallocate(Klass& self) noexcept
{
static_assert(sizeof...(Mems) > 0);
(allocator_ops::destroy_deallocate_impl<AllocMem, Mems>(self), ...);
}
template <auto AllocMem, auto... Mems>
static constexpr void copy_assign(Klass& self, Klass const& other)
{
BOOST_ASSERT(std::addressof(self) != std::addressof(other));
(allocator_ops::copy_assign_impl<AllocMem, Mems>(self, other), ...);
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
constexpr bool pocca = std::allocator_traits<Alloc>::propagate_on_container_copy_assignment::value;
if constexpr (pocca)
{
self.*AllocMem = other.*AllocMem;
}
}
template <auto AllocMem, auto... Mems>
static constexpr void move_assign(Klass& self, Klass&& other)
noexcept(move_assign_noexcept<decltype(self.*AllocMem)>)
{
BOOST_ASSERT(std::addressof(self) != std::addressof(other));
(allocator_ops::move_assign_impl<AllocMem, Mems>(self, std::move(other)), ...);
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
constexpr bool pocca = std::allocator_traits<Alloc>::propagate_on_container_move_assignment::value;
if constexpr (pocca)
{
self.*AllocMem = std::move(other.*AllocMem);
}
}
private:
template <auto AllocMem, auto Mem>
static constexpr void destroy_deallocate_impl(Klass& self) noexcept
{
auto& data = self.*Mem;
if (!data) return;
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
auto& alloc = self.*AllocMem;
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
}
template <auto AllocMem, auto Mem>
static constexpr void copy_assign_impl(Klass& self, Klass const& other)
{
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
constexpr bool pocca = std::allocator_traits<Alloc>::propagate_on_container_copy_assignment::value;
auto& data = self.*Mem;
auto& alloc = self.*AllocMem;
auto const& other_data = other.*Mem;
auto const& other_alloc = other.*AllocMem;
if (other_data)
{
if constexpr (std::allocator_traits<Alloc>::is_always_equal::value)
{
if (data)
{
*data = *other_data;
return;
}
if constexpr (pocca)
{
data = std::allocator_traits<Alloc>::allocate(other_alloc, 1);
std::allocator_traits<Alloc>::construct(other_alloc, data, *other_data);
}
else
{
data = std::allocator_traits<Alloc>::allocate(alloc, 1);
std::allocator_traits<Alloc>::construct(alloc, data, *other_data);
}
return;
}
else if (alloc == other_alloc)
{
if (data)
{
*data = *other_data;
return;
}
if constexpr (pocca)
{
data = std::allocator_traits<Alloc>::allocate(other_alloc, 1);
std::allocator_traits<Alloc>::construct(other_alloc, data, *other_data);
}
else
{
data = std::allocator_traits<Alloc>::allocate(alloc, 1);
std::allocator_traits<Alloc>::construct(alloc, data, *other_data);
}
return;
}
else
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
data = nullptr;
}
if constexpr (pocca)
{
data = std::allocator_traits<Alloc>::allocate(other_alloc, 1);
std::allocator_traits<Alloc>::construct(other_alloc, data, *other_data);
}
else
{
data = std::allocator_traits<Alloc>::allocate(alloc, 1);
std::allocator_traits<Alloc>::construct(alloc, data, *other_data);
}
return;
}
}
else // !other_data
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
data = nullptr;
}
return;
}
}
template <auto AllocMem, auto Mem>
static constexpr void move_assign_impl(Klass& self, Klass&& other)
noexcept(move_assign_noexcept<std::remove_reference_t<decltype(self.*AllocMem)>>)
{
using Alloc = std::remove_reference_t<decltype(self.*AllocMem)>;
constexpr bool pocma = std::allocator_traits<Alloc>::propagate_on_container_move_assignment::value;
auto& data = self.*Mem;
auto& alloc = self.*AllocMem;
auto& other_data = other.*Mem;
auto& other_alloc = other.*AllocMem;
if (other_data)
{
if constexpr (std::allocator_traits<Alloc>::is_always_equal::value)
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
}
data = std::exchange(other_data, nullptr);
return;
}
else if (alloc == other_alloc)
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
}
data = std::exchange(other_data, nullptr);
return;
}
else
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
}
if constexpr (pocma)
{
data = std::allocator_traits<Alloc>::allocate(other_alloc, 1);
std::allocator_traits<Alloc>::construct(other_alloc, data, std::move(*other_data));
}
else
{
data = std::allocator_traits<Alloc>::allocate(alloc, 1);
std::allocator_traits<Alloc>::construct(alloc, data, std::move(*other_data));
}
std::allocator_traits<Alloc>::destroy(other_alloc, other_data);
std::allocator_traits<Alloc>::deallocate(other_alloc, other_data, 1);
return;
}
}
else // !other_data
{
if (data)
{
std::allocator_traits<Alloc>::destroy(alloc, data);
std::allocator_traits<Alloc>::deallocate(alloc, data, 1);
data = nullptr;
}
return;
}
}
};
} // boost::spirit::x3::detail
#endif
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,9 +11,7 @@
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
#include <cstdint>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
struct no_case_tag {};
@@ -22,20 +19,19 @@ namespace boost::spirit::x3
struct case_compare
{
template <typename Char, typename CharSet>
[[nodiscard]] constexpr bool in_set(Char ch, CharSet const& set) noexcept
bool in_set(Char ch, CharSet const& set)
{
static_assert(noexcept(set.test(ch)));
return set.test(ch);
}
template <typename Char>
[[nodiscard]] constexpr std::int32_t operator()(Char lc, Char rc) const noexcept
int32_t operator()(Char lc, Char rc) const
{
return lc - rc;
}
template <typename CharClassTag>
[[nodiscard]] constexpr CharClassTag get_char_class_tag(CharClassTag tag) const noexcept
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
@@ -45,18 +41,17 @@ namespace boost::spirit::x3
struct no_case_compare
{
template <typename Char, typename CharSet>
[[nodiscard]] bool in_set(Char ch_, CharSet const& set) noexcept // TODO: constexpr
bool in_set(Char ch_, CharSet const& set)
{
using char_type = typename Encoding::classify_type;
auto ch = char_type(ch_);
static_assert(noexcept(set.test(ch)));
return set.test(ch)
|| set.test(Encoding::islower(ch)
? Encoding::toupper(ch) : Encoding::tolower(ch));
}
template <typename Char>
[[nodiscard]] std::int32_t operator()(Char lc_, Char const rc_) const noexcept // TODO: constexpr
int32_t operator()(Char lc_, Char const rc_) const
{
using char_type = typename Encoding::classify_type;
auto lc = char_type(lc_);
@@ -66,45 +61,43 @@ namespace boost::spirit::x3
}
template <typename CharClassTag>
[[nodiscard]] constexpr CharClassTag get_char_class_tag(CharClassTag tag) const noexcept
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
[[nodiscard]] constexpr alpha_tag get_char_class_tag(lower_tag) const noexcept
alpha_tag get_char_class_tag(lower_tag ) const
{
return {};
}
[[nodiscard]] constexpr alpha_tag get_char_class_tag(upper_tag) const noexcept
alpha_tag get_char_class_tag(upper_tag ) const
{
return {};
}
};
namespace detail
template <typename Encoding>
case_compare<Encoding> get_case_compare_impl(unused_type const&)
{
template <typename Encoding>
[[nodiscard]] constexpr case_compare<Encoding> get_case_compare_impl(unused_type const&) noexcept
{
return {};
}
template <typename Encoding>
[[nodiscard]] constexpr no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&) noexcept
{
return {};
}
} // detail
template <typename Encoding, typename Context>
[[nodiscard]] constexpr decltype(auto) get_case_compare(Context const& context) noexcept
{
return detail::get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
return {};
}
auto const no_case_compare_ = no_case_tag{}; // TODO: this should be private
template <typename Encoding>
no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
{
return {};
}
} // boost::spirit::x3
template <typename Encoding, typename Context>
inline decltype(auto) get_case_compare(Context const& context)
{
return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
}
auto const no_case_compare_ = no_case_tag{};
}}}
#endif
@@ -16,7 +16,7 @@
#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#include <boost/spirit/home/x3/support/traits/char_encoding_traits.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/iteration/local.hpp>
@@ -123,7 +123,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
{
return (Radix <= 10 || (ch >= '0' && ch <= '9'))
? ch - '0'
: traits::char_encoding_traits<Char>::encoding_type::tolower(ch) - 'a' + 10;
: char_encoding::ascii::tolower(ch) - 'a' + 10;
}
};
@@ -1,62 +0,0 @@
/*=============================================================================
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_SUPPORT_TRAITS_CHAR_ENCODING_TRAITS_HPP
#define BOOST_SPIRIT_X3_SUPPORT_TRAITS_CHAR_ENCODING_TRAITS_HPP
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp>
#include <boost/spirit/home/x3/string/literal_string.hpp>
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/x3/char_encoding/unicode.hpp>
#endif
namespace boost::spirit::x3::traits
{
namespace detail
{
template <typename Encoding>
struct char_encoding_traits_impl
{
using encoding_type = Encoding;
template <class... Args>
[[nodiscard]] static constexpr auto lit(Args&&... args)
noexcept(noexcept(Encoding::lit(std::forward<Args>(args)...)))
{
return Encoding::lit(std::forward<Args>(args)...);
}
template <class... Args>
[[nodiscard]] static constexpr auto string(Args&&... args)
noexcept(noexcept(Encoding::string(std::forward<Args>(args)...)))
{
return Encoding::string(std::forward<Args>(args)...);
}
};
} // detail
template <traits::CharLike CharT>
struct char_encoding_traits;
template <>
struct char_encoding_traits<char> : detail::char_encoding_traits_impl<char_encoding::standard> {};
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
template <>
struct char_encoding_traits<wchar_t> : detail::char_encoding_traits_impl<char_encoding::standard_wide> {};
#endif
#ifdef BOOST_SPIRIT_X3_UNICODE
template <>
struct char_encoding_traits<char32_t> : detail::char_encoding_traits_impl<char_encoding::unicode> {};
#endif
} // boost::spirit::x3::traits
#endif
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,16 +9,16 @@
#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
#include <boost/variant.hpp>
#include <boost/optional/optional.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#ifdef BOOST_SPIRIT_X3_UNICODE
# include <boost/spirit/home/x3/char_encoding/unicode.hpp>
# include <boost/spirit/home/support/char_encoding/unicode.hpp>
#endif
namespace boost::spirit::x3::traits
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Out, typename T>
void print_attribute(Out& out, T const& val);
@@ -166,6 +165,6 @@ namespace boost::spirit::x3::traits
{
print_attribute_debug<Out, T>::call(out, val);
}
} // boost::spirit::x3::traits
}}}}
#endif
@@ -1,8 +1,7 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 Bryce Lelbach
Copyright (c) 2025 Nana Sakisaka
Copyright (c) 2010 Bryce Lelbach
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,113 +9,146 @@
#if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
#if defined(BOOST_SPIRIT_UNICODE) && !defined(BOOST_SPIRIT_X3_UNICODE)
# error "`BOOST_SPIRIT_UNICODE` has no effect on X3. #define `BOOST_SPIRIT_X3_UNICODE`"
#endif
#if defined(BOOST_SPIRIT_X3_NO_STANDARD_WIDE) && !defined(BOOST_SPIRIT_X3_NO_STANDARD_WIDE)
# error "`BOOST_SPIRIT_X3_NO_STANDARD_WIDE` has no effect on X3. #define `BOOST_SPIRIT_X3_NO_STANDARD_WIDE`"
#endif
#include <string>
#include <string_view>
#include <type_traits>
#include <concepts>
#include <boost/mpl/bool.hpp>
namespace boost::spirit::x3::char_encoding
namespace boost { namespace spirit { namespace x3 { namespace traits
{
struct standard;
///////////////////////////////////////////////////////////////////////////
// Get the C string from a string
///////////////////////////////////////////////////////////////////////////
template <typename String>
struct extract_c_string;
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
struct standard_wide;
#endif
template <typename String>
struct extract_c_string
{
template <typename T>
static T const* call (T* str)
{
return (T const*)str;
}
#ifdef BOOST_SPIRIT_X3_UNICODE
struct unicode;
#endif
} // boost::spirit::x3::char_encoding
template <typename T>
static T const* call (T const* str)
{
return str;
}
};
namespace boost::spirit::x3::traits
{
// Forwarder that strips const
template <typename T>
concept CharLike =
std::same_as<std::remove_cvref_t<T>, char> ||
std::same_as<std::remove_cvref_t<T>, wchar_t> ||
std::same_as<std::remove_cvref_t<T>, char8_t> ||
std::same_as<std::remove_cvref_t<T>, char16_t> ||
std::same_as<std::remove_cvref_t<T>, char32_t>;
struct extract_c_string<T const>
{
static decltype(auto) call(T const str)
{
return extract_c_string<T>::call(str);
}
};
// Spirit has historically converted "c" to 'c'.
//
// While we think it's still useful to retain the conversion,
// we need to avoid further conversion to `std::basic_string_view`,
// which leads to performance overhead. This trait enables
// detection of such arrays.
//
// Note that the status quo introduces ambiguity in determining
// {'c', '\0'} and {'c', 'd'}, but we're not aware of any practical
// usage of non-null-terminated character array in the context of
// DSL on parser combinator.
//
// However, if compelling use cases emerge, we may revise these
// semantics. Versioned as `X3` for forward compatibility.
template <typename T, typename CharT>
concept X3VagueArrayOf2Chars =
std::same_as<std::remove_all_extents_t<std::remove_cvref_t<T>>, CharT> &&
std::is_bounded_array_v<std::remove_cvref_t<T>> &&
std::extent_v<std::remove_cvref_t<T>> == 2;
// Forwarder that strips references
template <typename T>
struct extract_c_string<T&>
{
static decltype(auto) call(T& str)
{
return extract_c_string<T>::call(str);
}
};
// Main utility to guide `char_`, `lit` and `string` to be
// resolved into either `x3::literal_char` or `x3::literal_string`.
//
// This may also be used in other codes which require the same
// semantics.
template <typename T, typename CharT>
concept CppStringLike =
// This avoids converting `CharT[2]` to `std::basic_string_view`.
(!X3VagueArrayOf2Chars<T, CharT>) &&
// All other types that are *naturally* convertible to `std::basic_string_view`.
std::convertible_to<std::decay_t<T>, std::basic_string_view<CharT>>;
// Forwarder that strips const references
template <typename T>
struct extract_c_string<T const&>
{
static decltype(auto) call(T const& str)
{
return extract_c_string<T>::call(str);
}
};
// Mixing incompatible character types is semantically wrong.
// Don't do that. It may even lead to security vulnerabilities.
template <typename T, typename ExpectedCharT>
concept CharIncompatibleWith =
CharLike<T> &&
!std::same_as<std::remove_cvref_t<T>, ExpectedCharT>;
template <typename T, typename Traits, typename Allocator>
struct extract_c_string<std::basic_string<T, Traits, Allocator> >
{
typedef std::basic_string<T, Traits, Allocator> string;
// Mixing incompatible character types is semantically wrong.
// Don't do that. It may even lead to security vulnerabilities.
template <typename T, typename ExpectedCharT>
concept StringLikeIncompatibleWith =
CharLike<std::remove_const_t<std::remove_pointer_t<std::decay_t<T>>>> &&
!std::convertible_to<T, std::basic_string_view<ExpectedCharT>>;
static T const* call (string const& str)
{
return str.c_str();
}
};
namespace detail {
template <CharLike CharT> struct char_encoding_for_impl;
template <> struct char_encoding_for_impl<char> { using type = char_encoding::standard; };
template <typename T>
decltype(auto) get_c_string(T* str)
{
return extract_c_string<T*>::call(str);
}
#ifndef BOOST_SPIRIT_X3_NO_STANDARD_WIDE
template <> struct char_encoding_for_impl<wchar_t> { using type = char_encoding::standard_wide; };
#endif
template <typename T>
decltype(auto) get_c_string(T const* str)
{
return extract_c_string<T const*>::call(str);
}
#ifdef BOOST_SPIRIT_X3_UNICODE
template <> struct char_encoding_for_impl<char8_t> { using type = char_encoding::unicode; };
template <> struct char_encoding_for_impl<char16_t> { using type = char_encoding::unicode; };
template <> struct char_encoding_for_impl<char32_t> { using type = char_encoding::unicode; };
#endif
} // detail
template <typename String>
decltype(auto) get_c_string(String& str)
{
return extract_c_string<String>::call(str);
}
template <class T>
using maybe_owning_string = std::conditional_t<
std::is_pointer_v<std::decay_t<T>>,
std::basic_string_view<std::remove_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
std::remove_cvref_t<T>
>;
template <typename String>
decltype(auto) get_c_string(String const& str)
{
return extract_c_string<String>::call(str);
}
template <CharLike CharT>
using char_encoding_for = typename detail::char_encoding_for_impl<CharT>::type;
///////////////////////////////////////////////////////////////////////////
// Get the begin/end iterators from a string
///////////////////////////////////////////////////////////////////////////
} // boost::spirit::x3::traits
// Implementation for C-style strings.
template <typename T>
inline T const* get_string_begin(T const* str) { return str; }
template <typename T>
inline T* get_string_begin(T* str) { return str; }
template <typename T>
inline T const* get_string_end(T const* str)
{
T const* last = str;
while (*last)
last++;
return last;
}
template <typename T>
inline T* get_string_end(T* str)
{
T* last = str;
while (*last)
last++;
return last;
}
// Implementation for containers (includes basic_string).
template <typename T, typename Str>
inline typename Str::const_iterator get_string_begin(Str const& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_begin(Str& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::const_iterator get_string_end(Str const& str)
{ return str.end(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_end(Str& str)
{ return str.end(); }
}}}}
#endif
@@ -1,7 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2023 Nikita Kniazev
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,165 +9,121 @@
#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
#include <boost/config.hpp>
#include <ranges>
#include <type_traits>
#include <string>
#include <string_view>
#include <cassert>
namespace boost::spirit::x3
namespace boost { namespace spirit { namespace x3
{
using ucs4_char = char32_t;
using utf8_char = char;
using ucs4_string = std::basic_string<ucs4_char>;
using utf8_string = std::basic_string<utf8_char>;
typedef char32_t ucs4_char;
typedef char utf8_char;
typedef std::basic_string<ucs4_char> ucs4_string;
typedef std::basic_string<utf8_char> utf8_string;
namespace detail {
constexpr void utf8_put_encode(utf8_string& out, ucs4_char x) noexcept
{
// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf D90
if (x > 0x10FFFFul || (0xD7FFul < x && x < 0xE000ul)) [[unlikely]]
x = 0xFFFDul;
namespace detail {
inline void utf8_put_encode(utf8_string& out, ucs4_char x)
{
// https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf D90
if (BOOST_UNLIKELY(x > 0x10FFFFul || (0xD7FFul < x && x < 0xE000ul)))
x = 0xFFFDul;
// Table 3-6. UTF-8 Bit Distribution
if (x < 0x80ul) {
out.push_back(static_cast<unsigned char>(x));
}
else if (x < 0x800ul) {
out.push_back(static_cast<unsigned char>(0xC0ul + (x >> 6)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else if (x < 0x10000ul) {
out.push_back(static_cast<unsigned char>(0xE0ul + (x >> 12)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else {
out.push_back(static_cast<unsigned char>(0xF0ul + (x >> 18)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 12) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
// Table 3-6. UTF-8 Bit Distribution
if (x < 0x80ul) {
out.push_back(static_cast<unsigned char>(x));
}
else if (x < 0x800ul) {
out.push_back(static_cast<unsigned char>(0xC0ul + (x >> 6)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else if (x < 0x10000ul) {
out.push_back(static_cast<unsigned char>(0xE0ul + (x >> 12)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
else {
out.push_back(static_cast<unsigned char>(0xF0ul + (x >> 18)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 12) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + ((x >> 6) & 0x3Ful)));
out.push_back(static_cast<unsigned char>(0x80ul + (x & 0x3Ful)));
}
}
}
template <typename Char>
[[nodiscard]] constexpr utf8_string to_utf8(Char value)
inline utf8_string to_utf8(Char value)
{
utf8_string result;
using UChar = std::make_unsigned_t<Char>;
typedef typename std::make_unsigned<Char>::type UChar;
detail::utf8_put_encode(result, static_cast<UChar>(value));
return result;
}
template <typename Char>
[[nodiscard]] constexpr utf8_string to_utf8(Char const* str)
inline utf8_string to_utf8(Char const* str)
{
utf8_string result;
using UChar = typename std::make_unsigned<Char>::type;
typedef typename std::make_unsigned<Char>::type UChar;
while (*str)
{
detail::utf8_put_encode(result, static_cast<UChar>(*str++));
}
return result;
}
template <typename Char, typename Traits>
[[nodiscard]] constexpr utf8_string
to_utf8(std::basic_string_view<Char, Traits> const str)
template <typename Char, typename Traits, typename Allocator>
inline utf8_string
to_utf8(std::basic_string<Char, Traits, Allocator> const& str)
{
utf8_string result;
using UChar = typename std::make_unsigned<Char>::type;
typedef typename std::make_unsigned<Char>::type UChar;
for (Char ch : str)
{
detail::utf8_put_encode(result, static_cast<UChar>(ch));
}
return result;
}
template <typename Char, typename Traits>
[[nodiscard]] constexpr utf8_string
to_utf8(std::basic_string<Char, Traits> const& str)
{
utf8_string result;
using UChar = typename std::make_unsigned<Char>::type;
for (Char ch : str)
{
detail::utf8_put_encode(result, static_cast<UChar>(ch));
}
return result;
}
// Assume wchar_t content is UTF-16 on MSVC, or mingw/wineg++ with -fshort-wchar
#if defined(_MSC_VER) || defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2
[[nodiscard]] constexpr utf8_string to_utf8(wchar_t value)
inline utf8_string to_utf8(wchar_t value)
{
utf8_string result;
detail::utf8_put_encode(result, static_cast<std::make_unsigned_t<wchar_t>>(value));
detail::utf8_put_encode(result, static_cast<std::make_unsigned<wchar_t>::type>(value));
return result;
}
namespace detail {
template <std::forward_iterator It>
requires std::is_same_v<std::remove_const_t<std::iter_value_t<It>>, wchar_t>
[[nodiscard]] constexpr ucs4_char decode_utf16(It& s) noexcept
inline ucs4_char decode_utf16(wchar_t const*& s)
{
using uwchar_t = std::make_unsigned<wchar_t>::type;
typedef std::make_unsigned<wchar_t>::type uwchar_t;
uwchar_t x(*s);
if (x < 0xD800ul || x > 0xDFFFul)
{
return x;
}
// expected high-surrogate
if ((x >> 10) != 0b110110ul) [[unlikely]]
{
if (BOOST_UNLIKELY((x >> 10) != 0b110110ul))
return 0xFFFDul;
}
uwchar_t y(*++s);
// expected low-surrogate
if ((y >> 10) != 0b110111ul) [[unlikely]]
{
if (BOOST_UNLIKELY((y >> 10) != 0b110111ul))
return 0xFFFDul;
}
return ((x & 0x3FFul) << 10) + (y & 0x3FFul) + 0x10000ul;
}
}
template <typename Traits>
[[nodiscard]] constexpr utf8_string
to_utf8(std::basic_string_view<wchar_t, Traits> const str)
inline utf8_string to_utf8(wchar_t const* str)
{
utf8_string result;
for (auto it = str.begin(); it != str.end(); ++it)
{
detail::utf8_put_encode(result, detail::decode_utf16(it));
}
for (ucs4_char c; (c = detail::decode_utf16(str)) != ucs4_char(); ++str)
detail::utf8_put_encode(result, c);
return result;
}
[[nodiscard]] constexpr utf8_string to_utf8(wchar_t const* str)
template <typename Traits, typename Allocator>
inline utf8_string
to_utf8(std::basic_string<wchar_t, Traits, Allocator> const& str)
{
return x3::to_utf8(std::basic_string_view(str));
}
template <typename Traits>
[[nodiscard]] constexpr utf8_string
to_utf8(std::basic_string<wchar_t, Traits> const& str)
{
utf8_string result;
for (auto it = str.begin(); it != str.end(); ++it)
{
detail::utf8_put_encode(result, detail::decode_utf16(it));
}
return result;
return to_utf8(str.c_str());
}
#endif
} // boost::spirit::x3
}}}
#endif
+2 -1
View File
@@ -91,7 +91,8 @@ run extract_int.cpp ;
run int1.cpp ;
run kleene.cpp ;
run lexeme.cpp ;
run lit.cpp ;
run lit1.cpp ;
run lit2.cpp ;
run list.cpp ;
run matches.cpp ;
run no_case.cpp ;
+16 -47
View File
@@ -1,38 +1,11 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Bryce Lelbach
Copyright (c) 2025 Nana Sakisaka
Copyright (c) 2011 Bryce Lelbach
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include "test.hpp"
#include <boost/spirit/home/x3.hpp>
#include <string_view>
#include <iterator>
struct backwards_bool_policies : boost::spirit::x3::bool_policies<>
{
// we want to interpret a 'true' spelled backwards as 'false'
template <std::forward_iterator It, std::sentinel_for<It> Se, typename Attribute, typename CaseCompare>
[[nodiscard]] static constexpr bool
parse_false(
It& first, Se const& last, Attribute& attr, CaseCompare const& case_compare
)
{
using namespace std::string_view_literals;
namespace x3 = boost::spirit::x3;
if (x3::detail::string_parse("eurt"sv, first, last, x3::unused, case_compare))
{
x3::traits::move_to(false, attr); // result is false
return true;
}
return false;
}
};
#include "bool.hpp"
int main()
{
@@ -54,65 +27,61 @@ int main()
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(true_);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(false_);
BOOST_TEST(test("true", true_));
BOOST_TEST(!test("true", false_));
BOOST_TEST(test("false", false_));
BOOST_TEST(!test("false", true_));
}
{
using boost::spirit::x3::true_;
using boost::spirit::x3::false_;
using boost::spirit::x3::no_case;
BOOST_TEST(test("True", no_case[bool_]));
BOOST_TEST(test("False", no_case[bool_]));
BOOST_TEST(test("True", no_case[true_]));
BOOST_TEST(test("False", no_case[false_]));
}
{
bool b = false;
BOOST_TEST(test_attr("true", bool_, b) && b);
BOOST_TEST(test_attr("false", bool_, b) && !b);
BOOST_TEST(!test_attr("fasle", bool_, b));
}
{
using backwards_bool_type = boost::spirit::x3::bool_parser<bool, boost::spirit::x3::char_encoding::standard, backwards_bool_policies>;
typedef boost::spirit::x3::bool_parser<bool, boost::spirit::char_encoding::standard, backwards_bool_policies>
backwards_bool_type;
constexpr backwards_bool_type backwards_bool{};
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(backwards_bool);
BOOST_TEST(test("true", backwards_bool));
BOOST_TEST(test("eurt", backwards_bool));
BOOST_TEST(!test("false", backwards_bool));
BOOST_TEST(!test("fasle", backwards_bool));
bool b = false;
BOOST_TEST(test_attr("true", backwards_bool, b) && b);
BOOST_TEST(test_attr("eurt", backwards_bool, b) && !b);
BOOST_TEST(!test_attr("false", backwards_bool, b));
BOOST_TEST(!test_attr("fasle", backwards_bool, b));
}
{
struct test_bool_type
{
test_bool_type(bool b = false) : b(b) {} // provide conversion
bool b;
};
using bool_test_type = boost::spirit::x3::bool_parser<test_bool_type, boost::spirit::x3::char_encoding::standard>;
typedef boost::spirit::x3::bool_parser<test_bool_type, boost::spirit::char_encoding::standard>
bool_test_type;
constexpr bool_test_type test_bool{};
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(test_bool);
BOOST_TEST(test("true", test_bool));
BOOST_TEST(test("false", test_bool));
BOOST_TEST(!test("fasle", test_bool));
test_bool_type b = false;
BOOST_TEST(test_attr("true", test_bool, b) && b.b);
BOOST_TEST(test_attr("false", test_bool, b) && !b.b);
+40
View File
@@ -0,0 +1,40 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Bryce Lelbach
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_TEST_QI_BOOL)
#define BOOST_SPIRIT_TEST_QI_BOOL
#include <boost/spirit/home/x3.hpp>
#include "test.hpp"
///////////////////////////////////////////////////////////////////////////////
struct backwards_bool_policies : boost::spirit::x3::bool_policies<>
{
// we want to interpret a 'true' spelled backwards as 'false'
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
parse_false(Iterator& first, Iterator const& last, Attribute& attr, CaseCompare const& case_compare)
{
namespace spirit = boost::spirit;
namespace x3 = boost::spirit::x3;
if (x3::detail::string_parse("eurt", first, last, x3::unused, case_compare))
{
x3::traits::move_to(false, attr); // result is false
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////////
struct test_bool_type
{
test_bool_type(bool b = false) : b(b) {} // provide conversion
bool b;
};
#endif
+34 -23
View File
@@ -1,32 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2019 Christian Mazakas
Copyright (c) 2025 Nana Sakisaka
Copyright (c) 2019 Christian Mazakas
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_SPIRIT_UNICODE
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
#include <string>
#include <string_view>
#include <boost/utility/string_view.hpp>
#include <iostream>
#include <vector>
#include <algorithm>
#include "test.hpp"
int main()
int
main()
{
using spirit_test::test;
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_('x'));
@@ -70,7 +69,7 @@ int main()
}
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test(" x", 'x', space));
BOOST_TEST(test(L" x", L'x', space));
@@ -126,11 +125,11 @@ int main()
auto const sub_delims = char_(U"!$&'()*+,;=");
auto const delims =
std::vector<std::u32string_view>{U"!", U"$", U"&", U"'", U"(", U")", U"*", U"+",
std::vector<boost::u32string_view>{U"!", U"$", U"&", U"'", U"(", U")", U"*", U"+",
U",", U";", U"="};
auto const matched_all_sub_delims =
std::ranges::all_of(delims, [&](auto const delim) -> bool {
std::all_of(delims.begin(), delims.end(), [&](auto const delim) -> bool {
return test(delim, sub_delims);
});
@@ -144,18 +143,18 @@ int main()
auto const chars = char_(U"\u0024\u00a2\u0939\u20ac\U00010348");
auto const test_strings =
std::vector<std::u32string_view>{U"\u0024", U"\u00a2", U"\u0939", U"\u20ac",
std::vector<boost::u32string_view>{U"\u0024", U"\u00a2", U"\u0939", U"\u20ac",
U"\U00010348"};
auto const bad_test_strings = std::vector<std::u32string_view>{U"a", U"B", U"c", U"\u0409"};
auto const bad_test_strings = std::vector<boost::u32string_view>{U"a", U"B", U"c", U"\u0409"};
auto const all_matched =
std::ranges::all_of(test_strings, [&](auto const test_str) -> bool {
std::all_of(test_strings.begin(), test_strings.end(), [&](auto const test_str) -> bool {
return test(test_str, chars);
});
auto const none_matched =
std::ranges::all_of(bad_test_strings, [&](auto const bad_test_str) -> bool {
std::all_of(bad_test_strings.begin(), bad_test_strings.end(), [&](auto const bad_test_str) -> bool {
return !test(bad_test_str, chars);
});
@@ -165,38 +164,50 @@ int main()
{ // single char strings!
namespace standard = boost::spirit::x3::standard;
namespace wide = boost::spirit::x3::standard_wide;
namespace ascii = boost::spirit::x3::ascii;
namespace wide = boost::spirit::x3::standard_wide;
BOOST_TEST(test("x", "x"));
BOOST_TEST(test(L"x", L"x"));
BOOST_TEST(test("x", standard::char_("x")));
BOOST_TEST(test("x", ascii::char_("x")));
BOOST_TEST(test(L"x", wide::char_(L"x")));
BOOST_TEST(test("x", standard::char_("a", "z")));
BOOST_TEST(test("x", ascii::char_("a", "z")));
BOOST_TEST(test(L"x", wide::char_(L"a", L"z")));
}
{
// chsets
namespace standard = boost::spirit::x3::standard;
namespace ascii = boost::spirit::x3::ascii;
namespace wide = boost::spirit::x3::standard_wide;
BOOST_TEST(test("x", standard::char_("a-z")));
BOOST_TEST(!test("1", standard::char_("a-z")));
BOOST_TEST(test("1", standard::char_("a-z0-9")));
BOOST_TEST(test("x", ascii::char_("a-z")));
BOOST_TEST(!test("1", ascii::char_("a-z")));
BOOST_TEST(test("1", ascii::char_("a-z0-9")));
BOOST_TEST(test("x", wide::char_(L"a-z")));
BOOST_TEST(!test("1", wide::char_(L"a-z")));
BOOST_TEST(test("1", wide::char_(L"a-z0-9")));
std::string set = "a-z0-9";
BOOST_TEST(test("x", standard::char_(set)));
BOOST_TEST(test("x", ascii::char_(set)));
#ifdef SPIRIT_NO_COMPILE_CHECK
test("", ascii::char_(L"a-z0-9"));
#endif
}
{
namespace ascii = boost::spirit::x3::ascii;
char const* input = "\x80";
// ascii > 7 bits (this should fail, not assert!)
BOOST_TEST(!test(input, ascii::char_));
BOOST_TEST(!test(input, ascii::char_('a')));
BOOST_TEST(!test(input, ascii::alnum));
BOOST_TEST(!test(input, ascii::char_("a-z")));
BOOST_TEST(!test(input, ascii::char_('0', '9')));
}
return boost::report_errors();
}
+154 -44
View File
@@ -1,23 +1,21 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2010 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_SPIRIT_UNICODE
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/spirit/home/x3.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iostream>
#include "test.hpp"
#include <boost/spirit/home/x3.hpp>
#include <type_traits>
#include <iostream>
int main()
int
main()
{
using spirit_test::test;
using spirit_test::test_failure;
@@ -25,6 +23,113 @@ int main()
using boost::spirit::x3::unused_type;
{
using namespace boost::spirit::x3::ascii;
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);
BOOST_TEST(test("1", alnum));
BOOST_TEST(!test(" ", alnum));
BOOST_TEST(!test("1", alpha));
BOOST_TEST(test("x", alpha));
BOOST_TEST(test(" ", blank));
BOOST_TEST(!test("x", blank));
BOOST_TEST(test("1", digit));
BOOST_TEST(!test("x", digit));
BOOST_TEST(test("a", lower));
BOOST_TEST(!test("A", lower));
BOOST_TEST(test("!", punct));
BOOST_TEST(!test("x", punct));
BOOST_TEST(test(" ", space));
BOOST_TEST(test("\n", space));
BOOST_TEST(test("\r", space));
BOOST_TEST(test("\t", space));
BOOST_TEST(test("A", upper));
BOOST_TEST(!test("a", upper));
BOOST_TEST(test("A", xdigit));
BOOST_TEST(test("0", xdigit));
BOOST_TEST(test("f", xdigit));
BOOST_TEST(!test("g", xdigit));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(!test("1", ~alnum));
BOOST_TEST(test(" ", ~alnum));
BOOST_TEST(test("1", ~alpha));
BOOST_TEST(!test("x", ~alpha));
BOOST_TEST(!test(" ", ~blank));
BOOST_TEST(test("x", ~blank));
BOOST_TEST(!test("1", ~digit));
BOOST_TEST(test("x", ~digit));
BOOST_TEST(!test("a", ~lower));
BOOST_TEST(test("A", ~lower));
BOOST_TEST(!test("!", ~punct));
BOOST_TEST(test("x", ~punct));
BOOST_TEST(!test(" ", ~space));
BOOST_TEST(!test("\n", ~space));
BOOST_TEST(!test("\r", ~space));
BOOST_TEST(!test("\t", ~space));
BOOST_TEST(!test("A", ~upper));
BOOST_TEST(test("a", ~upper));
BOOST_TEST(!test("A", ~xdigit));
BOOST_TEST(!test("0", ~xdigit));
BOOST_TEST(!test("f", ~xdigit));
BOOST_TEST(test("g", ~xdigit));
}
{
using namespace boost::spirit::x3::iso8859_1;
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alpha);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(digit);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(xdigit);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(cntrl);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(graph);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lower);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(print);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(punct);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);
BOOST_TEST(test("1", alnum));
BOOST_TEST(!test(" ", alnum));
BOOST_TEST(!test("1", alpha));
BOOST_TEST(test("x", alpha));
BOOST_TEST(test(" ", blank));
BOOST_TEST(!test("x", blank));
BOOST_TEST(test("1", digit));
BOOST_TEST(!test("x", digit));
BOOST_TEST(test("a", lower));
BOOST_TEST(!test("A", lower));
BOOST_TEST(test("!", punct));
BOOST_TEST(!test("x", punct));
BOOST_TEST(test(" ", space));
BOOST_TEST(test("\n", space));
BOOST_TEST(test("\r", space));
BOOST_TEST(test("\t", space));
BOOST_TEST(test("A", upper));
BOOST_TEST(!test("a", upper));
BOOST_TEST(test("A", xdigit));
BOOST_TEST(test("0", xdigit));
BOOST_TEST(test("f", xdigit));
BOOST_TEST(!test("g", xdigit));
// test extended ASCII characters
BOOST_TEST(test("\xE9", alpha));
BOOST_TEST(test("\xE9", lower));
BOOST_TEST(!test("\xE9", upper));
}
{
using namespace boost::spirit::x3::standard;
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(alnum);
@@ -116,42 +221,42 @@ int main()
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(space);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(blank);
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(upper);
BOOST_TEST(test(U"1", alnum));
BOOST_TEST(!test(U" ", alnum));
BOOST_TEST(!test(U"1", alpha));
BOOST_TEST(test(U"x", alpha));
BOOST_TEST(test(U" ", blank));
BOOST_TEST(!test(U"x", blank));
BOOST_TEST(test(U"1", digit));
BOOST_TEST(!test(U"x", digit));
BOOST_TEST(test(U"a", lower));
BOOST_TEST(!test(U"A", lower));
BOOST_TEST(test(U"!", punct));
BOOST_TEST(!test(U"x", punct));
BOOST_TEST(test(U" ", space));
BOOST_TEST(test(U"\n", space));
BOOST_TEST(test(U"\r", space));
BOOST_TEST(test(U"\t", space));
BOOST_TEST(test(U"A", upper));
BOOST_TEST(!test(U"a", upper));
BOOST_TEST(test(U"A", xdigit));
BOOST_TEST(test(U"0", xdigit));
BOOST_TEST(test(U"f", xdigit));
BOOST_TEST(!test(U"g", xdigit));
BOOST_TEST(test(L"1", alnum));
BOOST_TEST(!test(L" ", alnum));
BOOST_TEST(!test(L"1", alpha));
BOOST_TEST(test(L"x", alpha));
BOOST_TEST(test(L" ", blank));
BOOST_TEST(!test(L"x", blank));
BOOST_TEST(test(L"1", digit));
BOOST_TEST(!test(L"x", digit));
BOOST_TEST(test(L"a", lower));
BOOST_TEST(!test(L"A", lower));
BOOST_TEST(test(L"!", punct));
BOOST_TEST(!test(L"x", punct));
BOOST_TEST(test(L" ", space));
BOOST_TEST(test(L"\n", space));
BOOST_TEST(test(L"\r", space));
BOOST_TEST(test(L"\t", space));
BOOST_TEST(test(L"A", upper));
BOOST_TEST(!test(L"a", upper));
BOOST_TEST(test(L"A", xdigit));
BOOST_TEST(test(L"0", xdigit));
BOOST_TEST(test(L"f", xdigit));
BOOST_TEST(!test(L"g", xdigit));
BOOST_TEST(test(U"A", alphabetic));
BOOST_TEST(test(U"9", decimal_number));
BOOST_TEST(test(U"\u2800", braille));
BOOST_TEST(!test(U" ", braille));
BOOST_TEST(test(U" ", ~braille));
// TODO: Add more unicode tests
BOOST_TEST(test(L"A", alphabetic));
BOOST_TEST(test(L"9", decimal_number));
BOOST_TEST(test(L"\u2800", braille));
BOOST_TEST(!test(L" ", braille));
BOOST_TEST(test(L" ", ~braille));
// $$$ TODO $$$ Add more unicode tests
}
{ // test invalid unicode literals
using namespace boost::spirit::x3::unicode;
auto const invalid_unicode = char32_t{0x7FFFFFFF};
auto const input = std::u32string_view(&invalid_unicode, 1);
auto const input = boost::u32string_view(&invalid_unicode, 1);
BOOST_TEST(test_failure(input, char_));
@@ -163,11 +268,16 @@ int main()
}
{ // test attribute extraction
using boost::spirit::x3::traits::attribute_of_t;
using boost::spirit::x3::standard::alpha;
using boost::spirit::x3::standard::alpha_type;
using boost::spirit::x3::traits::attribute_of;
using boost::spirit::x3::iso8859_1::alpha;
using boost::spirit::x3::iso8859_1::alpha_type;
static_assert(std::is_same_v<attribute_of_t<alpha_type, unused_type>, char>);
static_assert(
boost::is_same<
attribute_of<alpha_type, unused_type>::type
, unsigned char>::value
, "Wrong attribute type!"
);
int attr = 0;
BOOST_TEST(test_attr("a", alpha, attr));
@@ -175,15 +285,15 @@ int main()
}
{ // test attribute extraction
using boost::spirit::x3::standard::alpha;
using boost::spirit::x3::standard::space;
using boost::spirit::x3::iso8859_1::alpha;
using boost::spirit::x3::iso8859_1::space;
char attr = 0;
BOOST_TEST(test_attr(" a", alpha, attr, space));
BOOST_TEST(attr == 'a');
}
{ // test action
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
using boost::spirit::x3::_attr;
char ch;
auto f = [&](auto& ctx){ ch = _attr(ctx); };
+26 -136
View File
@@ -1,164 +1,54 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#undef BOOST_SPIRIT_NO_STANDARD_WIDE
#ifndef BOOST_SPIRIT_UNICODE
# define BOOST_SPIRIT_UNICODE
#endif
#ifndef BOOST_SPIRIT_X3_UNICODE
# define BOOST_SPIRIT_X3_UNICODE
#endif
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/vector.hpp>
#include <string>
#include "test.hpp"
int main()
int
main()
{
namespace x3 = boost::spirit::x3;
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::lit;
using boost::spirit::x3::char_;
// standard
{
(void)x3::lit('f'); // deprecated
(void)x3::lit("f"); // deprecated
(void)x3::lit("foo"); // deprecated
(void)x3::standard::lit('f');
(void)x3::standard::lit("f");
(void)x3::standard::lit("foo");
(void)x3::char_('f'); // deprecated
(void)x3::char_("f"); // deprecated
(void)x3::char_("foo"); // deprecated
(void)x3::standard::char_('f');
(void)x3::standard::char_("f");
(void)x3::standard::char_("foo");
(void)x3::string('f'); // deprecated
(void)x3::string("f"); // deprecated
(void)x3::string("foo"); // deprecated
(void)x3::standard::string('f');
(void)x3::standard::string("f");
(void)x3::standard::string("foo");
}
// standard_wide
{
(void)x3::lit(L'f'); // deprecated
(void)x3::lit(L"f"); // deprecated
(void)x3::lit(L"foo"); // deprecated
(void)x3::standard_wide::lit(L'f');
(void)x3::standard_wide::lit(L"f");
(void)x3::standard_wide::lit(L"foo");
(void)x3::standard_wide::char_(L'f');
(void)x3::standard_wide::char_(L"f");
(void)x3::standard_wide::char_(L"foo");
(void)x3::string(L'f'); // deprecated
(void)x3::string(L"f"); // deprecated
(void)x3::string(L"foo"); // deprecated
(void)x3::standard_wide::string(L'f');
(void)x3::standard_wide::string(L"f");
(void)x3::standard_wide::string(L"foo");
}
// unicode
{
(void)x3::unicode::lit(U'f');
(void)x3::unicode::lit(U"f");
(void)x3::unicode::lit(U"foo");
(void)x3::unicode::char_(U'f');
(void)x3::unicode::char_(U"f");
(void)x3::unicode::char_(U"foo");
(void)x3::unicode::string(U'f');
(void)x3::unicode::string(U"f");
(void)x3::unicode::string(U"foo");
}
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(lit("x"));
{
std::string attr;
auto p = x3::standard::char_ >> x3::standard::lit("\n");
auto p = char_ >> lit("\n");
BOOST_TEST(test_attr("A\n", p, attr));
BOOST_TEST(attr == "A");
}
{
using namespace boost::spirit::x3::ascii;
std::string attr;
auto p = char_ >> lit("\n");
BOOST_TEST(test_attr("A\n", p, attr));
BOOST_TEST(attr == "A");
}
{
using namespace boost::spirit::x3::iso8859_1;
std::string attr;
auto p = char_ >> lit("\n");
BOOST_TEST(test_attr("É\n", p, attr));
BOOST_TEST(attr == "É");
}
{
using namespace boost::spirit::x3::standard_wide;
std::wstring attr;
auto p = x3::standard_wide::char_ >> x3::standard_wide::lit(L"\n");
BOOST_TEST(test_attr(L"É\n", p, attr));
BOOST_TEST(attr == L"É");
auto p = char_ >> lit("\n");
BOOST_TEST(test_attr(l"É\n", p, attr));
BOOST_TEST(attr == "A");
}
// -------------------------------------------------
{
BOOST_TEST((test("kimpo", x3::standard::lit("kimpo"))));
std::basic_string<char> s("kimpo");
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test("kimpo", x3::standard::lit(s))));
BOOST_TEST((test(L"kimpo", x3::standard_wide::lit(ws))));
}
{
std::basic_string<char> s("kimpo");
BOOST_TEST((test("kimpo", x3::standard::lit(s))));
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test(L"kimpo", x3::standard_wide::lit(ws))));
}
// -------------------------------------------------
{
BOOST_TEST((test("kimpo", "kimpo")));
BOOST_TEST((test("kimpo", x3::standard::string("kimpo"))));
BOOST_TEST((test("x", x3::standard::string("x"))));
BOOST_TEST((test(L"x", x3::standard_wide::string(L"x"))));
std::basic_string<char> s("kimpo");
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test("kimpo", s)));
BOOST_TEST((test(L"kimpo", ws)));
BOOST_TEST((test("kimpo", x3::standard::string(s))));
BOOST_TEST((test(L"kimpo", x3::standard_wide::string(ws))));
}
{
BOOST_TEST((test(L"kimpo", L"kimpo")));
BOOST_TEST((test(L"kimpo", x3::standard_wide::string(L"kimpo"))));
BOOST_TEST((test(L"x", x3::standard_wide::string(L"x"))));
}
{
std::basic_string<char> s("kimpo");
BOOST_TEST((test("kimpo", x3::standard::string(s))));
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test(L"kimpo", x3::standard_wide::string(ws))));
}
{
// single-element fusion vector tests
boost::fusion::vector<std::string> s;
BOOST_TEST(test_attr("kimpo", x3::standard::string("kimpo"), s));
BOOST_TEST(boost::fusion::at_c<0>(s) == "kimpo");
}
return boost::report_errors();
}
+89
View File
@@ -0,0 +1,89 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/vector.hpp>
#include <string>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::string;
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(string("x"));
{
BOOST_TEST((test("kimpo", "kimpo")));
BOOST_TEST((test("kimpo", string("kimpo"))));
BOOST_TEST((test("x", string("x"))));
BOOST_TEST((test(L"x", string(L"x"))));
std::basic_string<char> s("kimpo");
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test("kimpo", s)));
BOOST_TEST((test(L"kimpo", ws)));
BOOST_TEST((test("kimpo", string(s))));
BOOST_TEST((test(L"kimpo", string(ws))));
}
{
BOOST_TEST((test(L"kimpo", L"kimpo")));
BOOST_TEST((test(L"kimpo", string(L"kimpo"))));
BOOST_TEST((test(L"x", string(L"x"))));
}
{
std::basic_string<char> s("kimpo");
BOOST_TEST((test("kimpo", string(s))));
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test(L"kimpo", string(ws))));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST((test(" kimpo", string("kimpo"), space)));
BOOST_TEST((test(L" kimpo", string(L"kimpo"), space)));
BOOST_TEST((test(" x", string("x"), space)));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST((test(" kimpo", string("kimpo"), space)));
BOOST_TEST((test(L" kimpo", string(L"kimpo"), space)));
BOOST_TEST((test(" x", string("x"), space)));
}
{
using namespace boost::spirit::x3::ascii;
std::string s;
BOOST_TEST((test_attr("kimpo", string("kimpo"), s)));
BOOST_TEST(s == "kimpo");
s.clear();
BOOST_TEST((test_attr("kimpo", string("kim") >> string("po"), s)));
BOOST_TEST(s == "kimpo");
s.clear();
BOOST_TEST((test_attr(L"kimpo", string(L"kimpo"), s)));
BOOST_TEST(s == "kimpo");
s.clear();
BOOST_TEST((test_attr("x", string("x"), s)));
BOOST_TEST(s == "x");
}
{ // single-element fusion vector tests
boost::fusion::vector<std::string> s;
BOOST_TEST(test_attr("kimpo", string("kimpo"), s));
BOOST_TEST(boost::fusion::at_c<0>(s) == "kimpo");
}
return boost::report_errors();
}
+51
View File
@@ -0,0 +1,51 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::lit;
{
BOOST_TEST((test("kimpo", lit("kimpo"))));
std::basic_string<char> s("kimpo");
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test("kimpo", lit(s))));
BOOST_TEST((test(L"kimpo", lit(ws))));
}
{
std::basic_string<char> s("kimpo");
BOOST_TEST((test("kimpo", lit(s))));
std::basic_string<wchar_t> ws(L"kimpo");
BOOST_TEST((test(L"kimpo", lit(ws))));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST((test(" kimpo", lit("kimpo"), space)));
BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space)));
}
{
using namespace boost::spirit::x3::iso8859_1;
BOOST_TEST((test(" kimpo", lit("kimpo"), space)));
BOOST_TEST((test(L" kimpo", lit(L"kimpo"), space)));
}
return boost::report_errors();
}
+47 -7
View File
@@ -1,6 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,7 +11,8 @@
#include <iostream>
#include "test.hpp"
int main()
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
@@ -20,7 +21,7 @@ int main()
BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(no_case['x']);
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("x", no_case[char_]));
BOOST_TEST(test("X", no_case[char_('x')]));
BOOST_TEST(test("X", no_case[char_('X')]));
@@ -34,7 +35,7 @@ int main()
BOOST_TEST(!test("z", no_case[char_('a', 'y')]));
}
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("X", no_case['x']));
BOOST_TEST(test("X", no_case['X']));
BOOST_TEST(test("x", no_case['X']));
@@ -44,13 +45,24 @@ int main()
}
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::iso8859_1;
BOOST_TEST(test("X", no_case[char_("a-z")]));
BOOST_TEST(!test("1", no_case[char_("a-z")]));
}
{ // test extended ASCII characters
using namespace boost::spirit::x3::iso8859_1;
BOOST_TEST(test("\xC1", no_case[char_('\xE1')]));
BOOST_TEST(test("\xC9", no_case[char_("\xE5-\xEF")]));
BOOST_TEST(!test("\xFF", no_case[char_("\xE5-\xEF")]));
BOOST_TEST(test("\xC1\xE1", no_case[lit("\xE1\xC1")]));
BOOST_TEST(test("\xE1\xE1", no_case[no_case[lit("\xE1\xC1")]]));
}
{
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("Bochi Bochi", no_case[lit("bochi bochi")]));
BOOST_TEST(test("BOCHI BOCHI", no_case[lit("bochi bochi")]));
BOOST_TEST(!test("Vavoo", no_case[lit("bochi bochi")]));
@@ -58,12 +70,40 @@ int main()
{
// should work!
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("x", no_case[no_case[char_]]));
BOOST_TEST(test("x", no_case[no_case[char_('x')]]));
BOOST_TEST(test("yabadabadoo", no_case[no_case[lit("Yabadabadoo")]]));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("X", no_case[alnum]));
BOOST_TEST(test("6", no_case[alnum]));
BOOST_TEST(!test(":", no_case[alnum]));
BOOST_TEST(test("X", no_case[lower]));
BOOST_TEST(test("x", no_case[lower]));
BOOST_TEST(test("X", no_case[upper]));
BOOST_TEST(test("x", no_case[upper]));
BOOST_TEST(!test(":", no_case[lower]));
BOOST_TEST(!test(":", no_case[upper]));
}
{
using namespace boost::spirit::x3::iso8859_1;
BOOST_TEST(test("X", no_case[alnum]));
BOOST_TEST(test("6", no_case[alnum]));
BOOST_TEST(!test(":", no_case[alnum]));
BOOST_TEST(test("X", no_case[lower]));
BOOST_TEST(test("x", no_case[lower]));
BOOST_TEST(test("X", no_case[upper]));
BOOST_TEST(test("x", no_case[upper]));
BOOST_TEST(!test(":", no_case[lower]));
BOOST_TEST(!test(":", no_case[upper]));
}
{
using namespace boost::spirit::x3::standard;
BOOST_TEST(test("X", no_case[alnum]));
+10 -10
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -22,15 +21,16 @@ private:
char str[2];
};
int main()
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::shared_symbols;
using boost::spirit::x3::symbols;
using boost::spirit::x3::no_case;
{ // basics
shared_symbols<int> sym;
symbols<int> sym;
sym.add
("Joel")
@@ -52,7 +52,7 @@ int main()
BOOST_TEST((!test("XXX", sym)));
// test copy
shared_symbols<int> sym2;
symbols<int> sym2;
sym2 = sym;
BOOST_TEST((test("Joel", sym2)));
BOOST_TEST((test("Ruby", sym2)));
@@ -75,7 +75,7 @@ int main()
}
{ // comma syntax
shared_symbols<int> sym;
symbols<int> sym;
sym += "Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey";
BOOST_TEST((test("Joel", sym)));
@@ -93,9 +93,9 @@ int main()
}
{ // no-case handling
using namespace boost::spirit::x3::standard;
using namespace boost::spirit::x3::ascii;
shared_symbols<int> sym;
symbols<int> sym;
// NOTE: make sure all entries are in lower-case!!!
sym = "joel", "ruby", "tenji", "tutit", "kim", "joey";
@@ -118,7 +118,7 @@ int main()
}
{ // attributes
shared_symbols<int> sym;
symbols<int> sym;
sym.add
("Joel", 1)
@@ -154,7 +154,7 @@ int main()
{ // actions
using boost::spirit::x3::_attr;
shared_symbols<int> sym;
symbols<int> sym;
sym.add
("Joel", 1)
("Ruby", 2)
+54 -34
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -10,17 +9,34 @@
#include <iostream>
#include "test.hpp"
int main()
// Custom string type with a C-style string conversion.
struct custom_string_c
{
custom_string_c(char c) { str[0] = c; str[1] = '\0'; }
operator char*() { return str; }
operator char const*() const { return str; }
private:
char str[2];
};
std::string get_str(char const* str)
{
return std::string(str);
}
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::shared_symbols;
using boost::spirit::x3::symbols;
using boost::spirit::x3::rule;
{
// construction from symbol array
char const* syms[] = {"Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey"};
shared_symbols<int> sym(syms);
{ // construction from symbol array
char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
symbols<int> sym(syms);
BOOST_TEST((test("Joel", sym)));
BOOST_TEST((test("Ruby", sym)));
@@ -31,12 +47,11 @@ int main()
BOOST_TEST((!test("XXX", sym)));
}
{
// construction from 2 arrays
{ // construction from 2 arrays
char const* syms[] = {"Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey"};
int data[] = {1, 2, 3, 4, 5, 6};
shared_symbols<int> sym(syms, data);
char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
int data[] = {1,2,3,4,5,6};
symbols<int> sym(syms, data);
int i;
BOOST_TEST((test_attr("Joel", sym, i)));
@@ -54,9 +69,8 @@ int main()
BOOST_TEST((!test_attr("XXX", sym, i)));
}
{
// allow std::string and other string types
shared_symbols<> sym;
{ // allow std::string and other string types
symbols<> sym;
// const and non-const std::string
std::string a("abc");
@@ -74,12 +88,19 @@ int main()
sym = arr;
BOOST_TEST((test("a", sym)));
BOOST_TEST((!test("b", sym)));
// const and non-const custom string type
custom_string_c c('x');
custom_string_c const cc('y');
sym = c, cc;
BOOST_TEST((test("x", sym)));
BOOST_TEST((test("y", sym)));
BOOST_TEST((!test("z", sym)));
}
{
// find
{ // find
shared_symbols<int> sym;
symbols<int> sym;
sym.add("a", 1)("b", 2);
BOOST_TEST(!sym.find("c"));
@@ -95,7 +116,7 @@ int main()
BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
BOOST_TEST(sym.find("c") && *sym.find("c") == 0);
shared_symbols<int> const_sym(sym);
symbols<int> const_sym(sym);
BOOST_TEST(const_sym.find("a") && *const_sym.find("a") == 1);
BOOST_TEST(const_sym.find("b") && *const_sym.find("b") == 2);
@@ -111,22 +132,20 @@ int main()
BOOST_TEST(!sym.prefix_find(first, last) && first == str2);
}
{
// name
shared_symbols<int> sym,sym2;
{ // name
symbols <int> sym,sym2;
sym.name("test");
BOOST_TEST(sym.name()=="test");
sym2 = sym;
BOOST_TEST(sym2.name()=="test");
shared_symbols<int> sym3(sym);
symbols <int> sym3(sym);
BOOST_TEST(sym3.name()=="test");
}
{
// Substrings
{ // Substrings
shared_symbols<int> sym;
symbols<int> sym;
BOOST_TEST(sym.at("foo") == 0);
sym.at("foo") = 1;
BOOST_TEST(sym.at("foo") == 1);
@@ -156,22 +175,23 @@ int main()
}
{
// remove bug
std::string s;
shared_symbols<double> vars;
symbols<double> vars;
vars.add("l1", 12.0);
vars.add("l2", 0.0);
vars.remove("l2");
(void)vars.find("l1");
vars.find("l1");
double* d = vars.find("l1");
BOOST_TEST(d != nullptr);
BOOST_TEST(d != 0);
}
{
// test for proto problem with rvalue references (10-11-2011)
shared_symbols<int> sym;
sym += std::string("Joel");
sym += std::string("Ruby");
{ // test for proto problem with rvalue references (10-11-2011)
symbols<int> sym;
sym += get_str("Joel");
sym += get_str("Ruby");
BOOST_TEST((test("Joel", sym)));
BOOST_TEST((test("Ruby", sym)));
+16 -18
View File
@@ -1,33 +1,30 @@
/*=============================================================================
Copyright (c) 2013 Carl Barron
Copyright (c) 2015 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_SPIRIT_X3_DEBUG
#define BOOST_SPIRIT_X3_USE_BOOST_OPTIONAL 0
#include "test.hpp"
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/support/char_encoding/unicode.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/mpl/int.hpp>
#include <boost/optional.hpp>
#include <optional>
#include <iostream>
#include <numeric>
#include <vector>
#include "test.hpp"
struct roman
{
std::optional<int> a;
std::optional<int> b;
std::optional<int> c;
boost::optional<int> a;
boost::optional<int> b;
boost::optional<int> c;
};
BOOST_FUSION_ADAPT_STRUCT(roman,
@@ -36,29 +33,30 @@ BOOST_FUSION_ADAPT_STRUCT(roman,
int eval(roman const & c)
{
return c.a.value_or(0) + c.b.value_or(0) + c.c.value_or(0);
return c.a.get_value_or(0) + c.b.get_value_or(0) + c.c.get_value_or(0);
}
int main()
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::shared_symbols;
using boost::spirit::x3::symbols;
{ // construction from initializer-list
shared_symbols<int> const ones =
symbols<int> const ones =
{
{"I", 1}, {"II", 2}, {"III", 3}, {"IV", 4},
{"V", 5}, {"VI", 6}, {"VII", 7}, {"VIII", 8},
{"IX", 9}
};
shared_symbols<int> const tens =
symbols<int> const tens =
{
{"X", 10}, {"XX", 20}, {"XXX", 30}, {"XL", 40},
{"L", 50}, {"LX", 60}, {"LXX", 70}, {"LXXX", 80},
{"XC", 90}
};
shared_symbols<int> const hundreds
symbols<int> const hundreds
{
{"C", 100}, {"CC", 200}, {"CCC", 300}, {"CD", 400},
{"D", 500}, {"DC", 600}, {"DCC", 700}, {"DCCC", 800},
@@ -73,13 +71,13 @@ int main()
}
{ // construction from initializer-list without attribute
shared_symbols<> foo = {"a1", "a2", "a3"};
symbols<> foo = {"a1", "a2", "a3"};
BOOST_TEST((test("a3", foo)));
}
{ // assignment from initializer-list
shared_symbols<> foo;
symbols<> foo;
foo = {"a1", "a2", "a3"};
BOOST_TEST((test("a3", foo)));
@@ -87,7 +85,7 @@ int main()
{ // unicode | construction from initializer-list
using namespace boost::spirit;
x3::shared_symbols_parser<char_encoding::unicode, int> foo = {{U"a1", 1}, {U"a2", 2}, {U"a3", 3}};
x3::symbols_parser<char_encoding::unicode, int> foo = {{U"a1", 1}, {U"a2", 2}, {U"a3", 3}};
int r;
BOOST_TEST((test_attr(U"a3", foo, r)));
+26 -46
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,16 +10,13 @@
#include <boost/spirit/home/x3/core/parse.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string_view>
#include <boost/utility/string_view.hpp>
#include <iostream>
namespace spirit_test
{
template <typename Char, typename Parser>
[[nodiscard]] bool test(
Char const* in, Parser const& p, bool full_match = true
)
bool test(Char const* in, Parser const& p, bool full_match = true)
{
Char const* last = in;
while (*last)
@@ -29,11 +25,9 @@ namespace spirit_test
&& (!full_match || (in == last));
}
template <typename Char, typename CharTraits, typename Parser>
[[nodiscard]] bool test(
std::basic_string_view<Char, CharTraits> in,
Parser const& p, bool full_match = true
)
template <typename Char, typename Parser>
bool test(boost::basic_string_view<Char, std::char_traits<Char>> in,
Parser const& p, bool full_match = true)
{
auto const last = in.end();
auto pos = in.begin();
@@ -42,10 +36,8 @@ namespace spirit_test
}
template <typename Char, typename Parser, typename Skipper>
[[nodiscard]] bool test(
Char const* in, Parser const& p,
Skipper const& s, bool full_match = true
)
bool test(Char const* in, Parser const& p
, Skipper const& s, bool full_match = true)
{
Char const* last = in;
while (*last)
@@ -55,7 +47,7 @@ namespace spirit_test
}
template <typename Char, typename Parser>
[[nodiscard]] bool test_failure(Char const* in, Parser const& p)
bool test_failure(Char const* in, Parser const& p)
{
Char const * const start = in;
Char const* last = in;
@@ -65,20 +57,17 @@ namespace spirit_test
return !boost::spirit::x3::parse(in, last, p) && (in == start);
}
template <typename Char, typename CharTraits, typename Parser>
[[nodiscard]] bool test_failure(
std::basic_string_view<Char, CharTraits> const in, Parser const& p
)
template <typename Char, typename Parser>
bool test_failure(boost::basic_string_view<Char, std::char_traits<Char>> const in,
Parser const& p)
{
auto pos = in.begin();
return !boost::spirit::x3::parse(pos, in.end(), p) && (pos == in.begin());
}
template <typename Char, typename Parser, typename Attr>
[[nodiscard]] bool test_attr(
Char const* in, Parser const& p,
Attr& attr, bool full_match = true
)
bool test_attr(Char const* in, Parser const& p
, Attr& attr, bool full_match = true)
{
Char const* last = in;
while (*last)
@@ -88,10 +77,8 @@ namespace spirit_test
}
template <typename Char, typename Parser, typename Attr, typename Skipper>
[[nodiscard]] bool test_attr(
Char const* in, Parser const& p,
Attr& attr, Skipper const& s, bool full_match = true
)
bool test_attr(Char const* in, Parser const& p
, Attr& attr, Skipper const& s, bool full_match = true)
{
Char const* last = in;
while (*last)
@@ -101,10 +88,8 @@ namespace spirit_test
}
template <typename Char, typename Parser>
[[nodiscard]] bool binary_test(
Char const* in, std::size_t size, Parser const& p,
bool full_match = true
)
bool binary_test(Char const* in, std::size_t size, Parser const& p,
bool full_match = true)
{
Char const* last = in + size;
return boost::spirit::x3::parse(in, last, p)
@@ -112,10 +97,8 @@ namespace spirit_test
}
template <typename Char, typename Parser, typename Skipper>
[[nodiscard]] bool binary_test(
Char const* in, std::size_t size, Parser const& p,
Skipper const& s, bool full_match = true
)
bool binary_test(Char const* in, std::size_t size, Parser const& p,
Skipper const& s, bool full_match = true)
{
Char const* last = in + size;
return boost::spirit::x3::phrase_parse(in, last, p, s)
@@ -123,10 +106,8 @@ namespace spirit_test
}
template <typename Char, typename Parser, typename Attr>
[[nodiscard]] bool binary_test_attr(
Char const* in, std::size_t size, Parser const& p,
Attr& attr, bool full_match = true
)
bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
Attr& attr, bool full_match = true)
{
Char const* last = in + size;
return boost::spirit::x3::parse(in, last, p, attr)
@@ -134,21 +115,20 @@ namespace spirit_test
}
template <typename Char, typename Parser, typename Attr, typename Skipper>
[[nodiscard]] bool binary_test_attr(
Char const* in, std::size_t size, Parser const& p,
Attr& attr, Skipper const& s, bool full_match = true
)
bool binary_test_attr(Char const* in, std::size_t size, Parser const& p,
Attr& attr, Skipper const& s, bool full_match = true)
{
Char const* last = in + size;
return boost::spirit::x3::phrase_parse(in, last, p, s, attr)
&& (!full_match || (in == last));
}
template <typename... T>
[[nodiscard]] constexpr bool always_true(T&&...) { return true; }
constexpr bool always_true(T&&...) { return true; }
template <typename Parser>
[[nodiscard]] constexpr bool test_ctors(Parser const& p)
constexpr bool test_ctors(Parser const& p)
{
return always_true(
static_cast<Parser>(static_cast<Parser&&>( // test move ctor
+20 -21
View File
@@ -1,6 +1,5 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2025 Nana Sakisaka
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -9,6 +8,7 @@
#include <boost/phoenix.hpp>
#include <boost/unordered_map.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/cstdint.hpp>
#include <boost/foreach.hpp>
#include <boost/array.hpp>
#include <boost/scoped_array.hpp>
@@ -22,12 +22,10 @@
#include <string>
#include <map>
#include <cstdint>
// We place the data here. Each line comprises various fields
using ucd_line = std::vector<std::string>;
using ucd_vector = std::vector<ucd_line>;
using ucd_iterator = std::vector<ucd_line>::iterator;
typedef std::vector<std::string> ucd_line;
typedef std::vector<ucd_line> ucd_vector;
typedef std::vector<ucd_line>::iterator ucd_iterator;
// spirit and phoenix using declarations
using boost::spirit::qi::parse;
@@ -42,9 +40,9 @@ using boost::phoenix::push_back;
using boost::phoenix::ref;
// basic unsigned types
using std::uint8_t;
using std::uint16_t;
using std::uint32_t;
using boost::uint8_t;
using boost::uint16_t;
using boost::uint32_t;
enum code_action
{
@@ -537,16 +535,15 @@ void print_head(Out& out)
out
<< "/*=============================================================================\n"
<< " Copyright (c) 2001-2011 Joel de Guzman\n"
<< " Copyright (c) 2025 Nana Sakisaka\n"
<< "\n"
<< " Distributed under the Boost Software License, Version 1.0. (See accompanying\n"
<< " file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
<< "\n"
<< " AUTOGENERATED. DO NOT EDIT!!!\n"
<< "==============================================================================*/\n"
<< "#include <cstdint>\n"
<< "#include <boost/cstdint.hpp>\n"
<< "\n"
<< "namespace boost::spirit::x3::unicode::detail\n"
<< "namespace boost { namespace spirit { namespace ucd { namespace detail\n"
<< "{"
;
}
@@ -556,7 +553,7 @@ void print_tail(Out& out)
{
out
<< "\n"
<< "} // boost::spirit::x3::unicode::detail\n"
<< "}}}} // namespace boost::spirit::unicode::detail\n"
;
}
@@ -564,10 +561,10 @@ char const* get_int_type_name(int size)
{
switch (size)
{
case 1: return "std::uint8_t";
case 2: return "std::uint16_t";
case 4: return "std::uint32_t";
case 5: return "std::uint64_t";
case 1: return "::boost::uint8_t";
case 2: return "::boost::uint16_t";
case 4: return "::boost::uint32_t";
case 5: return "::boost::uint64_t";
default: BOOST_ASSERT(false); return 0; // invalid size
};
}
@@ -591,7 +588,7 @@ void print_file(Out& out, Builder& builder, int field_width, char const* name)
out
<< "\n"
<< " inline constexpr std::uint8_t " << name << "_stage1[] = {\n"
<< " static const ::boost::uint8_t " << name << "_stage1[] = {\n"
<< "\n"
;
@@ -603,7 +600,7 @@ void print_file(Out& out, Builder& builder, int field_width, char const* name)
<< " };"
<< "\n"
<< "\n"
<< " inline constexpr " << int_name << ' ' << name << "_stage2[] = {"
<< " static const " << int_name << ' ' << name << "_stage2[] = {"
;
int block_n = 0;
@@ -624,9 +621,9 @@ void print_file(Out& out, Builder& builder, int field_width, char const* name)
out
<< "\n"
<< " [[nodiscard]] constexpr " << int_name << ' ' << name << "_lookup(std::uint32_t ch) noexcept\n"
<< " inline " << int_name << ' ' << name << "_lookup(::boost::uint32_t ch)\n"
<< " {\n"
<< " std::uint32_t block_offset = " << name << "_stage1[ch / " << block_size << "] * " << block_size << ";\n"
<< " ::boost::uint32_t block_offset = " << name << "_stage1[ch / " << block_size << "] * " << block_size << ";\n"
<< " return " << name << "_stage2[block_offset + ch % " << block_size << "];\n"
<< " }\n"
;
@@ -669,4 +666,6 @@ int main()
builder.collect("UnicodeData.txt", 12, assign_code_value);
print_file(out, builder, 6, "uppercase");
}
return 0;
}