update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -35,8 +35,7 @@ namespace boost { namespace spirit { namespace x3
traits::is_container<Attribute>::value;
public:
any_parser()
: _content(nullptr) {}
any_parser() = default;
template <typename Expr,
typename Enable = typename enable_if<traits::is_parser<Expr>>::type>

View File

@@ -16,13 +16,32 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <algorithm>
#include <cstddef>
#include <string>
#include <utility>
namespace boost { namespace spirit { namespace x3
{
namespace detail
{
template <typename Value, std::size_t N
, typename = std::make_index_sequence<N>>
struct array_helper;
template <typename Value, std::size_t N, std::size_t... Is>
struct array_helper<Value, N, std::index_sequence<Is...>>
{
constexpr array_helper(Value const (&value)[N])
: value_{ value[Is]... } {}
constexpr array_helper(Value (&&value)[N])
: value_{ static_cast<Value&&>(value[Is])... } {}
Value value_[N];
};
}
template <typename Value>
struct attr_parser : parser<attr_parser<Value>>
{
@@ -33,9 +52,9 @@ namespace boost { namespace spirit { namespace x3
static bool const handles_container =
traits::is_container<attribute_type>::value;
attr_parser(Value const& value)
constexpr attr_parser(Value const& value)
: value_(value) {}
attr_parser(Value&& value)
constexpr attr_parser(Value&& value)
: value_(std::move(value)) {}
template <typename Iterator, typename Context
@@ -49,30 +68,19 @@ namespace boost { namespace spirit { namespace x3
}
Value value_;
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&);
};
template <typename Value, std::size_t N>
struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
, detail::array_helper<Value, N>
{
using detail::array_helper<Value, N>::array_helper;
typedef Value attribute_type[N];
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = true;
attr_parser(Value const (&value)[N])
{
std::copy(value + 0, value + N, value_ + 0);
}
attr_parser(Value (&&value)[N])
{
std::move(value + 0, value + N, value_ + 0);
}
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
@@ -80,15 +88,9 @@ namespace boost { namespace spirit { namespace x3
, Context const& /* context */, RuleContext&, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
traits::move_to(value_ + 0, value_ + N, attr_);
traits::move_to(this->value_ + 0, this->value_ + N, attr_);
return true;
}
Value value_[N];
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&);
};
template <typename Value>
@@ -104,28 +106,15 @@ namespace boost { namespace spirit { namespace x3
struct attr_gen
{
template <typename Value>
attr_parser<typename remove_cv<
constexpr attr_parser<typename remove_cv<
typename remove_reference<Value>::type>::type>
operator()(Value&& value) const
{
return { std::forward<Value>(value) };
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&value)[N]) const
{
return { value };
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&&value)[N]) const
{
return { value };
}
};
auto const attr = attr_gen{};
constexpr auto attr = attr_gen{};
}}}
#endif

View File

@@ -35,7 +35,7 @@ namespace boost { namespace spirit { namespace x3
result_type operator()(eoi_parser const &) const { return "eoi"; }
};
auto const eoi = eoi_parser{};
constexpr auto eoi = eoi_parser{};
}}}
#endif

View File

@@ -49,7 +49,7 @@ namespace boost { namespace spirit { namespace x3
result_type operator()(eol_parser const &) const { return "eol"; }
};
auto const eol = eol_parser{};
constexpr auto eol = eol_parser{};
}}}
#endif

View File

@@ -20,7 +20,7 @@ namespace boost { namespace spirit { namespace x3
typedef unused_type attribute_type;
static bool const has_attribute = false;
semantic_predicate(bool predicate)
constexpr semantic_predicate(bool predicate)
: predicate(predicate) {}
template <typename Iterator, typename Context, typename Attribute>
@@ -40,7 +40,7 @@ namespace boost { namespace spirit { namespace x3
typedef unused_type attribute_type;
static bool const has_attribute = false;
lazy_semantic_predicate(F f)
constexpr lazy_semantic_predicate(F f)
: f(f) {}
template <typename Iterator, typename Context, typename Attribute>
@@ -68,19 +68,19 @@ namespace boost { namespace spirit { namespace x3
return true;
}
inline semantic_predicate operator()(bool predicate) const
constexpr semantic_predicate operator()(bool predicate) const
{
return { predicate };
}
template <typename F>
lazy_semantic_predicate<F> operator()(F f) const
constexpr lazy_semantic_predicate<F> operator()(F f) const
{
return { f };
}
};
auto const eps = eps_parser{};
constexpr auto eps = eps_parser{};
}}}
#endif

View File

@@ -26,7 +26,7 @@ namespace boost { namespace spirit { namespace x3
typedef unary_parser<Subject, guard<Subject, Handler>> base_type;
static bool const is_pass_through_unary = true;
guard(Subject const& subject, Handler handler)
constexpr guard(Subject const& subject, Handler handler)
: base_type(subject), handler(handler) {}
template <typename Iterator, typename Context

View File

@@ -20,18 +20,18 @@
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/config.hpp>
#include <climits>
namespace boost { namespace spirit { namespace x3
{
template <typename V, typename T
, boost::endian::order endian, std::size_t bits>
template <typename T, boost::endian::order endian, std::size_t bits>
struct binary_lit_parser
: parser<binary_lit_parser<V, T, endian, bits> >
: parser<binary_lit_parser<T, endian, bits> >
{
static bool const has_attribute = false;
typedef unused_type attribute_type;
binary_lit_parser(V n_)
constexpr binary_lit_parser(T n_)
: n(n_) {}
template <typename Iterator, typename Context, typename Attribute>
@@ -40,7 +40,7 @@ namespace boost { namespace spirit { namespace x3
{
x3::skip_over(first, last, context);
auto bytes = reinterpret_cast<const unsigned char*>(&n);
unsigned char const* bytes = n.data();
Iterator it = first;
for (unsigned int i = 0; i < sizeof(n); ++i)
@@ -72,11 +72,12 @@ namespace boost { namespace spirit { namespace x3
{
x3::skip_over(first, last, context);
attribute_type attr_;
auto bytes = reinterpret_cast<unsigned char*>(&attr_);
// Properly align the buffer for performance reasons
alignas(T) unsigned char buf[sizeof(T)];
unsigned char * bytes = buf;
Iterator it = first;
for (unsigned int i = 0; i < sizeof(attr_); ++i)
for (unsigned int i = 0; i < sizeof(T); ++i)
{
if (it == last)
return false;
@@ -84,14 +85,16 @@ namespace boost { namespace spirit { namespace x3
}
first = it;
static_assert(bits % CHAR_BIT == 0,
"Boost.Endian supports only multiples of CHAR_BIT");
x3::traits::move_to(
endian::conditional_reverse<endian, endian::order::native>(attr_)
, attr_param );
endian::endian_load<T, bits / CHAR_BIT, endian>(buf),
attr_param);
return true;
}
template <typename V>
binary_lit_parser< V, T, endian, bits> operator()(V n) const
constexpr binary_lit_parser<T, endian, bits> operator()(T n) const
{
return {n};
}
@@ -99,7 +102,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, attrtype, bits) \
typedef any_binary_parser< attrtype, boost::endian::order::endiantype, bits > name##type; \
name##type const name = name##type();
constexpr name##type name = name##type();
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
@@ -114,18 +117,12 @@ namespace boost { namespace spirit { namespace x3
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, uint_least64_t, 64)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, uint_least64_t, 64)
#endif
// Use a pseudo configuration macro to make clear that endian libray support
// for floating point types is required. Must be removed as soon as the endian library
// properly supports floating point types.
#ifdef BOOST_ENDIAN_HAS_FLOATING_POINT
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, 64)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, 64)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, 64)
#endif
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_float, native, float, sizeof(float) * CHAR_BIT)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_float, big, float, sizeof(float) * CHAR_BIT)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_float, little, float, sizeof(float) * CHAR_BIT)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(bin_double, native, double, sizeof(double) * CHAR_BIT)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_bin_double, big, double, sizeof(double) * CHAR_BIT)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_bin_double, little, double, sizeof(double) * CHAR_BIT)
#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
@@ -134,7 +131,7 @@ namespace boost { namespace spirit { namespace x3
struct get_info<any_binary_parser<T, endian::order::little, bits>>
{
typedef std::string result_type;
std::string operator()(any_binary_parser<T, endian::order::little, bits> const& p) const
std::string operator()(any_binary_parser<T, endian::order::little, bits> const&) const
{
return "little-endian binary";
}
@@ -144,27 +141,27 @@ namespace boost { namespace spirit { namespace x3
struct get_info<any_binary_parser<T, endian::order::big, bits>>
{
typedef std::string result_type;
std::string operator()(any_binary_parser<T, endian::order::big, bits> const& p) const
std::string operator()(any_binary_parser<T, endian::order::big, bits> const&) const
{
return "big-endian binary";
}
};
template <typename V, typename T, std::size_t bits>
struct get_info<binary_lit_parser<V, T, endian::order::little, bits>>
template <typename T, std::size_t bits>
struct get_info<binary_lit_parser<T, endian::order::little, bits>>
{
typedef std::string result_type;
std::string operator()(binary_lit_parser<V, T, endian::order::little, bits> const& p) const
std::string operator()(binary_lit_parser<T, endian::order::little, bits> const&) const
{
return "little-endian binary";
}
};
template <typename V, typename T, std::size_t bits>
struct get_info<binary_lit_parser<V, T, endian::order::big, bits>>
template <typename T, std::size_t bits>
struct get_info<binary_lit_parser<T, endian::order::big, bits>>
{
typedef std::string result_type;
std::string operator()(binary_lit_parser<V, T, endian::order::big, bits> const& p) const
std::string operator()(binary_lit_parser<T, endian::order::big, bits> const&) const
{
return "big-endian binary";
}

View File

@@ -24,35 +24,35 @@ namespace boost { namespace spirit { namespace x3
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
return encoding::ischar(ch_);
}
template <typename Char>
literal_char<Encoding> operator()(Char ch) const
constexpr literal_char<Encoding> operator()(Char ch) const
{
return { ch };
}
template <typename Char>
literal_char<Encoding> operator()(const Char (&ch)[2]) const
constexpr literal_char<Encoding> operator()(const Char (&ch)[2]) const
{
return { ch[0] };
}
template <typename Char, std::size_t N>
char_set<Encoding> operator()(const Char (&ch)[N]) const
constexpr char_set<Encoding> operator()(const Char (&ch)[N]) const
{
return { ch };
}
template <typename Char>
char_range<Encoding> operator()(Char from, Char to) const
constexpr char_range<Encoding> operator()(Char from, Char to) const
{
return { from, to };
}
template <typename Char>
char_range<Encoding> operator()(Char (&from)[2], Char (&to)[2]) const
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]) };
}

View File

@@ -18,15 +18,15 @@ namespace boost { namespace spirit { namespace x3
namespace standard
{
typedef any_char<char_encoding::standard> char_type;
auto const char_ = char_type{};
constexpr auto char_ = char_type{};
inline literal_char<char_encoding::standard, unused_type>
constexpr literal_char<char_encoding::standard, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::standard, unused_type>
constexpr literal_char<char_encoding::standard, unused_type>
lit(wchar_t ch)
{
return { ch };
@@ -42,9 +42,9 @@ namespace boost { namespace spirit { namespace x3
namespace standard_wide
{
typedef any_char<char_encoding::standard_wide> char_type;
auto const char_ = char_type{};
constexpr auto char_ = char_type{};
inline literal_char<char_encoding::standard_wide, unused_type>
constexpr literal_char<char_encoding::standard_wide, unused_type>
lit(wchar_t ch)
{
return { ch };
@@ -55,15 +55,15 @@ namespace boost { namespace spirit { namespace x3
namespace ascii
{
typedef any_char<char_encoding::ascii> char_type;
auto const char_ = char_type{};
constexpr auto char_ = char_type{};
inline literal_char<char_encoding::ascii, unused_type>
constexpr literal_char<char_encoding::ascii, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::ascii, unused_type>
constexpr literal_char<char_encoding::ascii, unused_type>
lit(wchar_t ch)
{
return { ch };
@@ -73,15 +73,15 @@ namespace boost { namespace spirit { namespace x3
namespace iso8859_1
{
typedef any_char<char_encoding::iso8859_1> char_type;
auto const char_ = char_type{};
constexpr auto char_ = char_type{};
inline literal_char<char_encoding::iso8859_1, unused_type>
constexpr literal_char<char_encoding::iso8859_1, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::iso8859_1, unused_type>
constexpr literal_char<char_encoding::iso8859_1, unused_type>
lit(wchar_t ch)
{
return { ch };
@@ -99,7 +99,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(char ch)
static constexpr type call(char ch)
{
return { ch };
}
@@ -115,7 +115,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(wchar_t ch)
static constexpr type call(wchar_t ch)
{
return { ch };
}
@@ -131,7 +131,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(char const ch[])
static constexpr type call(char const ch[])
{
return { ch[0] };
}
@@ -147,7 +147,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(wchar_t const ch[] )
static constexpr type call(wchar_t const ch[] )
{
return { ch[0] };
}

View File

@@ -20,9 +20,9 @@ namespace boost { namespace spirit { namespace x3
template <typename Encoding>
struct char_class_base
{
typedef typename Encoding::char_type char_type;
typedef typename Encoding::classify_type char_type;
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
@@ -63,20 +63,20 @@ namespace boost { namespace spirit { namespace x3
template <typename Char, typename Context>
bool test(Char ch, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
return encoding::ischar(ch)
&& char_class_base<Encoding>::is(
get_case_compare<Encoding>(context).get_char_class_tag(tag()), ch);
}
};
#define BOOST_SPIRIT_X3_CHAR_CLASS(encoding, name) \
typedef char_class<char_encoding::encoding, name##_tag> name##_type; \
name##_type const name = name##_type(); \
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 \
{ \
namespace encoding \
{ \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alnum) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alpha) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, digit) \
@@ -89,7 +89,7 @@ namespace boost { namespace spirit { namespace 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)

View File

@@ -33,7 +33,7 @@ namespace boost { namespace spirit { namespace x3
!is_same<unused_type, attribute_type>::value;
char_range(char_type from_, char_type to_)
constexpr char_range(char_type from_, char_type to_)
: from(from_), to(to_) {}
template <typename Char, typename Context>
@@ -41,9 +41,8 @@ namespace boost { namespace spirit { namespace x3
{
char_type ch = char_type(ch_); // optimize for token based parsing
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
&& (get_case_compare<encoding>(context)(ch, from) >= 0 )
&& (get_case_compare<encoding>(context)(ch , to) <= 0 );
return (get_case_compare<encoding>(context)(ch, from) >= 0)
&& (get_case_compare<encoding>(context)(ch , to) <= 0);
}
char_type from, to;
@@ -67,18 +66,11 @@ namespace boost { namespace spirit { namespace x3
{
using spirit::x3::detail::cast_char;
typedef typename
remove_const<
typename traits::char_type_of<String>::type
>::type
in_type;
in_type const* definition =
(in_type const*)traits::get_c_string(str);
in_type ch = *definition++;
auto* definition = traits::get_c_string(str);
auto ch = *definition++;
while (ch)
{
in_type next = *definition++;
auto next = *definition++;
if (next == '-')
{
next = *definition++;
@@ -104,8 +96,7 @@ namespace boost { namespace spirit { namespace x3
template <typename Char, typename Context>
bool test(Char ch_, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
&& get_case_compare<encoding>(context).in_set(ch_,chset);
return get_case_compare<encoding>(context).in_set(ch_, chset);
}
support::detail::basic_chset<char_type> chset;

View File

@@ -26,6 +26,10 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename TargetChar, typename SourceChar>
TargetChar cast_char(SourceChar ch)
{
#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 (is_signed<SourceChar>::value)
@@ -46,6 +50,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
// source and target has same signedness
return TargetChar(ch); // just cast
}
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
}
}}}}

View File

@@ -23,16 +23,15 @@ namespace boost { namespace spirit { namespace x3
!is_same<unused_type, attribute_type>::value;
template <typename Char>
literal_char(Char ch)
constexpr literal_char(Char ch)
: ch(static_cast<char_type>(ch)) {}
template <typename Char, typename Context>
bool test(Char ch_, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
&& (get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0);
return get_case_compare<encoding>(context)(ch, char_type(ch_)) == 0;
}
char_type ch;
};

View File

@@ -20,7 +20,7 @@ namespace boost { namespace spirit { namespace x3
struct negated_char_parser :
char_parser<negated_char_parser<Positive>>
{
negated_char_parser(Positive const& positive)
constexpr negated_char_parser(Positive const& positive)
: positive(positive) {}
template <typename CharParam, typename Context>
@@ -33,14 +33,14 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Positive>
inline negated_char_parser<Positive>
constexpr negated_char_parser<Positive>
operator~(char_parser<Positive> const& cp)
{
return { cp.derived() };
}
template <typename Positive>
inline Positive const&
constexpr Positive const&
operator~(negated_char_parser<Positive> const& cp)
{
return cp.positive;

View File

@@ -96,46 +96,72 @@ namespace boost { namespace spirit { namespace x3
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
struct adlam_tag {};
struct caucasian_albanian_tag {};
struct ahom_tag {};
struct arabic_tag {};
struct imperial_aramaic_tag {};
struct armenian_tag {};
struct avestan_tag {};
struct balinese_tag {};
struct bamum_tag {};
struct bassa_vah_tag {};
struct batak_tag {};
struct bengali_tag {};
struct bhaiksuki_tag {};
struct bopomofo_tag {};
struct brahmi_tag {};
struct braille_tag {};
struct buginese_tag {};
struct buhid_tag {};
struct chakma_tag {};
struct canadian_aboriginal_tag {};
struct carian_tag {};
struct cham_tag {};
struct cherokee_tag {};
struct chorasmian_tag {};
struct coptic_tag {};
struct cypro_minoan_tag {};
struct cypriot_tag {};
struct cyrillic_tag {};
struct devanagari_tag {};
struct dives_akuru_tag {};
struct dogra_tag {};
struct deseret_tag {};
struct duployan_tag {};
struct egyptian_hieroglyphs_tag {};
struct elbasan_tag {};
struct elymaic_tag {};
struct ethiopic_tag {};
struct georgian_tag {};
struct glagolitic_tag {};
struct gunjala_gondi_tag {};
struct masaram_gondi_tag {};
struct gothic_tag {};
struct grantha_tag {};
struct greek_tag {};
struct gujarati_tag {};
struct gurmukhi_tag {};
struct hangul_tag {};
struct han_tag {};
struct hanunoo_tag {};
struct hatran_tag {};
struct hebrew_tag {};
struct hiragana_tag {};
struct anatolian_hieroglyphs_tag {};
struct pahawh_hmong_tag {};
struct nyiakeng_puachue_hmong_tag {};
struct katakana_or_hiragana_tag {};
struct old_hungarian_tag {};
struct old_italic_tag {};
struct javanese_tag {};
struct kayah_li_tag {};
struct katakana_tag {};
struct kawi_tag {};
struct kharoshthi_tag {};
struct khmer_tag {};
struct khojki_tag {};
struct khitan_small_script_tag {};
struct kannada_tag {};
struct kaithi_tag {};
struct tai_tham_tag {};
@@ -143,38 +169,75 @@ namespace boost { namespace spirit { namespace x3
struct latin_tag {};
struct lepcha_tag {};
struct limbu_tag {};
struct linear_a_tag {};
struct linear_b_tag {};
struct lisu_tag {};
struct lycian_tag {};
struct lydian_tag {};
struct mahajani_tag {};
struct makasar_tag {};
struct mandaic_tag {};
struct manichaean_tag {};
struct marchen_tag {};
struct medefaidrin_tag {};
struct mende_kikakui_tag {};
struct meroitic_cursive_tag {};
struct meroitic_hieroglyphs_tag {};
struct malayalam_tag {};
struct modi_tag {};
struct mongolian_tag {};
struct mro_tag {};
struct meetei_mayek_tag {};
struct multani_tag {};
struct myanmar_tag {};
struct nag_mundari_tag {};
struct nandinagari_tag {};
struct old_north_arabian_tag {};
struct nabataean_tag {};
struct newa_tag {};
struct nko_tag {};
struct nushu_tag {};
struct ogham_tag {};
struct ol_chiki_tag {};
struct old_turkic_tag {};
struct oriya_tag {};
struct osage_tag {};
struct osmanya_tag {};
struct old_uyghur_tag {};
struct palmyrene_tag {};
struct pau_cin_hau_tag {};
struct old_permic_tag {};
struct phags_pa_tag {};
struct inscriptional_pahlavi_tag {};
struct psalter_pahlavi_tag {};
struct phoenician_tag {};
struct miao_tag {};
struct inscriptional_parthian_tag {};
struct rejang_tag {};
struct hanifi_rohingya_tag {};
struct runic_tag {};
struct samaritan_tag {};
struct old_south_arabian_tag {};
struct saurashtra_tag {};
struct signwriting_tag {};
struct shavian_tag {};
struct sharada_tag {};
struct siddham_tag {};
struct khudawadi_tag {};
struct sinhala_tag {};
struct sogdian_tag {};
struct old_sogdian_tag {};
struct sora_sompeng_tag {};
struct soyombo_tag {};
struct sundanese_tag {};
struct syloti_nagri_tag {};
struct syriac_tag {};
struct tagbanwa_tag {};
struct takri_tag {};
struct tai_le_tag {};
struct new_tai_lue_tag {};
struct tamil_tag {};
struct tangut_tag {};
struct tai_viet_tag {};
struct telugu_tag {};
struct tifinagh_tag {};
@@ -182,11 +245,19 @@ namespace boost { namespace spirit { namespace x3
struct thaana_tag {};
struct thai_tag {};
struct tibetan_tag {};
struct tirhuta_tag {};
struct tangsa_tag {};
struct toto_tag {};
struct ugaritic_tag {};
struct vai_tag {};
struct vithkuqi_tag {};
struct warang_citi_tag {};
struct wancho_tag {};
struct old_persian_tag {};
struct cuneiform_tag {};
struct yezidi_tag {};
struct yi_tag {};
struct zanabazar_square_tag {};
struct inherited_tag {};
struct common_tag {};
struct unknown_tag {};
@@ -197,26 +268,26 @@ namespace boost { namespace spirit { namespace x3
typedef char_encoding::unicode encoding;
typedef char_encoding::unicode::char_type char_type;
#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is ##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is ##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is_##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is_##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
@@ -302,46 +373,72 @@ namespace boost { namespace spirit { namespace x3
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(adlam)
BOOST_SPIRIT_X3_CLASSIFY(caucasian_albanian)
BOOST_SPIRIT_X3_CLASSIFY(ahom)
BOOST_SPIRIT_X3_CLASSIFY(arabic)
BOOST_SPIRIT_X3_CLASSIFY(imperial_aramaic)
BOOST_SPIRIT_X3_CLASSIFY(armenian)
BOOST_SPIRIT_X3_CLASSIFY(avestan)
BOOST_SPIRIT_X3_CLASSIFY(balinese)
BOOST_SPIRIT_X3_CLASSIFY(bamum)
BOOST_SPIRIT_X3_CLASSIFY(bassa_vah)
BOOST_SPIRIT_X3_CLASSIFY(batak)
BOOST_SPIRIT_X3_CLASSIFY(bengali)
BOOST_SPIRIT_X3_CLASSIFY(bhaiksuki)
BOOST_SPIRIT_X3_CLASSIFY(bopomofo)
BOOST_SPIRIT_X3_CLASSIFY(brahmi)
BOOST_SPIRIT_X3_CLASSIFY(braille)
BOOST_SPIRIT_X3_CLASSIFY(buginese)
BOOST_SPIRIT_X3_CLASSIFY(buhid)
BOOST_SPIRIT_X3_CLASSIFY(chakma)
BOOST_SPIRIT_X3_CLASSIFY(canadian_aboriginal)
BOOST_SPIRIT_X3_CLASSIFY(carian)
BOOST_SPIRIT_X3_CLASSIFY(cham)
BOOST_SPIRIT_X3_CLASSIFY(cherokee)
BOOST_SPIRIT_X3_CLASSIFY(chorasmian)
BOOST_SPIRIT_X3_CLASSIFY(coptic)
BOOST_SPIRIT_X3_CLASSIFY(cypro_minoan)
BOOST_SPIRIT_X3_CLASSIFY(cypriot)
BOOST_SPIRIT_X3_CLASSIFY(cyrillic)
BOOST_SPIRIT_X3_CLASSIFY(devanagari)
BOOST_SPIRIT_X3_CLASSIFY(dives_akuru)
BOOST_SPIRIT_X3_CLASSIFY(dogra)
BOOST_SPIRIT_X3_CLASSIFY(deseret)
BOOST_SPIRIT_X3_CLASSIFY(duployan)
BOOST_SPIRIT_X3_CLASSIFY(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CLASSIFY(elbasan)
BOOST_SPIRIT_X3_CLASSIFY(elymaic)
BOOST_SPIRIT_X3_CLASSIFY(ethiopic)
BOOST_SPIRIT_X3_CLASSIFY(georgian)
BOOST_SPIRIT_X3_CLASSIFY(glagolitic)
BOOST_SPIRIT_X3_CLASSIFY(gunjala_gondi)
BOOST_SPIRIT_X3_CLASSIFY(masaram_gondi)
BOOST_SPIRIT_X3_CLASSIFY(gothic)
BOOST_SPIRIT_X3_CLASSIFY(grantha)
BOOST_SPIRIT_X3_CLASSIFY(greek)
BOOST_SPIRIT_X3_CLASSIFY(gujarati)
BOOST_SPIRIT_X3_CLASSIFY(gurmukhi)
BOOST_SPIRIT_X3_CLASSIFY(hangul)
BOOST_SPIRIT_X3_CLASSIFY(han)
BOOST_SPIRIT_X3_CLASSIFY(hanunoo)
BOOST_SPIRIT_X3_CLASSIFY(hatran)
BOOST_SPIRIT_X3_CLASSIFY(hebrew)
BOOST_SPIRIT_X3_CLASSIFY(hiragana)
BOOST_SPIRIT_X3_CLASSIFY(anatolian_hieroglyphs)
BOOST_SPIRIT_X3_CLASSIFY(pahawh_hmong)
BOOST_SPIRIT_X3_CLASSIFY(nyiakeng_puachue_hmong)
BOOST_SPIRIT_X3_CLASSIFY(katakana_or_hiragana)
BOOST_SPIRIT_X3_CLASSIFY(old_hungarian)
BOOST_SPIRIT_X3_CLASSIFY(old_italic)
BOOST_SPIRIT_X3_CLASSIFY(javanese)
BOOST_SPIRIT_X3_CLASSIFY(kayah_li)
BOOST_SPIRIT_X3_CLASSIFY(katakana)
BOOST_SPIRIT_X3_CLASSIFY(kawi)
BOOST_SPIRIT_X3_CLASSIFY(kharoshthi)
BOOST_SPIRIT_X3_CLASSIFY(khmer)
BOOST_SPIRIT_X3_CLASSIFY(khojki)
BOOST_SPIRIT_X3_CLASSIFY(khitan_small_script)
BOOST_SPIRIT_X3_CLASSIFY(kannada)
BOOST_SPIRIT_X3_CLASSIFY(kaithi)
BOOST_SPIRIT_X3_CLASSIFY(tai_tham)
@@ -349,38 +446,75 @@ namespace boost { namespace spirit { namespace x3
BOOST_SPIRIT_X3_CLASSIFY(latin)
BOOST_SPIRIT_X3_CLASSIFY(lepcha)
BOOST_SPIRIT_X3_CLASSIFY(limbu)
BOOST_SPIRIT_X3_CLASSIFY(linear_a)
BOOST_SPIRIT_X3_CLASSIFY(linear_b)
BOOST_SPIRIT_X3_CLASSIFY(lisu)
BOOST_SPIRIT_X3_CLASSIFY(lycian)
BOOST_SPIRIT_X3_CLASSIFY(lydian)
BOOST_SPIRIT_X3_CLASSIFY(mahajani)
BOOST_SPIRIT_X3_CLASSIFY(makasar)
BOOST_SPIRIT_X3_CLASSIFY(mandaic)
BOOST_SPIRIT_X3_CLASSIFY(manichaean)
BOOST_SPIRIT_X3_CLASSIFY(marchen)
BOOST_SPIRIT_X3_CLASSIFY(medefaidrin)
BOOST_SPIRIT_X3_CLASSIFY(mende_kikakui)
BOOST_SPIRIT_X3_CLASSIFY(meroitic_cursive)
BOOST_SPIRIT_X3_CLASSIFY(meroitic_hieroglyphs)
BOOST_SPIRIT_X3_CLASSIFY(malayalam)
BOOST_SPIRIT_X3_CLASSIFY(modi)
BOOST_SPIRIT_X3_CLASSIFY(mongolian)
BOOST_SPIRIT_X3_CLASSIFY(mro)
BOOST_SPIRIT_X3_CLASSIFY(meetei_mayek)
BOOST_SPIRIT_X3_CLASSIFY(multani)
BOOST_SPIRIT_X3_CLASSIFY(myanmar)
BOOST_SPIRIT_X3_CLASSIFY(nag_mundari)
BOOST_SPIRIT_X3_CLASSIFY(nandinagari)
BOOST_SPIRIT_X3_CLASSIFY(old_north_arabian)
BOOST_SPIRIT_X3_CLASSIFY(nabataean)
BOOST_SPIRIT_X3_CLASSIFY(newa)
BOOST_SPIRIT_X3_CLASSIFY(nko)
BOOST_SPIRIT_X3_CLASSIFY(nushu)
BOOST_SPIRIT_X3_CLASSIFY(ogham)
BOOST_SPIRIT_X3_CLASSIFY(ol_chiki)
BOOST_SPIRIT_X3_CLASSIFY(old_turkic)
BOOST_SPIRIT_X3_CLASSIFY(oriya)
BOOST_SPIRIT_X3_CLASSIFY(osage)
BOOST_SPIRIT_X3_CLASSIFY(osmanya)
BOOST_SPIRIT_X3_CLASSIFY(old_uyghur)
BOOST_SPIRIT_X3_CLASSIFY(palmyrene)
BOOST_SPIRIT_X3_CLASSIFY(pau_cin_hau)
BOOST_SPIRIT_X3_CLASSIFY(old_permic)
BOOST_SPIRIT_X3_CLASSIFY(phags_pa)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CLASSIFY(psalter_pahlavi)
BOOST_SPIRIT_X3_CLASSIFY(phoenician)
BOOST_SPIRIT_X3_CLASSIFY(miao)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_parthian)
BOOST_SPIRIT_X3_CLASSIFY(rejang)
BOOST_SPIRIT_X3_CLASSIFY(hanifi_rohingya)
BOOST_SPIRIT_X3_CLASSIFY(runic)
BOOST_SPIRIT_X3_CLASSIFY(samaritan)
BOOST_SPIRIT_X3_CLASSIFY(old_south_arabian)
BOOST_SPIRIT_X3_CLASSIFY(saurashtra)
BOOST_SPIRIT_X3_CLASSIFY(signwriting)
BOOST_SPIRIT_X3_CLASSIFY(shavian)
BOOST_SPIRIT_X3_CLASSIFY(sharada)
BOOST_SPIRIT_X3_CLASSIFY(siddham)
BOOST_SPIRIT_X3_CLASSIFY(khudawadi)
BOOST_SPIRIT_X3_CLASSIFY(sinhala)
BOOST_SPIRIT_X3_CLASSIFY(sogdian)
BOOST_SPIRIT_X3_CLASSIFY(old_sogdian)
BOOST_SPIRIT_X3_CLASSIFY(sora_sompeng)
BOOST_SPIRIT_X3_CLASSIFY(soyombo)
BOOST_SPIRIT_X3_CLASSIFY(sundanese)
BOOST_SPIRIT_X3_CLASSIFY(syloti_nagri)
BOOST_SPIRIT_X3_CLASSIFY(syriac)
BOOST_SPIRIT_X3_CLASSIFY(tagbanwa)
BOOST_SPIRIT_X3_CLASSIFY(takri)
BOOST_SPIRIT_X3_CLASSIFY(tai_le)
BOOST_SPIRIT_X3_CLASSIFY(new_tai_lue)
BOOST_SPIRIT_X3_CLASSIFY(tamil)
BOOST_SPIRIT_X3_CLASSIFY(tangut)
BOOST_SPIRIT_X3_CLASSIFY(tai_viet)
BOOST_SPIRIT_X3_CLASSIFY(telugu)
BOOST_SPIRIT_X3_CLASSIFY(tifinagh)
@@ -388,11 +522,19 @@ namespace boost { namespace spirit { namespace x3
BOOST_SPIRIT_X3_CLASSIFY(thaana)
BOOST_SPIRIT_X3_CLASSIFY(thai)
BOOST_SPIRIT_X3_CLASSIFY(tibetan)
BOOST_SPIRIT_X3_CLASSIFY(tirhuta)
BOOST_SPIRIT_X3_CLASSIFY(tangsa)
BOOST_SPIRIT_X3_CLASSIFY(toto)
BOOST_SPIRIT_X3_CLASSIFY(ugaritic)
BOOST_SPIRIT_X3_CLASSIFY(vai)
BOOST_SPIRIT_X3_CLASSIFY(vithkuqi)
BOOST_SPIRIT_X3_CLASSIFY(warang_citi)
BOOST_SPIRIT_X3_CLASSIFY(wancho)
BOOST_SPIRIT_X3_CLASSIFY(old_persian)
BOOST_SPIRIT_X3_CLASSIFY(cuneiform)
BOOST_SPIRIT_X3_CLASSIFY(yezidi)
BOOST_SPIRIT_X3_CLASSIFY(yi)
BOOST_SPIRIT_X3_CLASSIFY(zanabazar_square)
BOOST_SPIRIT_X3_CLASSIFY(inherited)
BOOST_SPIRIT_X3_CLASSIFY(common)
BOOST_SPIRIT_X3_CLASSIFY(unknown)
@@ -414,20 +556,19 @@ namespace boost { namespace spirit { namespace x3
template <typename Char, typename Context>
bool test(Char ch, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || 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) \
typedef unicode_char_class<name##_tag> name##_type; \
name##_type const name = name##_type(); \
#define BOOST_SPIRIT_X3_CHAR_CLASS(name) \
typedef unicode_char_class<name##_tag> name##_type; \
constexpr name##_type name = name##_type(); \
/***/
namespace unicode
{
typedef any_char<char_encoding::unicode> char_type;
auto const char_ = char_type{};
constexpr auto char_ = char_type{};
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
@@ -510,46 +651,72 @@ namespace boost { namespace spirit { namespace x3
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(adlam)
BOOST_SPIRIT_X3_CHAR_CLASS(caucasian_albanian)
BOOST_SPIRIT_X3_CHAR_CLASS(ahom)
BOOST_SPIRIT_X3_CHAR_CLASS(arabic)
BOOST_SPIRIT_X3_CHAR_CLASS(imperial_aramaic)
BOOST_SPIRIT_X3_CHAR_CLASS(armenian)
BOOST_SPIRIT_X3_CHAR_CLASS(avestan)
BOOST_SPIRIT_X3_CHAR_CLASS(balinese)
BOOST_SPIRIT_X3_CHAR_CLASS(bamum)
BOOST_SPIRIT_X3_CHAR_CLASS(bassa_vah)
BOOST_SPIRIT_X3_CHAR_CLASS(batak)
BOOST_SPIRIT_X3_CHAR_CLASS(bengali)
BOOST_SPIRIT_X3_CHAR_CLASS(bhaiksuki)
BOOST_SPIRIT_X3_CHAR_CLASS(bopomofo)
BOOST_SPIRIT_X3_CHAR_CLASS(brahmi)
BOOST_SPIRIT_X3_CHAR_CLASS(braille)
BOOST_SPIRIT_X3_CHAR_CLASS(buginese)
BOOST_SPIRIT_X3_CHAR_CLASS(buhid)
BOOST_SPIRIT_X3_CHAR_CLASS(chakma)
BOOST_SPIRIT_X3_CHAR_CLASS(canadian_aboriginal)
BOOST_SPIRIT_X3_CHAR_CLASS(carian)
BOOST_SPIRIT_X3_CHAR_CLASS(cham)
BOOST_SPIRIT_X3_CHAR_CLASS(cherokee)
BOOST_SPIRIT_X3_CHAR_CLASS(chorasmian)
BOOST_SPIRIT_X3_CHAR_CLASS(coptic)
BOOST_SPIRIT_X3_CHAR_CLASS(cypro_minoan)
BOOST_SPIRIT_X3_CHAR_CLASS(cypriot)
BOOST_SPIRIT_X3_CHAR_CLASS(cyrillic)
BOOST_SPIRIT_X3_CHAR_CLASS(devanagari)
BOOST_SPIRIT_X3_CHAR_CLASS(dives_akuru)
BOOST_SPIRIT_X3_CHAR_CLASS(dogra)
BOOST_SPIRIT_X3_CHAR_CLASS(deseret)
BOOST_SPIRIT_X3_CHAR_CLASS(duployan)
BOOST_SPIRIT_X3_CHAR_CLASS(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CHAR_CLASS(elbasan)
BOOST_SPIRIT_X3_CHAR_CLASS(elymaic)
BOOST_SPIRIT_X3_CHAR_CLASS(ethiopic)
BOOST_SPIRIT_X3_CHAR_CLASS(georgian)
BOOST_SPIRIT_X3_CHAR_CLASS(glagolitic)
BOOST_SPIRIT_X3_CHAR_CLASS(gunjala_gondi)
BOOST_SPIRIT_X3_CHAR_CLASS(masaram_gondi)
BOOST_SPIRIT_X3_CHAR_CLASS(gothic)
BOOST_SPIRIT_X3_CHAR_CLASS(grantha)
BOOST_SPIRIT_X3_CHAR_CLASS(greek)
BOOST_SPIRIT_X3_CHAR_CLASS(gujarati)
BOOST_SPIRIT_X3_CHAR_CLASS(gurmukhi)
BOOST_SPIRIT_X3_CHAR_CLASS(hangul)
BOOST_SPIRIT_X3_CHAR_CLASS(han)
BOOST_SPIRIT_X3_CHAR_CLASS(hanunoo)
BOOST_SPIRIT_X3_CHAR_CLASS(hatran)
BOOST_SPIRIT_X3_CHAR_CLASS(hebrew)
BOOST_SPIRIT_X3_CHAR_CLASS(hiragana)
BOOST_SPIRIT_X3_CHAR_CLASS(anatolian_hieroglyphs)
BOOST_SPIRIT_X3_CHAR_CLASS(pahawh_hmong)
BOOST_SPIRIT_X3_CHAR_CLASS(nyiakeng_puachue_hmong)
BOOST_SPIRIT_X3_CHAR_CLASS(katakana_or_hiragana)
BOOST_SPIRIT_X3_CHAR_CLASS(old_hungarian)
BOOST_SPIRIT_X3_CHAR_CLASS(old_italic)
BOOST_SPIRIT_X3_CHAR_CLASS(javanese)
BOOST_SPIRIT_X3_CHAR_CLASS(kayah_li)
BOOST_SPIRIT_X3_CHAR_CLASS(katakana)
BOOST_SPIRIT_X3_CHAR_CLASS(kawi)
BOOST_SPIRIT_X3_CHAR_CLASS(kharoshthi)
BOOST_SPIRIT_X3_CHAR_CLASS(khmer)
BOOST_SPIRIT_X3_CHAR_CLASS(khojki)
BOOST_SPIRIT_X3_CHAR_CLASS(khitan_small_script)
BOOST_SPIRIT_X3_CHAR_CLASS(kannada)
BOOST_SPIRIT_X3_CHAR_CLASS(kaithi)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_tham)
@@ -557,38 +724,75 @@ namespace boost { namespace spirit { namespace x3
BOOST_SPIRIT_X3_CHAR_CLASS(latin)
BOOST_SPIRIT_X3_CHAR_CLASS(lepcha)
BOOST_SPIRIT_X3_CHAR_CLASS(limbu)
BOOST_SPIRIT_X3_CHAR_CLASS(linear_a)
BOOST_SPIRIT_X3_CHAR_CLASS(linear_b)
BOOST_SPIRIT_X3_CHAR_CLASS(lisu)
BOOST_SPIRIT_X3_CHAR_CLASS(lycian)
BOOST_SPIRIT_X3_CHAR_CLASS(lydian)
BOOST_SPIRIT_X3_CHAR_CLASS(mahajani)
BOOST_SPIRIT_X3_CHAR_CLASS(makasar)
BOOST_SPIRIT_X3_CHAR_CLASS(mandaic)
BOOST_SPIRIT_X3_CHAR_CLASS(manichaean)
BOOST_SPIRIT_X3_CHAR_CLASS(marchen)
BOOST_SPIRIT_X3_CHAR_CLASS(medefaidrin)
BOOST_SPIRIT_X3_CHAR_CLASS(mende_kikakui)
BOOST_SPIRIT_X3_CHAR_CLASS(meroitic_cursive)
BOOST_SPIRIT_X3_CHAR_CLASS(meroitic_hieroglyphs)
BOOST_SPIRIT_X3_CHAR_CLASS(malayalam)
BOOST_SPIRIT_X3_CHAR_CLASS(modi)
BOOST_SPIRIT_X3_CHAR_CLASS(mongolian)
BOOST_SPIRIT_X3_CHAR_CLASS(mro)
BOOST_SPIRIT_X3_CHAR_CLASS(meetei_mayek)
BOOST_SPIRIT_X3_CHAR_CLASS(multani)
BOOST_SPIRIT_X3_CHAR_CLASS(myanmar)
BOOST_SPIRIT_X3_CHAR_CLASS(nag_mundari)
BOOST_SPIRIT_X3_CHAR_CLASS(nandinagari)
BOOST_SPIRIT_X3_CHAR_CLASS(old_north_arabian)
BOOST_SPIRIT_X3_CHAR_CLASS(nabataean)
BOOST_SPIRIT_X3_CHAR_CLASS(newa)
BOOST_SPIRIT_X3_CHAR_CLASS(nko)
BOOST_SPIRIT_X3_CHAR_CLASS(nushu)
BOOST_SPIRIT_X3_CHAR_CLASS(ogham)
BOOST_SPIRIT_X3_CHAR_CLASS(ol_chiki)
BOOST_SPIRIT_X3_CHAR_CLASS(old_turkic)
BOOST_SPIRIT_X3_CHAR_CLASS(oriya)
BOOST_SPIRIT_X3_CHAR_CLASS(osage)
BOOST_SPIRIT_X3_CHAR_CLASS(osmanya)
BOOST_SPIRIT_X3_CHAR_CLASS(old_uyghur)
BOOST_SPIRIT_X3_CHAR_CLASS(palmyrene)
BOOST_SPIRIT_X3_CHAR_CLASS(pau_cin_hau)
BOOST_SPIRIT_X3_CHAR_CLASS(old_permic)
BOOST_SPIRIT_X3_CHAR_CLASS(phags_pa)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CHAR_CLASS(psalter_pahlavi)
BOOST_SPIRIT_X3_CHAR_CLASS(phoenician)
BOOST_SPIRIT_X3_CHAR_CLASS(miao)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_parthian)
BOOST_SPIRIT_X3_CHAR_CLASS(rejang)
BOOST_SPIRIT_X3_CHAR_CLASS(hanifi_rohingya)
BOOST_SPIRIT_X3_CHAR_CLASS(runic)
BOOST_SPIRIT_X3_CHAR_CLASS(samaritan)
BOOST_SPIRIT_X3_CHAR_CLASS(old_south_arabian)
BOOST_SPIRIT_X3_CHAR_CLASS(saurashtra)
BOOST_SPIRIT_X3_CHAR_CLASS(signwriting)
BOOST_SPIRIT_X3_CHAR_CLASS(shavian)
BOOST_SPIRIT_X3_CHAR_CLASS(sharada)
BOOST_SPIRIT_X3_CHAR_CLASS(siddham)
BOOST_SPIRIT_X3_CHAR_CLASS(khudawadi)
BOOST_SPIRIT_X3_CHAR_CLASS(sinhala)
BOOST_SPIRIT_X3_CHAR_CLASS(sogdian)
BOOST_SPIRIT_X3_CHAR_CLASS(old_sogdian)
BOOST_SPIRIT_X3_CHAR_CLASS(sora_sompeng)
BOOST_SPIRIT_X3_CHAR_CLASS(soyombo)
BOOST_SPIRIT_X3_CHAR_CLASS(sundanese)
BOOST_SPIRIT_X3_CHAR_CLASS(syloti_nagri)
BOOST_SPIRIT_X3_CHAR_CLASS(syriac)
BOOST_SPIRIT_X3_CHAR_CLASS(tagbanwa)
BOOST_SPIRIT_X3_CHAR_CLASS(takri)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_le)
BOOST_SPIRIT_X3_CHAR_CLASS(new_tai_lue)
BOOST_SPIRIT_X3_CHAR_CLASS(tamil)
BOOST_SPIRIT_X3_CHAR_CLASS(tangut)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_viet)
BOOST_SPIRIT_X3_CHAR_CLASS(telugu)
BOOST_SPIRIT_X3_CHAR_CLASS(tifinagh)
@@ -596,11 +800,19 @@ namespace boost { namespace spirit { namespace x3
BOOST_SPIRIT_X3_CHAR_CLASS(thaana)
BOOST_SPIRIT_X3_CHAR_CLASS(thai)
BOOST_SPIRIT_X3_CHAR_CLASS(tibetan)
BOOST_SPIRIT_X3_CHAR_CLASS(tirhuta)
BOOST_SPIRIT_X3_CHAR_CLASS(tangsa)
BOOST_SPIRIT_X3_CHAR_CLASS(toto)
BOOST_SPIRIT_X3_CHAR_CLASS(ugaritic)
BOOST_SPIRIT_X3_CHAR_CLASS(vai)
BOOST_SPIRIT_X3_CHAR_CLASS(vithkuqi)
BOOST_SPIRIT_X3_CHAR_CLASS(warang_citi)
BOOST_SPIRIT_X3_CHAR_CLASS(wancho)
BOOST_SPIRIT_X3_CHAR_CLASS(old_persian)
BOOST_SPIRIT_X3_CHAR_CLASS(cuneiform)
BOOST_SPIRIT_X3_CHAR_CLASS(yezidi)
BOOST_SPIRIT_X3_CHAR_CLASS(yi)
BOOST_SPIRIT_X3_CHAR_CLASS(zanabazar_square)
BOOST_SPIRIT_X3_CHAR_CLASS(inherited)
BOOST_SPIRIT_X3_CHAR_CLASS(common)
BOOST_SPIRIT_X3_CHAR_CLASS(unknown)

View File

@@ -1,5 +1,5 @@
/*=============================================================================
Copyright (arg) 2001-2014 Joel de Guzman
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)
@@ -11,7 +11,7 @@
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/call.hpp>
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/iterator_range_core.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -31,7 +31,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const has_action = true;
action(Subject const& subject, Action f)
constexpr action(Subject const& subject, Action f)
: base_type(subject), f(f) {}
template <typename Iterator, typename Context, typename RuleContext, typename Attribute>
@@ -83,8 +83,8 @@ namespace boost { namespace spirit { namespace x3
attribute_type;
// synthesize the attribute since one is not supplied
attribute_type attr{};
return parse_main(first, last, context, rcontext, attr);
attribute_type attribute{};
return parse_main(first, last, context, rcontext, attribute);
}
// main parse function
@@ -100,7 +100,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename P, typename Action>
inline action<typename extension::as_parser<P>::value_type, Action>
constexpr action<typename extension::as_parser<P>::value_type, Action>
operator/(P const& p, Action f)
{
return { as_parser(p), f };

View File

@@ -11,7 +11,7 @@
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/utility/is_callable.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/iterator_range_core.hpp>
namespace boost { namespace spirit { namespace x3
{

View File

@@ -10,8 +10,8 @@
#include <type_traits>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/value_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/pseudo_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/handles_container.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
@@ -91,10 +91,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
{
// synthesized attribute needs to be value initialized
typedef typename
traits::container_value<Attribute>::type
value_type;
value_type val = traits::value_initialize<value_type>::call();
using value_type = typename traits::container_value<Attribute>::type;
value_type val{};
if (!parser.parse(first, last, context, rcontext, val))
return false;
@@ -221,10 +219,14 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Parser, typename Context, typename RContext, typename Enable = void>
struct parse_into_container_impl : parse_into_container_base_impl<Parser> {};
template <typename Parser, typename Container, typename Context>
template <typename Parser, typename Iterator, typename Container, typename Context>
struct parser_attr_is_substitute_for_container_value
: traits::is_substitute<
typename traits::attribute_of<Parser, Context>::type
typename traits::pseudo_attribute<
Context
, typename traits::attribute_of<Parser, Context>::type
, Iterator
>::type
, typename traits::container_value<Container>::type
>
{};
@@ -278,7 +280,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
parser_accepts_container;
typedef parser_attr_is_substitute_for_container_value<
Parser, Attribute, Context>
Parser, Iterator, Attribute, Context>
parser_attr_is_substitute_for_container_value;
typedef mpl::or_<

View File

@@ -17,7 +17,6 @@
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/assert.hpp>
#include <string>
@@ -45,41 +44,24 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = false;
static bool const has_action = false;
Derived const& derived() const
constexpr Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
template <typename Action>
action<Derived, Action> operator[](Action f) const
constexpr action<Derived, Action> operator[](Action f) const
{
return { this->derived(), f };
}
template <typename Handler>
guard<Derived, Handler> on_error(Handler f) const
constexpr guard<Derived, Handler> on_error(Handler f) const
{
return { this->derived(), f };
}
};
namespace detail {
template <typename Parser>
static void assert_initialized_rule(Parser const& p) {
boost::ignore_unused(p);
// Assert that we are not copying an unitialized static rule. If
// the static is in another TU, it may be initialized after we copy
// it. If so, its name member will be nullptr.
//
// Rather than hardcoding behaviour for rule-type subject parsers,
// we simply allow get_info<> to do the check in debug builds.
#ifndef NDEBUG
what(p); // note: allows get_info<> to diagnose the issue
#endif
}
}
struct unary_category;
struct binary_category;
@@ -90,8 +72,8 @@ namespace boost { namespace spirit { namespace x3
typedef Subject subject_type;
static bool const has_action = Subject::has_action;
unary_parser(Subject const& subject)
: subject(subject) { detail::assert_initialized_rule(subject); }
constexpr unary_parser(Subject const& subject)
: subject(subject) {}
unary_parser const& get_unary() const { return *this; }
@@ -107,12 +89,8 @@ namespace boost { namespace spirit { namespace x3
static bool const has_action =
left_type::has_action || right_type::has_action;
binary_parser(Left const& left, Right const& right)
: left(left), right(right)
{
detail::assert_initialized_rule(left);
detail::assert_initialized_rule(right);
}
constexpr binary_parser(Left const& left, Right const& right)
: left(left), right(right) {}
binary_parser const& get_binary() const { return *this; }
@@ -162,7 +140,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef unused_type type;
typedef unused_type value_type;
static type call(unused_type)
static constexpr type call(unused_type)
{
return unused;
}
@@ -174,7 +152,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef Derived const& type;
typedef Derived value_type;
static type call(Derived const& p)
static constexpr type call(Derived const& p)
{
return p;
}
@@ -185,7 +163,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef Derived const& type;
typedef Derived value_type;
static type call(parser<Derived> const& p)
static constexpr type call(parser<Derived> const& p)
{
return p.derived();
}
@@ -193,14 +171,14 @@ namespace boost { namespace spirit { namespace x3
}
template <typename T>
inline typename extension::as_parser<T>::type
constexpr typename extension::as_parser<T>::type
as_parser(T const& x)
{
return extension::as_parser<T>::call(x);
}
template <typename Derived>
inline Derived const&
constexpr Derived const&
as_parser(parser<Derived> const& p)
{
return p.derived();

View File

@@ -18,7 +18,7 @@ namespace boost { namespace spirit { namespace x3
{
static bool const is_pass_through_unary = true;
proxy(Subject const& subject)
constexpr proxy(Subject const& subject)
: unary_parser<Subject, Derived>(subject) {}
// Overload this when appropriate. The proxy parser will pick up

View File

@@ -22,7 +22,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
confix_directive(Prefix const& prefix
constexpr confix_directive(Prefix const& prefix
, Subject const& subject
, Postfix const& postfix) :
base_type(subject),
@@ -58,7 +58,7 @@ namespace boost { namespace spirit { namespace x3
struct confix_gen
{
template<typename Subject>
confix_directive<
constexpr confix_directive<
Prefix, typename extension::as_parser<Subject>::value_type, Postfix>
operator[](Subject const& subject) const
{
@@ -71,7 +71,7 @@ namespace boost { namespace spirit { namespace x3
template<typename Prefix, typename Postfix>
confix_gen<typename extension::as_parser<Prefix>::value_type,
constexpr confix_gen<typename extension::as_parser<Prefix>::value_type,
typename extension::as_parser<Postfix>::value_type>
confix(Prefix const& prefix, Postfix const& postfix)
{

View File

@@ -43,7 +43,7 @@ namespace boost { namespace spirit { namespace x3
typedef unary_parser<Subject, expect_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
expect_directive(Subject const& subject)
constexpr expect_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -66,14 +66,14 @@ namespace boost { namespace spirit { namespace x3
struct expect_gen
{
template <typename Subject>
expect_directive<typename extension::as_parser<Subject>::value_type>
constexpr expect_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const expect = expect_gen{};
constexpr auto expect = expect_gen{};
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail

View File

@@ -23,7 +23,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
lexeme_directive(Subject const& subject)
constexpr lexeme_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -65,14 +65,14 @@ namespace boost { namespace spirit { namespace x3
struct lexeme_gen
{
template <typename Subject>
lexeme_directive<typename extension::as_parser<Subject>::value_type>
constexpr lexeme_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const lexeme = lexeme_gen{};
constexpr auto lexeme = lexeme_gen{};
}}}
#endif

View File

@@ -21,7 +21,7 @@ namespace boost { namespace spirit { namespace x3
static bool const has_attribute = true;
using attribute_type = bool;
matches_directive(Subject const& subject) : base_type(subject) {}
constexpr matches_directive(Subject const& subject) : base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
@@ -38,14 +38,14 @@ namespace boost { namespace spirit { namespace x3
struct matches_gen
{
template <typename Subject>
matches_directive<typename extension::as_parser<Subject>::value_type>
constexpr matches_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const matches = matches_gen{};
constexpr auto matches = matches_gen{};
}}}
#endif

View File

@@ -22,7 +22,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
no_case_directive(Subject const& subject)
constexpr no_case_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -41,14 +41,14 @@ namespace boost { namespace spirit { namespace x3
struct no_case_gen
{
template <typename Subject>
no_case_directive<typename extension::as_parser<Subject>::value_type>
constexpr no_case_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const no_case = no_case_gen{};
constexpr auto no_case = no_case_gen{};
}}}
#endif

View File

@@ -26,7 +26,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
no_skip_directive(Subject const& subject)
constexpr no_skip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -65,14 +65,14 @@ namespace boost { namespace spirit { namespace x3
struct no_skip_gen
{
template <typename Subject>
no_skip_directive<typename extension::as_parser<Subject>::value_type>
constexpr no_skip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const no_skip = no_skip_gen{};
constexpr auto no_skip = no_skip_gen{};
}}}
#endif

View File

@@ -24,7 +24,7 @@ namespace boost { namespace spirit { namespace x3
static bool const has_attribute = false;
typedef Subject subject_type;
omit_directive(Subject const& subject)
constexpr omit_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename RContext>
@@ -38,14 +38,14 @@ namespace boost { namespace spirit { namespace x3
struct omit_gen
{
template <typename Subject>
omit_directive<typename extension::as_parser<Subject>::value_type>
constexpr omit_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const omit = omit_gen{};
constexpr auto omit = omit_gen{};
}}}
#endif

View File

@@ -4,13 +4,14 @@
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(SPIRIT_X3_RAW_APRIL_9_2007_0912AM)
#define SPIRIT_X3_RAW_APRIL_9_2007_0912AM
#ifndef BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP
#define BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/spirit/home/x3/support/traits/pseudo_attribute.hpp>
#include <boost/range/iterator_range_core.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -24,10 +25,10 @@ namespace boost { namespace spirit { namespace x3
{
typedef unary_parser<Subject, raw_directive<Subject> > base_type;
typedef raw_attribute_type attribute_type;
static bool const handles_container = Subject::handles_container;
static bool const handles_container = true;
typedef Subject subject_type;
raw_directive(Subject const& subject)
constexpr raw_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -57,14 +58,29 @@ namespace boost { namespace spirit { namespace x3
struct raw_gen
{
template <typename Subject>
raw_directive<typename extension::as_parser<Subject>::value_type>
constexpr raw_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const raw = raw_gen{};
constexpr auto raw = raw_gen{};
namespace traits
{
template <typename Context, typename Iterator>
struct pseudo_attribute<Context, raw_attribute_type, Iterator>
{
using attribute_type = raw_attribute_type;
using type = boost::iterator_range<Iterator>;
static type call(Iterator& first, Iterator const& last, attribute_type)
{
return { first, last };
}
};
}
}}}
#endif

View File

@@ -6,8 +6,8 @@
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(SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM)
#define SPIRIT_X3_REPEAT_APRIL_16_2014_0848AM
#ifndef BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
#define BOOST_SPIRIT_X3_DIRECTIVE_REPEAT_HPP
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/kleene.hpp>
@@ -55,7 +55,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = true;
repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
constexpr repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
: base_type(subject)
, repeat_limit(repeat_limit_)
{}
@@ -91,12 +91,12 @@ namespace boost { namespace spirit { namespace x3
// Infinite loop tag type
struct inf_type {};
const inf_type inf = inf_type();
constexpr inf_type inf = inf_type();
struct repeat_gen
{
template<typename Subject>
auto operator[](Subject const& subject) const
constexpr auto operator[](Subject const& subject) const
{
return *as_parser(subject);
}
@@ -104,12 +104,12 @@ namespace boost { namespace spirit { namespace x3
template <typename T>
struct repeat_gen_lvl1
{
repeat_gen_lvl1(T&& repeat_limit_)
constexpr repeat_gen_lvl1(T&& repeat_limit_)
: repeat_limit(repeat_limit_)
{}
template<typename Subject>
repeat_directive< typename extension::as_parser<Subject>::value_type, T>
constexpr repeat_directive< typename extension::as_parser<Subject>::value_type, T>
operator[](Subject const& subject) const
{
return { as_parser(subject),repeat_limit };
@@ -119,28 +119,28 @@ namespace boost { namespace spirit { namespace x3
};
template <typename T>
repeat_gen_lvl1<detail::exact_count<T>>
constexpr repeat_gen_lvl1<detail::exact_count<T>>
operator()(T const exact) const
{
return { detail::exact_count<T>{exact} };
}
template <typename T>
repeat_gen_lvl1<detail::finite_count<T>>
constexpr repeat_gen_lvl1<detail::finite_count<T>>
operator()(T const min_val, T const max_val) const
{
return { detail::finite_count<T>{min_val,max_val} };
}
template <typename T>
repeat_gen_lvl1<detail::infinite_count<T>>
constexpr repeat_gen_lvl1<detail::infinite_count<T>>
operator()(T const min_val, inf_type const &) const
{
return { detail::infinite_count<T>{min_val} };
}
};
auto const repeat = repeat_gen{};
constexpr auto repeat = repeat_gen{};
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits

View File

@@ -19,7 +19,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
seek_directive(Subject const& subject) :
constexpr seek_directive(Subject const& subject) :
base_type(subject) {}
template<typename Iterator, typename Context
@@ -28,39 +28,32 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator current(first);
for (/**/; current != last; ++current)
for (Iterator current(first);; ++current)
{
if (this->subject.parse(current, last, context, rcontext, attr))
{
first = current;
return true;
}
}
// Test for when subjects match on input empty. Example:
// comment = "//" >> seek[eol | eoi]
if (this->subject.parse(current, last, context, rcontext, attr))
{
first = current;
return true;
// fail only after subject fails & no input
if (current == last)
return false;
}
return false;
}
};
struct seek_gen
{
template<typename Subject>
seek_directive<typename extension::as_parser<Subject>::value_type>
constexpr seek_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const seek = seek_gen{};
constexpr auto seek = seek_gen{};
}}}
#endif

View File

@@ -23,7 +23,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
reskip_directive(Subject const& subject)
constexpr reskip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -62,7 +62,7 @@ namespace boost { namespace spirit { namespace x3
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
skip_directive(Subject const& subject, Skipper const& skipper)
constexpr skip_directive(Subject const& subject, Skipper const& skipper)
: base_type(subject)
, skipper(skipper)
{}
@@ -87,11 +87,11 @@ namespace boost { namespace spirit { namespace x3
template <typename Skipper>
struct skip_gen
{
skip_gen(Skipper const& skipper)
constexpr skip_gen(Skipper const& skipper)
: skipper_(skipper) {}
template <typename Subject>
skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
constexpr skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
operator[](Subject const& subject) const
{
return { as_parser(subject), skipper_ };
@@ -101,20 +101,20 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Skipper>
skip_gen<Skipper> const operator()(Skipper const& skipper) const
constexpr skip_gen<Skipper> const operator()(Skipper const& skipper) const
{
return { skipper };
}
template <typename Subject>
reskip_directive<typename extension::as_parser<Subject>::value_type>
constexpr reskip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const skip = reskip_gen{};
constexpr auto skip = reskip_gen{};
}}}
#endif

View File

@@ -4,8 +4,8 @@
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(SPIRIT_X3_WITH_MAY_02_2014_0749AM)
#define SPIRIT_X3_WITH_MAY_02_2014_0749AM
#ifndef BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP
#define BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
@@ -21,7 +21,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef unary_parser<Subject, Derived> base_type;
mutable T val;
with_value_holder(Subject const& subject, T&& val)
constexpr with_value_holder(Subject const& subject, T&& val)
: base_type(subject)
, val(std::forward<T>(val)) {}
};
@@ -32,7 +32,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef unary_parser<Subject, Derived> base_type;
T& val;
with_value_holder(Subject const& subject, T& val)
constexpr with_value_holder(Subject const& subject, T& val)
: base_type(subject)
, val(val) {}
};
@@ -47,7 +47,7 @@ namespace boost { namespace spirit { namespace x3
typedef Subject subject_type;
with_directive(Subject const& subject, T&& val)
constexpr with_directive(Subject const& subject, T&& val)
: base_type(subject, std::forward<T>(val)) {}
template <typename Iterator, typename Context
@@ -69,7 +69,7 @@ namespace boost { namespace spirit { namespace x3
T&& val;
template <typename Subject>
with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
constexpr with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
operator[](Subject const& subject) const
{
return { as_parser(subject), std::forward<T>(val) };
@@ -77,7 +77,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename ID, typename T>
inline with_gen<ID, T> with(T&& val)
constexpr with_gen<ID, T> with(T&& val)
{
return { std::forward<T>(val) };
}

View File

@@ -12,7 +12,6 @@
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
#include <boost/utility/addressof.hpp>
@@ -20,6 +19,8 @@
#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
#endif
#include <type_traits>
namespace boost { namespace spirit { namespace x3
{
template <typename ID>
@@ -32,6 +33,9 @@ namespace boost { namespace spirit { namespace x3
namespace detail
{
template <typename ID>
struct rule_id {};
// we use this so we can detect if the default parse_rule
// is the being called.
struct default_parse_rule_result
@@ -44,11 +48,11 @@ namespace boost { namespace spirit { namespace x3
}
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
template <typename ID, typename Iterator
, typename Context, typename ActualAttribute>
inline detail::default_parse_rule_result
parse_rule(
rule<ID, Attribute> rule_
detail::rule_id<ID>
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr);
}}}
@@ -93,15 +97,14 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename ID, typename Iterator, typename Context>
struct has_on_error<ID, Iterator, Context,
typename disable_if_substitution_failure<
decltype(
decltype(void(
std::declval<ID>().on_error(
std::declval<Iterator&>()
, std::declval<Iterator>()
, std::declval<expectation_failure<Iterator>>()
, std::declval<Context>()
)
)>::type
))
>
: mpl::true_
{};
@@ -111,15 +114,14 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename ID, typename Iterator, typename Attribute, typename Context>
struct has_on_success<ID, Iterator, Context, Attribute,
typename disable_if_substitution_failure<
decltype(
decltype(void(
std::declval<ID>().on_success(
std::declval<Iterator&>()
, std::declval<Iterator>()
, std::declval<Iterator&>()
, std::declval<Attribute&>()
, std::declval<Context>()
)
)>::type
))
>
: mpl::true_
{};
@@ -151,12 +153,12 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
return make_unique_context<ID>(rhs, context);
}
template <typename Attribute, typename ID>
template <typename Attribute, typename ID, bool skip_definition_injection = false>
struct rule_parser
{
template <typename Iterator, typename Context, typename ActualAttribute>
static bool call_on_success(
Iterator& /* first */, Iterator const& /* last */
Iterator& /* before */, Iterator& /* after */
, Context const& /* context */, ActualAttribute& /* attr */
, mpl::false_ /* No on_success handler */ )
{
@@ -165,14 +167,15 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Iterator, typename Context, typename ActualAttribute>
static bool call_on_success(
Iterator& first, Iterator const& last
Iterator& before, Iterator& after
, Context const& context, ActualAttribute& attr
, mpl::true_ /* Has on_success handler */)
{
x3::skip_over(before, after, context);
bool pass = true;
ID().on_success(
first
, last
before
, after
, attr
, make_context<parse_pass_context_tag>(pass, context)
);
@@ -190,8 +193,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
// see if the user has a BOOST_SPIRIT_DEFINE for this rule
typedef
decltype(parse_rule(
rule<ID, Attribute>(), first, last
, make_unique_context<ID>(rhs, context), attr))
detail::rule_id<ID>{}, first, last
, make_unique_context<ID>(rhs, context), std::declval<Attribute&>()))
parse_rule_result;
// If there is no BOOST_SPIRIT_DEFINE for this rule,
@@ -202,25 +205,21 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
is_same<parse_rule_result, default_parse_rule_result>
is_default_parse_rule;
Iterator i = first;
Iterator start = first;
bool r = rhs.parse(
i
first
, last
, make_rule_context<ID>(rhs, context, is_default_parse_rule())
, make_rule_context<ID>(rhs, context, std::conditional_t<skip_definition_injection, mpl::false_, is_default_parse_rule>())
, rcontext
, attr
);
if (r)
{
auto first_ = first;
x3::skip_over(first_, last, context);
r = call_on_success(first_, i, context, attr
r = call_on_success(start, first, context, attr
, has_on_success<ID, Iterator, Context, ActualAttribute>());
}
if (r)
first = i;
return r;
}

View File

@@ -5,8 +5,8 @@
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(SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
#define SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
#ifndef BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
#define BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
@@ -25,9 +25,9 @@ namespace boost { namespace spirit { namespace x3
static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed&& attr)
static void post(Exposed& val, Transformed&& attribute)
{
traits::move_to(std::forward<Transformed>(attr), val);
traits::move_to(std::forward<Transformed>(attribute), val);
}
};

View File

@@ -22,26 +22,26 @@
namespace boost { namespace spirit { namespace x3
{
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
template <typename ID, typename Iterator
, typename Context, typename ActualAttribute>
inline detail::default_parse_rule_result
parse_rule(
rule<ID, Attribute> /* rule_ */
detail::rule_id<ID>
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr)
{
static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
static_assert(!is_same<decltype(x3::get<ID>(context)), unused_type>::value,
"BOOST_SPIRIT_DEFINE undefined for this rule.");
return get<ID>(context).parse(first, last, context, unused, attr);
return x3::get<ID>(context).parse(first, last, context, unused, attr);
}
template <typename ID, typename RHS, typename Attribute, bool force_attribute_>
struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_>>
template <typename ID, typename RHS, typename Attribute, bool force_attribute_, bool skip_definition_injection = false>
struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection>>
{
typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
typedef rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection> this_type;
typedef ID id;
typedef RHS rhs_type;
typedef rule<ID, Attribute> lhs_type;
typedef rule<ID, Attribute, force_attribute_> lhs_type;
typedef Attribute attribute_type;
static bool const has_attribute =
@@ -51,14 +51,14 @@ namespace boost { namespace spirit { namespace x3
static bool const force_attribute =
force_attribute_;
rule_definition(RHS const& rhs, char const* name)
constexpr rule_definition(RHS const& rhs, char const* name)
: rhs(rhs), name(name) {}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
return detail::rule_parser<attribute_type, ID>
return detail::rule_parser<attribute_type, ID, skip_definition_injection>
::call_rule_definition(
rhs, name, first, last
, context
@@ -71,8 +71,11 @@ namespace boost { namespace spirit { namespace x3
};
template <typename ID, typename Attribute, bool force_attribute_>
struct rule : parser<rule<ID, Attribute>>
struct rule : parser<rule<ID, Attribute, force_attribute_>>
{
static_assert(!std::is_reference<Attribute>::value,
"Reference qualifier on rule attribute type is meaningless");
typedef ID id;
typedef Attribute attribute_type;
static bool const has_attribute =
@@ -84,24 +87,53 @@ namespace boost { namespace spirit { namespace x3
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
rule() : name(typeid(rule).name()) {}
#else
rule() : name("unnamed") {}
constexpr rule() : name("unnamed") {}
#endif
rule(char const* name)
constexpr rule(char const* name)
: name(name) {}
constexpr rule(rule const& r)
: name(r.name)
{
// Assert that we are not copying an unitialized static rule. If
// the static is in another TU, it may be initialized after we copy
// it. If so, its name member will be nullptr.
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
}
template <typename RHS>
rule_definition<
constexpr rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
operator=(RHS const& rhs) const
operator=(RHS const& rhs) const&
{
return { as_parser(rhs), name };
}
template <typename RHS>
rule_definition<
constexpr rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
operator%=(RHS const& rhs) const
operator%=(RHS const& rhs) const&
{
return { as_parser(rhs), name };
}
// When a rule placeholder constructed and immediately consumed it cannot be used recursively,
// that's why the rule definition injection into a parser context can be skipped.
// This optimization has a huge impact on compile times because immediate rules are commonly
// used to cast an attribute like `as`/`attr_cast` does in Qi.
template <typename RHS>
constexpr rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_, true>
operator=(RHS const& rhs) const&&
{
return { as_parser(rhs), name };
}
template <typename RHS>
constexpr rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, true, true>
operator%=(RHS const& rhs) const&&
{
return { as_parser(rhs), name };
}
@@ -120,7 +152,7 @@ namespace boost { namespace spirit { namespace x3
using transform_attr = typename transform::type;
transform_attr attr_ = transform::pre(attr);
if (parse_rule(*this, first, last, context, attr_)) {
if (parse_rule(detail::rule_id<ID>{}, first, last, context, attr_)) {
transform::post(attr, std::forward<transform_attr>(attr_));
return true;
}
@@ -131,12 +163,9 @@ namespace boost { namespace spirit { namespace x3
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, unused_type) const
{
static_assert(!has_attribute,
"The rule requires an input attribute. Check your parser.");
// make sure we pass exactly the rule attribute type
attribute_type no_attr;
return parse_rule(*this, first, last, context, no_attr);
attribute_type no_attr{};
return parse_rule(detail::rule_id<ID>{}, first, last, context, no_attr);
}
char const* name;
@@ -147,11 +176,11 @@ namespace boost { namespace spirit { namespace x3
template <typename T, typename Enable = void>
struct is_rule : mpl::false_ {};
template <typename ID, typename Attribute>
struct is_rule<rule<ID, Attribute>> : mpl::true_ {};
template <typename ID, typename Attribute, bool force_attribute>
struct is_rule<rule<ID, Attribute, force_attribute>> : mpl::true_ {};
template <typename ID, typename Attribute, typename RHS, bool force_attribute>
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
template <typename ID, typename Attribute, typename RHS, bool force_attribute, bool skip_definition_injection>
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute, skip_definition_injection>> : mpl::true_ {};
}
template <typename T>
@@ -168,7 +197,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
template <typename Iterator, typename Context> \
bool parse_rule( \
rule_type rule_ \
::boost::spirit::x3::detail::rule_id<rule_type::id> \
, Iterator& first, Iterator const& last \
, Context const& context, rule_type::attribute_type& attr); \
/***/
@@ -182,26 +211,34 @@ namespace boost { namespace spirit { namespace x3
using BOOST_PP_CAT(rule_name, _synonym) = decltype(rule_name); \
template <typename Iterator, typename Context> \
inline bool parse_rule( \
BOOST_PP_CAT(rule_name, _synonym) /* rule_ */ \
::boost::spirit::x3::detail::rule_id<BOOST_PP_CAT(rule_name, _synonym)::id> \
, Iterator& first, Iterator const& last \
, Context const& context, BOOST_PP_CAT(rule_name, _synonym)::attribute_type& attr) \
{ \
using boost::spirit::x3::unused; \
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
return def_.parse(first, last, context, unused, attr); \
using rule_t = BOOST_JOIN(rule_name, _synonym); \
return ::boost::spirit::x3::detail \
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
::call_rule_definition( \
BOOST_JOIN(rule_name, _def), rule_name.name \
, first, last, context, attr \
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
} \
/***/
#else
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
template <typename Iterator, typename Context> \
inline bool parse_rule( \
decltype(rule_name) /* rule_ */ \
::boost::spirit::x3::detail::rule_id<decltype(rule_name)::id> \
, Iterator& first, Iterator const& last \
, Context const& context, decltype(rule_name)::attribute_type& attr) \
{ \
using boost::spirit::x3::unused; \
static auto const def_ = (rule_name = BOOST_PP_CAT(rule_name, _def)); \
return def_.parse(first, last, context, unused, attr); \
using rule_t = decltype(rule_name); \
return ::boost::spirit::x3::detail \
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
::call_rule_definition( \
BOOST_JOIN(rule_name, _def), rule_name.name \
, first, last, context, attr \
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
} \
/***/
#endif
@@ -212,7 +249,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
template bool parse_rule<Iterator, Context>( \
rule_type rule_ \
::boost::spirit::x3::detail::rule_id<rule_type::id> \
, Iterator& first, Iterator const& last \
, Context const& context, rule_type::attribute_type&); \
/***/

View File

@@ -5,8 +5,8 @@
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(SPIRIT_X3_BOOL_SEP_29_2009_0709AM)
#define SPIRIT_X3_BOOL_SEP_29_2009_0709AM
#ifndef BOOST_SPIRIT_X3_NUMERIC_BOOL_HPP
#define BOOST_SPIRIT_X3_NUMERIC_BOOL_HPP
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
@@ -21,10 +21,10 @@ namespace boost { namespace spirit { namespace x3
typedef T attribute_type;
static bool const has_attribute = true;
bool_parser()
constexpr bool_parser()
: policies() {}
bool_parser(BoolPolicies const& policies)
constexpr bool_parser(BoolPolicies const& policies)
: policies(policies) {}
template <typename Iterator, typename Context>
@@ -61,11 +61,11 @@ namespace boost { namespace spirit { namespace x3
static bool const has_attribute = true;
template <typename Value>
literal_bool_parser(Value const& n)
constexpr literal_bool_parser(Value const& n)
: policies(), n_(n) {}
template <typename Value>
literal_bool_parser(Value const& n, BoolPolicies const& policies)
constexpr literal_bool_parser(Value const& n, BoolPolicies const& policies)
: policies(policies), n_(n) {}
template <typename Iterator, typename Context>
@@ -105,51 +105,51 @@ namespace boost { namespace spirit { namespace x3
namespace standard
{
typedef bool_parser<bool, char_encoding::standard> bool_type;
bool_type const bool_ = {};
constexpr bool_type bool_ = {};
typedef literal_bool_parser<bool, char_encoding::standard> true_type;
true_type const true_ = { true };
constexpr true_type true_ = { true };
typedef literal_bool_parser<bool, char_encoding::standard> false_type;
false_type const false_ = { false };
constexpr false_type false_ = { false };
}
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
typedef bool_parser<bool, char_encoding::standard_wide> bool_type;
bool_type const bool_ = {};
constexpr bool_type bool_ = {};
typedef literal_bool_parser<bool, char_encoding::standard_wide> true_type;
true_type const true_ = { true };
constexpr true_type true_ = { true };
typedef literal_bool_parser<bool, char_encoding::standard_wide> false_type;
false_type const false_ = { false };
constexpr false_type false_ = { false };
}
#endif
namespace ascii
{
typedef bool_parser<bool, char_encoding::ascii> bool_type;
bool_type const bool_ = {};
constexpr bool_type bool_ = {};
typedef literal_bool_parser<bool, char_encoding::ascii> true_type;
true_type const true_ = { true };
constexpr true_type true_ = { true };
typedef literal_bool_parser<bool, char_encoding::ascii> false_type;
false_type const false_ = { false };
constexpr false_type false_ = { false };
}
namespace iso8859_1
{
typedef bool_parser<bool, char_encoding::iso8859_1> bool_type;
bool_type const bool_ = {};
constexpr bool_type bool_ = {};
typedef literal_bool_parser<bool, char_encoding::iso8859_1> true_type;
true_type const true_ = { true };
constexpr true_type true_ = { true };
typedef literal_bool_parser<bool, char_encoding::iso8859_1> false_type;
false_type const false_ = { false };
constexpr false_type false_ = { false };
}
using standard::bool_;

View File

@@ -42,7 +42,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name) \
typedef int_parser<int_type> name##type; \
name##type const name = {}; \
constexpr name##type name = {}; \
/***/
BOOST_SPIRIT_X3_INT_PARSER(long, long_)

View File

@@ -20,10 +20,10 @@ namespace boost { namespace spirit { namespace x3
typedef T attribute_type;
static bool const has_attribute = true;
real_parser()
constexpr real_parser()
: policies() {}
real_parser(RealPolicies const& policies)
constexpr real_parser(RealPolicies const& policies)
: policies(policies) {}
template <typename Iterator, typename Context>
@@ -52,10 +52,13 @@ namespace boost { namespace spirit { namespace x3
};
typedef real_parser<float> float_type;
float_type const float_ = {};
constexpr float_type float_ = {};
typedef real_parser<double> double_type;
double_type const double_ = {};
constexpr double_type double_ = {};
typedef real_parser<long double> long_double_type;
constexpr long_double_type long_double = {};
}}}

View File

@@ -43,7 +43,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, name) \
typedef uint_parser<uint_type> name##type; \
name##type const name = {}; \
constexpr name##type name = {}; \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned long, ulong_)
@@ -60,7 +60,7 @@ namespace boost { namespace spirit { namespace x3
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, radix, name) \
typedef uint_parser<uint_type, radix> name##type; \
name##type const name = name##type(); \
constexpr name##type name = name##type(); \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 2, bin)

View File

@@ -7,10 +7,12 @@
#if !defined(BOOST_SPIRIT_X3_ALTERNATIVE_JAN_07_2013_1131AM)
#define BOOST_SPIRIT_X3_ALTERNATIVE_JAN_07_2013_1131AM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of_binary.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/alternative.hpp>
#include <boost/variant/variant_fwd.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
@@ -18,7 +20,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef binary_parser<Left, Right, alternative<Left, Right>> base_type;
alternative(Left const& left, Right const& right)
constexpr alternative(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
@@ -42,7 +44,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Left, typename Right>
inline alternative<
constexpr alternative<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator|(Left const& left, Right const& right)
@@ -55,7 +57,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::alternative<Left, Right>, Context>
: x3::detail::attribute_of_alternative<Left, Right, Context> {};
: x3::detail::attribute_of_binary<boost::variant, x3::alternative, Left, Right, Context> {};
}}}}
#endif

View File

@@ -19,7 +19,7 @@ namespace boost { namespace spirit { namespace x3
typedef unused_type attribute_type;
static bool const has_attribute = false;
and_predicate(Subject const& subject)
constexpr and_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -33,7 +33,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Subject>
inline and_predicate<typename extension::as_parser<Subject>::value_type>
constexpr and_predicate<typename extension::as_parser<Subject>::value_type>
operator&(Subject const& subject)
{
return { as_parser(subject) };

View File

@@ -8,24 +8,20 @@
#define BOOST_SPIRIT_X3_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/pseudo_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/variant_find_substitute.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/variant/variant.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/type_traits/is_same.hpp>
#include <type_traits>
namespace boost { namespace spirit { namespace x3
{
@@ -83,9 +79,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr, mpl::true_)
call(Attribute_& attribute, mpl::true_)
{
return attr;
return attribute;
}
template <typename Attribute_>
@@ -97,9 +93,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Attribute_>
static type
call(Attribute_& attr)
call(Attribute_& attribute)
{
return call(attr, is_same<Attribute_, typename remove_reference<type>::type>());
return call(attribute, is_same<Attribute_, typename remove_reference<type>::type>());
}
};
@@ -111,9 +107,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
typedef Attribute& type;
static Attribute&
call(Attribute& attr)
call(Attribute& attribute)
{
return attr;
return attribute;
}
};
@@ -153,7 +149,6 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, pass_parser_attribute<Parser, Attribute, Context>
, pass_variant_unused>::type
{
typedef typename mpl::false_ is_alternative;
};
template <typename L, typename R, typename Attribute, typename Context>
@@ -162,99 +157,58 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, pass_variant_used<Attribute>
, pass_variant_unused>::type
{
typedef typename mpl::true_ is_alternative;
};
template <typename L, typename R, typename C>
struct get_alternative_types
{
typedef
mpl::vector<
typename traits::attribute_of<L, C>::type
, typename traits::attribute_of<R, C>::type
>
type;
};
template <typename LL, typename LR, typename R, typename C>
struct get_alternative_types<alternative<LL, LR>, R, C>
: mpl::push_back< typename get_alternative_types<LL, LR, C>::type
, typename traits::attribute_of<R, C>::type> {};
template <typename L, typename RL, typename RR, typename C>
struct get_alternative_types<L, alternative<RL, RR>, C>
: mpl::push_front< typename get_alternative_types<RL, RR, C>::type
, typename traits::attribute_of<L, C>::type> {};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_alternative_types<alternative<LL, LR>, alternative<RL, RR>, C>
{
typedef typename get_alternative_types<LL, LR, C>::type left;
typedef typename get_alternative_types<RL, RR, C>::type right;
typedef typename
mpl::insert_range<left, typename mpl::end<left>::type, right>::type
type;
};
template <typename L, typename R, typename C>
struct attribute_of_alternative
{
// Get all alternative attribute types
typedef typename get_alternative_types<L, R, C>::type all_types;
// Filter all unused_types
typedef typename
mpl::copy_if<
all_types
, mpl::not_<is_same<mpl::_1, unused_type>>
, mpl::back_inserter<mpl::vector<>>
>::type
filtered_types;
// Build a variant if filtered_types is not empty,
// else just return unused_type
typedef typename
mpl::eval_if<
mpl::empty<filtered_types>
, mpl::identity<unused_type>
, make_variant_over<filtered_types>
>::type
type;
};
template <typename IsAlternative>
struct move_if_not_alternative
template <bool Condition>
struct move_if
{
template<typename T1, typename T2>
static void call(T1& /* attr_ */, T2& /* attr */) {}
};
template <>
struct move_if_not_alternative<mpl::false_ /*is alternative*/>
struct move_if<true>
{
template<typename T1, typename T2>
static void call(T1& attr_, T2& attr)
static void call(T1& attr_, T2& attribute)
{
traits::move_to(attr_, attr);
traits::move_to(attr_, attribute);
}
};
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_alternative(Parser const& p, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
, Context const& context, RContext& rcontext, Attribute& attribute)
{
typedef detail::pass_variant_attribute<Parser, Attribute, Context> pass;
using pass = detail::pass_variant_attribute<Parser, Attribute, Context>;
using pseudo = traits::pseudo_attribute<Context, typename pass::type, Iterator>;
typename pseudo::type attr_ = pseudo::call(first, last, pass::call(attribute));
typename pass::type attr_ = pass::call(attr);
if (p.parse(first, last, context, rcontext, attr_))
{
move_if_not_alternative<typename pass::is_alternative>::call(attr_, attr);
move_if<!std::is_reference<decltype(attr_)>::value>::call(attr_, attribute);
return true;
}
return false;
}
template <typename Subject>
struct alternative_helper : unary_parser<Subject, alternative_helper<Subject>>
{
static bool const is_pass_through_unary = true;
using unary_parser<Subject, alternative_helper<Subject>>::unary_parser;
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
return detail::parse_alternative(this->subject, first, last, context, rcontext, attr);
}
};
template <typename Left, typename Right, typename Context, typename RContext>
struct parse_into_container_impl<alternative<Left, Right>, Context, RContext>
@@ -265,33 +219,30 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
, Context const& context, RContext& rcontext, Attribute& attribute, mpl::false_)
{
return parse_alternative(parser, first, last, context, rcontext, attr);
return detail::parse_into_container(parser.left, first, last, context, rcontext, attribute)
|| detail::parse_into_container(parser.right, first, last, context, rcontext, attribute);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
, Context const& context, RContext& rcontext, Attribute& attribute, mpl::true_)
{
return parse_into_container_base_impl<parser_type>::call(
parser, first, last, context, rcontext, attr);
return detail::parse_into_container(alternative_helper<Left>{parser.left}, first, last, context, rcontext, attribute)
|| detail::parse_into_container(alternative_helper<Right>{parser.right}, first, last, context, rcontext, attribute);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
, Context const& context, RContext& rcontext, Attribute& attribute)
{
typedef typename
traits::attribute_of<parser_type, Context>::type
attribute_type;
return call(parser, first, last, context, rcontext, attr
, traits::variant_has_substitute<attribute_type, Attribute>());
return call(parser, first, last, context, rcontext, attribute,
typename traits::is_variant<typename traits::container_value<Attribute>::type>::type{});
}
};

View File

@@ -22,16 +22,8 @@
#include <boost/fusion/include/empty.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/iterator_range.hpp>
#include <boost/fusion/include/as_deque.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -88,9 +80,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
typename fusion::result_of::begin<Attribute>::type
>::type type;
static type call(Attribute& attr)
static type call(Attribute& attribute)
{
return fusion::deref(fusion::begin(attr));
return fusion::deref(fusion::begin(attribute));
}
};
@@ -101,9 +93,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr)
call(Attribute_& attribute)
{
return attr;
return attribute;
}
};
@@ -238,65 +230,6 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
}
};
template <typename L, typename R, typename C>
struct get_sequence_types
{
typedef
mpl::vector<
typename traits::attribute_of<L, C>::type
, typename traits::attribute_of<R, C>::type
>
type;
};
template <typename LL, typename LR, typename R, typename C>
struct get_sequence_types<sequence<LL, LR>, R, C>
: mpl::push_back< typename get_sequence_types<LL, LR, C>::type
, typename traits::attribute_of<R, C>::type> {};
template <typename L, typename RL, typename RR, typename C>
struct get_sequence_types<L, sequence<RL, RR>, C>
: mpl::push_front< typename get_sequence_types<RL, RR, C>::type
, typename traits::attribute_of<L, C>::type> {};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_sequence_types<sequence<LL, LR>, sequence<RL, RR>, C>
{
typedef typename get_sequence_types<LL, LR, C>::type left;
typedef typename get_sequence_types<RL, RR, C>::type right;
typedef typename
mpl::insert_range<left, typename mpl::end<left>::type, right>::type
type;
};
template <typename L, typename R, typename C>
struct attribute_of_sequence
{
// Get all sequence attribute types
typedef typename get_sequence_types<L, R, C>::type all_types;
// Filter all unused_types
typedef typename
mpl::copy_if<
all_types
, mpl::not_<is_same<mpl::_1, unused_type>>
, mpl::back_inserter<mpl::vector<>>
>::type
filtered_types;
// Build a fusion::deque if filtered_types is not empty,
// else just return unused_type
typedef typename
mpl::eval_if<
mpl::empty<filtered_types>
, mpl::identity<unused_type>
, mpl::if_<mpl::equal_to<mpl::size<filtered_types>, mpl::int_<1> >,
typename mpl::front<filtered_types>::type
, typename fusion::result_of::as_deque<filtered_types>::type >
>::type
type;
};
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute, typename AttributeCategory>
bool parse_sequence(
@@ -304,11 +237,11 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Context const& context, RContext& rcontext, Attribute& attr
, AttributeCategory)
{
typedef typename Parser::left_type Left;
typedef typename Parser::right_type Right;
typedef partition_attribute<Left, Right, Attribute, Context> partition;
typedef typename partition::l_pass l_pass;
typedef typename partition::r_pass r_pass;
using Left = typename Parser::left_type;
using Right = typename Parser::right_type;
using partition = partition_attribute<Left, Right, Attribute, Context>;
using l_pass = typename partition::l_pass;
using r_pass = typename partition::r_pass;
typename partition::l_part l_part = partition::left(attr);
typename partition::r_part r_part = partition::right(attr);
@@ -441,7 +374,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
"where type of first element is existing key in fusion::map and second element "
"is value to be stored under that key");
Attribute attr_;
Attribute attr_{};
if (!parse_sequence(parser
, first, last, context, rcontext, attr_, traits::container_attribute()))
{

View File

@@ -19,7 +19,7 @@ namespace boost { namespace spirit { namespace x3
typedef binary_parser<Left, Right, difference<Left, Right>> base_type;
static bool const handles_container = Left::handles_container;
difference(Left const& left, Right const& right)
constexpr difference(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context
@@ -40,7 +40,7 @@ namespace boost { namespace spirit { namespace x3
}
template <typename Left_, typename Right_>
difference<Left_, Right_>
constexpr difference<Left_, Right_>
make(Left_ const& left, Right_ const& right) const
{
return { left, right };
@@ -48,7 +48,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Left, typename Right>
inline difference<
constexpr difference<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator-(Left const& left, Right const& right)

View File

@@ -21,7 +21,7 @@ namespace boost { namespace spirit { namespace x3
typedef unary_parser<Subject, kleene<Subject>> base_type;
static bool const handles_container = true;
kleene(Subject const& subject)
constexpr kleene(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -37,7 +37,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Subject>
inline kleene<typename extension::as_parser<Subject>::value_type>
constexpr kleene<typename extension::as_parser<Subject>::value_type>
operator*(Subject const& subject)
{
return { as_parser(subject) };

View File

@@ -20,9 +20,8 @@ namespace boost { namespace spirit { namespace x3
{
typedef binary_parser<Left, Right, list<Left, Right>> base_type;
static bool const handles_container = true;
static bool const has_attribute = true;
list(Left const& left, Right const& right)
constexpr list(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context
@@ -48,7 +47,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Left, typename Right>
inline list<
constexpr list<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator%(Left const& left, Right const& right)
@@ -63,6 +62,10 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
struct attribute_of<x3::list<Left, Right>, Context>
: traits::build_container<
typename attribute_of<Left, Context>::type> {};
template <typename Left, typename Right, typename Context>
struct has_attribute<x3::list<Left, Right>, Context>
: has_attribute<Left, Context> {};
}}}}
#endif

View File

@@ -19,7 +19,7 @@ namespace boost { namespace spirit { namespace x3
typedef unused_type attribute_type;
static bool const has_attribute = false;
not_predicate(Subject const& subject)
constexpr not_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -33,7 +33,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Subject>
inline not_predicate<typename extension::as_parser<Subject>::value_type>
constexpr not_predicate<typename extension::as_parser<Subject>::value_type>
operator!(Subject const& subject)
{
return { as_parser(subject) };

View File

@@ -21,9 +21,10 @@ namespace boost { namespace spirit { namespace x3
struct optional : proxy<Subject, optional<Subject>>
{
typedef proxy<Subject, optional<Subject>> base_type;
static bool const is_pass_through_unary = false;
static bool const handles_container = true;
optional(Subject const& subject)
constexpr optional(Subject const& subject)
: base_type(subject) {}
using base_type::parse_subject;
@@ -64,7 +65,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Subject>
inline optional<typename extension::as_parser<Subject>::value_type>
constexpr optional<typename extension::as_parser<Subject>::value_type>
operator-(Subject const& subject)
{
return { as_parser(subject) };

View File

@@ -21,7 +21,7 @@ namespace boost { namespace spirit { namespace x3
typedef unary_parser<Subject, plus<Subject>> base_type;
static bool const handles_container = true;
plus(Subject const& subject)
constexpr plus(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
@@ -41,7 +41,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Subject>
inline plus<typename extension::as_parser<Subject>::value_type>
constexpr plus<typename extension::as_parser<Subject>::value_type>
operator+(Subject const& subject)
{
return { as_parser(subject) };

View File

@@ -7,11 +7,13 @@
#if !defined(BOOST_SPIRIT_X3_SEQUENCE_JAN_06_2013_1015AM)
#define BOOST_SPIRIT_X3_SEQUENCE_JAN_06_2013_1015AM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of_binary.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/sequence.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/fusion/include/deque_fwd.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
@@ -19,7 +21,7 @@ namespace boost { namespace spirit { namespace x3
{
typedef binary_parser<Left, Right, sequence<Left, Right>> base_type;
sequence(Left const& left, Right const& right)
constexpr sequence(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
@@ -47,7 +49,7 @@ namespace boost { namespace spirit { namespace x3
};
template <typename Left, typename Right>
inline sequence<
constexpr sequence<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator>>(Left const& left, Right const& right)
@@ -56,7 +58,7 @@ namespace boost { namespace spirit { namespace x3
}
template <typename Left, typename Right>
auto operator>(Left const& left, Right const& right)
constexpr auto operator>(Left const& left, Right const& right)
{
return left >> expect[right];
}
@@ -66,7 +68,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::sequence<Left, Right>, Context>
: x3::detail::attribute_of_sequence<Left, Right, Context> {};
: x3::detail::attribute_of_binary<fusion::deque, x3::sequence, Left, Right, Context> {};
}}}}
#endif

View File

@@ -1,60 +0,0 @@
/*=============================================================================
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_NO_CASE_STRING_PARSE_APR_18_2014_1125PM)
#define BOOST_SPIRIT_X3_NO_CASE_STRING_PARSE_APR_18_2014_1125PM
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Char, typename Encoding>
struct no_case_string
{
typedef std::basic_string< Char > string_type;
typedef typename string_type::const_iterator const_iterator;
no_case_string(char_type const* str)
: lower(str)
, upper(str)
{
typename string_type::iterator loi = lower.begin();
typename string_type::iterator upi = upper.begin();
typedef typename Encoding::char_type encoded_char_type;
Encoding encoding;
for (; loi != lower.end(); ++loi, ++upi)
{
*loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
*upi = static_cast<char_type>(encoding.toupper(encoded_char_type(*upi)));
}
}
string_type lower;
string_type upper;
};
template <typename String, typename Iterator, typename Attribute>
inline bool no_case_string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr)
{
typename String::const_iterator uc_i = str.upper.begin();
typename String::const_iterator uc_last = str.upper.end();
typename String::const_iterator lc_i = str.lower.begin();
Iterator i = first;
for (; uc_i != uc_last; ++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;
}
}}}}
#endif

View File

@@ -10,6 +10,8 @@
#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

View File

@@ -11,7 +11,6 @@
#include <boost/spirit/home/x3/core/skip_over.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/string/detail/no_case_string_parse.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>
@@ -34,7 +33,7 @@ namespace boost { namespace spirit { namespace x3
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = has_attribute;
literal_string(typename add_reference< typename add_const<String>::type >::type str)
constexpr literal_string(typename add_reference< typename add_const<String>::type >::type str)
: str(str)
{}
@@ -51,7 +50,7 @@ namespace boost { namespace spirit { namespace x3
namespace standard
{
inline literal_string<char const*, char_encoding::standard>
constexpr literal_string<char const*, char_encoding::standard>
string(char const* s)
{
return { s };
@@ -63,7 +62,7 @@ namespace boost { namespace spirit { namespace x3
return { s };
}
inline literal_string<char const*, char_encoding::standard, unused_type>
inline constexpr literal_string<char const*, char_encoding::standard, unused_type>
lit(char const* s)
{
return { s };
@@ -80,7 +79,7 @@ namespace boost { namespace spirit { namespace x3
#ifndef BOOST_SPIRIT_NO_STANDARD_WIDE
namespace standard_wide
{
inline literal_string<wchar_t const*, char_encoding::standard_wide>
constexpr literal_string<wchar_t const*, char_encoding::standard_wide>
string(wchar_t const* s)
{
return { s };
@@ -92,7 +91,7 @@ namespace boost { namespace spirit { namespace x3
return { s };
}
inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
constexpr literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
lit(wchar_t const* s)
{
return { s };
@@ -106,9 +105,38 @@ namespace boost { namespace spirit { namespace x3
}
#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
{
inline literal_string<wchar_t const*, char_encoding::ascii>
constexpr literal_string<wchar_t const*, char_encoding::ascii>
string(wchar_t const* s)
{
return { s };
@@ -120,7 +148,7 @@ namespace boost { namespace spirit { namespace x3
return { s };
}
inline literal_string<char const*, char_encoding::ascii, unused_type>
constexpr literal_string<char const*, char_encoding::ascii, unused_type>
lit(char const* s)
{
return { s };
@@ -136,7 +164,7 @@ namespace boost { namespace spirit { namespace x3
namespace iso8859_1
{
inline literal_string<wchar_t const*, char_encoding::iso8859_1>
constexpr literal_string<wchar_t const*, char_encoding::iso8859_1>
string(wchar_t const* s)
{
return { s };
@@ -148,7 +176,7 @@ namespace boost { namespace spirit { namespace x3
return { s };
}
inline literal_string<char const*, char_encoding::iso8859_1, unused_type>
constexpr literal_string<char const*, char_encoding::iso8859_1, unused_type>
lit(char const* s)
{
return { s };
@@ -180,7 +208,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(char const* s)
static constexpr type call(char const* s)
{
return type(s);
}
@@ -199,7 +227,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(wchar_t const* s)
static constexpr type call(wchar_t const* s)
{
return type(s);
}
@@ -218,7 +246,7 @@ namespace boost { namespace spirit { namespace x3
typedef type value_type;
static type call(char const* s)
static constexpr type call(char const* s)
{
return type(s);
}

View File

@@ -9,6 +9,8 @@
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <string>
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through

View File

@@ -7,7 +7,7 @@
#if !defined(BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM)
#define BOOST_SPIRIT_X3_POSITION_TAGGED_MAY_01_2014_0321PM
#include <boost/range.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/core/enable_if.hpp>

View File

@@ -18,22 +18,18 @@ namespace boost { namespace spirit { namespace x3
template <typename Encoding>
struct case_compare
{
template < template <typename> class basic_charset>
typename Encoding::char_type
in_set( typename Encoding::char_type const ch
, basic_charset<typename Encoding::char_type> const &set)
template <typename Char, typename CharSet>
bool in_set(Char ch, CharSet const& set)
{
return set.test(ch);
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
template <typename Char>
int32_t operator()(Char lc, Char rc) const
{
return lc - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
@@ -44,20 +40,24 @@ namespace boost { namespace spirit { namespace x3
template <typename Encoding>
struct no_case_compare
{
template < template <typename> class basic_charset>
typename Encoding::char_type
in_set( typename Encoding::char_type const ch
, basic_charset<typename Encoding::char_type> const &set)
template <typename Char, typename CharSet>
bool in_set(Char ch_, CharSet const& set)
{
using char_type = typename Encoding::classify_type;
auto ch = char_type(ch_);
return set.test(ch)
|| set.test(Encoding::islower(ch) ? Encoding::toupper(ch) : Encoding::tolower(ch));
|| set.test(Encoding::islower(ch)
? Encoding::toupper(ch) : Encoding::tolower(ch));
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
template <typename Char>
int32_t operator()(Char lc_, Char const rc_) const
{
return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
using char_type = typename Encoding::classify_type;
auto lc = char_type(lc_);
auto rc = char_type(rc_);
return Encoding::islower(rc)
? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
}
template <typename CharClassTag>
@@ -95,6 +95,7 @@ namespace boost { namespace spirit { namespace x3
{
return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
}
auto const no_case_compare_ = no_case_tag{};
}}}

View File

@@ -112,19 +112,17 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
template <typename Char>
inline static bool is_valid(Char ch)
{
if (Radix <= 10)
return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|| (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
return (ch >= '0' && ch <= (Radix > 10 ? '9' : static_cast<Char>('0' + Radix -1)))
|| (Radix > 10 && ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|| (Radix > 10 && ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
}
template <typename Char>
inline static unsigned digit(Char ch)
{
if (Radix <= 10 || (ch >= '0' && ch <= '9'))
return ch - '0';
return char_encoding::ascii::tolower(ch) - 'a' + 10;
return (Radix <= 10 || (ch >= '0' && ch <= '9'))
? ch - '0'
: char_encoding::ascii::tolower(ch) - 'a' + 10;
}
};
@@ -300,6 +298,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4459) // declaration hides global declaration
#endif
template <typename Iterator, typename Attribute>
inline static bool
@@ -398,6 +397,7 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4459) // declaration hides global declaration
#endif
template <typename Iterator, typename Attribute>
inline static bool

View File

@@ -14,7 +14,6 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/pow10.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/sign.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/assert.hpp>
@@ -29,65 +28,79 @@ namespace boost { namespace spirit { namespace x3 { namespace extension
using x3::traits::pow10;
template <typename T>
inline void
inline bool
scale(int exp, T& n)
{
constexpr auto max_exp = std::numeric_limits<T>::max_exponent10;
constexpr auto min_exp = std::numeric_limits<T>::min_exponent10;
if (exp >= 0)
{
// $$$ Why is this failing for boost.math.concepts ? $$$
//~ int nn = std::numeric_limits<T>::max_exponent10;
//~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
// return false if exp exceeds the max_exp
// do this check only for primitive types!
if (is_floating_point<T>() && exp > max_exp)
return false;
n *= pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
if (exp < min_exp)
{
n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-min_exp);
// return false if exp still exceeds the min_exp
// do this check only for primitive types!
exp += -min_exp;
if (is_floating_point<T>() && exp < min_exp)
return false;
n /= pow10<T>(-exp);
}
else
{
n /= pow10<T>(-exp);
}
}
return true;
}
inline void
inline bool
scale(int /*exp*/, unused_type /*n*/)
{
// no-op for unused_type
return true;
}
template <typename T>
inline void
inline bool
scale(int exp, int frac, T& n)
{
scale(exp - frac, n);
return scale(exp - frac, n);
}
inline void
inline bool
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
return true;
}
inline float
negate(bool neg, float n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysignf)(n, -1.f) : n;
}
inline double
negate(bool neg, double n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysign)(n, -1.) : n;
}
inline long double
negate(bool neg, long double n)
{
return neg ? x3::changesign(n) : n;
return neg ? (std::copysignl)(n, -1.) : n;
}
template <typename T>
@@ -150,6 +163,7 @@ namespace boost { namespace spirit { namespace x3
}
bool e_hit = false;
Iterator e_pos;
int frac_digits = 0;
// Try to parse the dot ('.' decimal point)
@@ -178,6 +192,7 @@ namespace boost { namespace spirit { namespace x3
}
// Now, let's see if we can parse the exponent prefix
e_pos = first;
e_hit = p.parse_exp(first, last);
}
else
@@ -191,6 +206,7 @@ namespace boost { namespace spirit { namespace x3
// If we must expect a dot and we didn't see an exponent
// prefix, return no-match.
e_pos = first;
e_hit = p.parse_exp(first, last);
if (p.expect_dot && !e_hit)
{
@@ -208,19 +224,25 @@ namespace boost { namespace spirit { namespace x3
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
extension::scale(exp, frac_digits, n);
if (!extension::scale(exp, frac_digits, n))
return false;
}
else
{
// Oops, no exponent, return no-match.
first = save;
return false;
// If there is no number, disregard the exponent altogether.
// by resetting 'first' prior to the exponent prefix (e|E)
first = e_pos;
// Scale the number by -frac_digits.
if (!extension::scale(-frac_digits, n))
return false;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
extension::scale(-frac_digits, n);
if (!extension::scale(-frac_digits, n))
return false;
}
// If we got a negative sign, negate the number

View File

@@ -13,6 +13,7 @@
#include <boost/limits.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#include <cfloat>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)

View File

@@ -1,30 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 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)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SIGN_MAR_11_2009_0734PM)
#define BOOST_SPIRIT_X3_SIGN_MAR_11_2009_0734PM
#include <boost/math/special_functions/sign.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename T>
inline bool (signbit)(T x)
{
return (boost::math::signbit)(x) ? true : false;
}
template<typename T>
inline T (changesign)(T x)
{
return (boost::math::changesign)(x);
}
}}}
#endif

View File

@@ -1,6 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustín Bergé
Copyright (c) 2013 Agustin Berge
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@@ -16,8 +16,8 @@
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Get the attribute type of a component. By default, this gets the
// Component's attribute_type typedef or instantiates a nested attribute
// Get the attribute type of a component. By default, this gets the
// Component's attribute_type typedef or instantiates a nested attribute
// metafunction. Components may specialize this if such an attribute_type
// is not readily available (e.g. expensive to compute at compile time).
///////////////////////////////////////////////////////////////////////////
@@ -28,28 +28,27 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Component, typename Context, typename Enable = void>
struct default_attribute_of;
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
struct default_attribute_of<Component, Context,
typename disable_if_substitution_failure<
typename Component::attribute_type>::type>
: mpl::identity<typename Component::attribute_type> {};
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
struct default_attribute_of<Component, Context,
typename disable_if_substitution_failure<
typename Component::template attribute<Context>::type>::type>
: Component::template attribute<Context> {};
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
typename enable_if_c<Component::is_pass_through_unary>::type>
: attribute_of<typename Component::subject_type, Context>{};
}
template <typename Component, typename Context, typename Enable>
struct attribute_of : detail::default_attribute_of<Component, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2020 Nikita Kniazev
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_ATTRIBUTE_OF_BINARY
#define BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/type_traits/type_identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename... T>
struct type_sequence
{
using type = type_sequence;
static const int size = sizeof...(T);
template <typename... U>
using append = type_sequence<T..., U...>;
template <typename... U>
using prepend = type_sequence<U..., T...>;
template <typename U>
using extend = typename U::template prepend<T...>;
template <template <typename...> class U>
using transfer_to = U<T...>;
};
template <typename Attribute>
struct types_of_binary_init : type_sequence<Attribute> {};
template <>
struct types_of_binary_init<unused_type> : type_sequence<> {};
template <>
struct types_of_binary_init<unused_type const> : type_sequence<> {};
template <template <typename, typename> class B, typename P, typename C>
struct get_types_of_binary
: types_of_binary_init<typename traits::attribute_of<P, C>::type> {};
template <template <typename, typename> class B, typename L, typename R, typename C>
struct get_types_of_binary<B, B<L, R>, C>
: get_types_of_binary<B, L, C>::template extend<get_types_of_binary<B, R, C>> {};
template <template <typename...> class A, typename T, int = T::size>
struct type_sequence_to_attribute { using type = typename T::template transfer_to<A>; };
template <template <typename...> class A, typename T>
struct type_sequence_to_attribute<A, T, 1> : T::template transfer_to<type_identity> {};
template <template <typename...> class A, typename T>
struct type_sequence_to_attribute<A, T, 0> { using type = unused_type; };
template <template <typename...> class A, template <typename, typename> class B,
typename L, typename R, typename C>
using attribute_of_binary = type_sequence_to_attribute<A,
typename get_types_of_binary<B, B<L, R>, C>::type>;
}}}}
#endif

View File

@@ -12,8 +12,8 @@
#include <boost/fusion/support/category_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/fusion/include/deque.hpp>
#include <boost/tti/has_type.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/make_void.hpp>
#include <vector>
#include <string>
@@ -28,30 +28,27 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
namespace detail
{
BOOST_TTI_HAS_TYPE(value_type)
BOOST_TTI_HAS_TYPE(iterator)
BOOST_TTI_HAS_TYPE(size_type)
BOOST_TTI_HAS_TYPE(reference)
BOOST_TTI_HAS_TYPE(key_type)
template <typename T, typename Enabler = void>
struct is_container_impl : mpl::false_ {};
template <typename T>
struct is_container_impl<T, void_t<
typename T::value_type, typename T::iterator,
typename T::size_type, typename T::reference> > : mpl::true_ {};
template <typename T, typename Enabler = void>
struct is_associative_impl : mpl::false_ {};
template <typename T>
struct is_associative_impl<T, void_t<typename T::key_type>>
: mpl::true_ {};
}
template <typename T>
using is_container = mpl::bool_<
detail::has_type_value_type<T>::value &&
detail::has_type_iterator<T>::value &&
detail::has_type_size_type<T>::value &&
detail::has_type_reference<T>::value>;
using is_container = typename detail::is_container_impl<T>::type;
template <typename T>
using is_associative = mpl::bool_<
detail::has_type_key_type<T>::value>;
template<typename T, typename Enable = void>
struct is_reservable : mpl::false_ {};
template<typename T>
struct is_reservable<T, decltype(std::declval<T&>().reserve(0))>
: mpl::true_ {};
using is_associative = typename detail::is_associative_impl<T>::type;
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -158,18 +155,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
struct append_container
{
private:
template <typename Iterator>
static void reserve(Container& /* c */, Iterator /* first */, Iterator /* last */, mpl::false_)
{
// Not all containers have "reserve"
}
template <typename Iterator>
static void reserve(Container& c, Iterator first, Iterator last, mpl::true_)
{
c.reserve(c.size() + std::distance(first, last));
}
template <typename Iterator>
static void insert(Container& c, Iterator first, Iterator last, mpl::false_)
{
@@ -186,7 +171,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Iterator>
static bool call(Container& c, Iterator first, Iterator last)
{
reserve(c, first, last, is_reservable<Container>{});
insert(c, first, last, is_associative<Container>{});
return true;
}

View File

@@ -8,7 +8,7 @@
#if !defined(BOOST_SPIRIT_X3_IS_RANGE_DEC_06_2017_1900PM)
#define BOOST_SPIRIT_X3_IS_RANGE_DEC_06_2017_1900PM
#include <boost/range/iterator_range.hpp>
#include <boost/range/range_fwd.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits

View File

@@ -46,7 +46,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{};
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute_impl : is_same<T, Attribute> {};
struct is_substitute_impl : mpl::false_ {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
@@ -75,16 +75,15 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typename enable_if<
is_variant<Attribute>
>::type>
: mpl::or_<
is_same<T, Attribute>
, variant_has_substitute<Attribute, T>
>
: variant_has_substitute<Attribute, T>
{};
}
template <typename T, typename Attribute, typename Enable /*= void*/>
struct is_substitute
: detail::is_substitute_impl<T, Attribute> {};
: mpl::or_<
is_same<T, Attribute>,
detail::is_substitute_impl<T, Attribute>> {};
// for reference T
template <typename T, typename Attribute, typename Enable>

View File

@@ -12,6 +12,8 @@
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>
#include <boost/assert.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/move.hpp>
@@ -51,37 +53,37 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Source, typename Dest>
inline void
move_to(Source&&, Dest&, unused_attribute) {}
move_to(Source&, Dest&, unused_attribute) {}
template <typename Source, typename Dest>
inline void
move_to_plain(Source&& src, Dest& dest, mpl::false_) // src is not a single-element tuple
move_to_plain(Source& src, Dest& dest, mpl::false_) // src is not a single-element tuple
{
dest = std::move(src);
}
template <typename Source, typename Dest>
inline void
move_to_plain(Source&& src, Dest& dest, mpl::true_) // src is a single-element tuple
move_to_plain(Source& src, Dest& dest, mpl::true_) // src is a single-element tuple
{
dest = std::move(fusion::front(src));
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, plain_attribute)
move_to(Source& src, Dest& dest, plain_attribute)
{
typename mpl::and_<
fusion::traits::is_sequence<Source>,
is_size_one_sequence<Source> >
is_single_element_sequence;
move_to_plain(std::forward<Source>(src), dest, is_single_element_sequence);
move_to_plain(src, dest, is_single_element_sequence);
}
template <typename Source, typename Dest>
inline typename enable_if<is_container<Source>>::type
move_to(Source&& src, Dest& dest, container_attribute)
move_to(Source& src, Dest& dest, container_attribute)
{
traits::move_to(src.begin(), src.end(), dest);
}
@@ -92,30 +94,30 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
is_same_size_sequence<Dest, Source>,
mpl::not_<is_size_one_sequence<Dest> > >
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
move_to(Source& src, Dest& dest, tuple_attribute)
{
fusion::move(std::forward<Source>(src), dest);
fusion::move(std::move(src), dest);
}
template <typename Source, typename Dest>
inline typename enable_if<
is_size_one_sequence<Dest>
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
move_to(Source& src, Dest& dest, tuple_attribute)
{
traits::move_to(std::forward<Source>(src), fusion::front(dest));
traits::move_to(src, fusion::front(dest));
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
move_to(Source& src, Dest& dest, variant_attribute, mpl::false_)
{
dest = std::move(src);
}
template <typename Source, typename Dest>
inline void
move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::false_)
move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::false_)
{
// dest is a variant, src is a single element fusion sequence that the variant
// cannot directly hold. We'll try to unwrap the single element fusion sequence.
@@ -129,7 +131,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Source, typename Dest>
inline void
move_to_variant_from_single_element_sequence(Source&& src, Dest& dest, mpl::true_)
move_to_variant_from_single_element_sequence(Source& src, Dest& dest, mpl::true_)
{
// dest is a variant, src is a single element fusion sequence that the variant
// *can* directly hold.
@@ -138,21 +140,21 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
move_to(Source& src, Dest& dest, variant_attribute, mpl::true_)
{
move_to_variant_from_single_element_sequence(src, dest, variant_has_substitute<Dest, Source>());
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute tag)
move_to(Source& src, Dest& dest, variant_attribute tag)
{
move_to(src, dest, tag, is_size_one_sequence<Source>());
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, optional_attribute)
move_to(Source& src, Dest& dest, optional_attribute)
{
dest = std::move(src);
}
@@ -191,29 +193,28 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Source, typename Dest>
inline void move_to(Source&& src, Dest& dest)
{
detail::move_to(std::move(src), dest
, typename attribute_category<Dest>::type());
detail::move_to(src, dest, typename attribute_category<Dest>::type());
}
template <typename T>
inline void move_to(T& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
dest = std::move(src);
}
template <typename T>
inline void move_to(T const& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
dest = src;
}
template <typename T>
inline void move_to(T&& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
BOOST_ASSERT(boost::addressof(src) != boost::addressof(dest));
dest = std::move(src);
}
template <typename Iterator, typename Dest>

View File

@@ -14,6 +14,9 @@
#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/support/char_encoding/unicode.hpp>
#endif
namespace boost { namespace spirit { namespace x3 { namespace traits
{
@@ -67,9 +70,8 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename Out, typename T, typename Enable = void>
struct print_attribute_debug
{
// for plain data types
template <typename T_>
static void call(Out& out, T_ const& val, unused_attribute)
// for unused_type
static void call(Out& out, unused_type, unused_attribute)
{
out << "unused";
}
@@ -81,6 +83,28 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
out << val;
}
#ifdef BOOST_SPIRIT_X3_UNICODE
static void call(Out& out, char_encoding::unicode::char_type val, plain_attribute)
{
if (val >= 0 && val < 127)
{
if (iscntrl(val))
out << "\\" << std::oct << int(val) << std::dec;
else if (isprint(val))
out << char(val);
else
out << "\\x" << std::hex << int(val) << std::dec;
}
else
out << "\\x" << std::hex << int(val) << std::dec;
}
static void call(Out& out, char val, plain_attribute tag)
{
call(out, static_cast<char_encoding::unicode::char_type>(val), tag);
}
#endif
// for fusion data types
template <typename T_>
static void call(Out& out, T_ const& val, tuple_attribute)

View File

@@ -12,6 +12,7 @@
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cctype>
#include <ios>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
@@ -36,10 +37,17 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
case '\t': o << "\\t"; break;
case '\v': o << "\\v"; break;
default:
if (c >= 0 && c < 127 && iscntrl(c))
if (c >= 0 && c < 127)
{
if (iscntrl(c))
o << "\\" << std::oct << int(c);
else if (isprint(c))
o << char(c);
else
o << "\\x" << std::hex << int(c);
}
else
o << Char(c);
o << "\\x" << std::hex << int(c);
}
}
};

View File

@@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2019 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_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM)
#define BOOST_SPIRIT_X3_PSEUDO_ATTRIBUTE_OF_MAY_15_2019_1012PM
#include <utility>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Pseudo attributes are placeholders for parsers that can only know
// its actual attribute at parse time. This trait customization point
// provides a mechanism to convert the trait to the actual trait at
// parse time.
///////////////////////////////////////////////////////////////////////////
template <typename Context, typename Attribute, typename Iterator
, typename Enable = void>
struct pseudo_attribute
{
using attribute_type = Attribute;
using type = Attribute;
static type&& call(Iterator&, Iterator const&, attribute_type&& attribute)
{
return std::forward<type>(attribute);
}
};
}}}}
#endif

View File

@@ -11,128 +11,9 @@
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Determine if T is a character type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_char : mpl::false_ {};
template <typename T>
struct is_char<T const> : is_char<T> {};
template <>
struct is_char<char> : mpl::true_ {};
template <>
struct is_char<wchar_t> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Determine if T is a string
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_string : mpl::false_ {};
template <typename T>
struct is_string<T const> : is_string<T> {};
template <>
struct is_string<char const*> : mpl::true_ {};
template <>
struct is_string<wchar_t const*> : mpl::true_ {};
template <>
struct is_string<char*> : mpl::true_ {};
template <>
struct is_string<wchar_t*> : mpl::true_ {};
template <std::size_t N>
struct is_string<char[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char const[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t const[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char const(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
template <typename T, typename Traits, typename Allocator>
struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Get the underlying char type of a string
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct char_type_of;
template <typename T>
struct char_type_of<T const> : char_type_of<T> {};
template <>
struct char_type_of<char> : mpl::identity<char> {};
template <>
struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
template <>
struct char_type_of<char const*> : mpl::identity<char const> {};
template <>
struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
template <>
struct char_type_of<char*> : mpl::identity<char> {};
template <>
struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char[N]> : mpl::identity<char> {};
template <std::size_t N>
struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char const[N]> : mpl::identity<char const> {};
template <std::size_t N>
struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
template <std::size_t N>
struct char_type_of<char(&)[N]> : mpl::identity<char> {};
template <std::size_t N>
struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
template <std::size_t N>
struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
template <typename T, typename Traits, typename Allocator>
struct char_type_of<std::basic_string<T, Traits, Allocator> >
: mpl::identity<T> {};
///////////////////////////////////////////////////////////////////////////
// Get the C string from a string
///////////////////////////////////////////////////////////////////////////
@@ -142,8 +23,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename String>
struct extract_c_string
{
typedef typename char_type_of<String>::type char_type;
template <typename T>
static T const* call (T* str)
{
@@ -161,9 +40,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T>
struct extract_c_string<T const>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T const str)
static decltype(auto) call(T const str)
{
return extract_c_string<T>::call(str);
}
@@ -173,9 +50,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T>
struct extract_c_string<T&>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T& str)
static decltype(auto) call(T& str)
{
return extract_c_string<T>::call(str);
}
@@ -185,9 +60,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T>
struct extract_c_string<T const&>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T const& str)
static decltype(auto) call(T const& str)
{
return extract_c_string<T>::call(str);
}
@@ -196,8 +69,6 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
template <typename T, typename Traits, typename Allocator>
struct extract_c_string<std::basic_string<T, Traits, Allocator> >
{
typedef T char_type;
typedef std::basic_string<T, Traits, Allocator> string;
static T const* call (string const& str)
@@ -207,29 +78,25 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
};
template <typename T>
typename extract_c_string<T*>::char_type const*
get_c_string(T* str)
decltype(auto) get_c_string(T* str)
{
return extract_c_string<T*>::call(str);
}
template <typename T>
typename extract_c_string<T const*>::char_type const*
get_c_string(T const* str)
decltype(auto) get_c_string(T const* str)
{
return extract_c_string<T const*>::call(str);
}
template <typename String>
typename extract_c_string<String>::char_type const*
get_c_string(String& str)
decltype(auto) get_c_string(String& str)
{
return extract_c_string<String>::call(str);
}
template <typename String>
typename extract_c_string<String>::char_type const*
get_c_string(String const& str)
decltype(auto) get_c_string(String const& str)
{
return extract_c_string<String>::call(str);
}

View File

@@ -1,24 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2014 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)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename T, typename Enable = void>
struct value_initialize
{
static T call()
{
return {};
}
};
}}}}
#endif

View File

@@ -13,22 +13,22 @@
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_find_substitute
{
// Get the type from the variant that can be a substitute for Attribute.
// If none is found, just return Attribute
// Get the type from the Variant that can be a substitute for T.
// If none is found, just return T
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename mpl::find<types, Attribute>::type iter_1;
typedef typename mpl::find<types, T>::type iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
mpl::find_if<types, traits::is_substitute<T, mpl::_1> >,
mpl::identity<iter_1>
>::type
iter;
@@ -36,7 +36,7 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typedef typename
mpl::eval_if<
is_same<iter, end>,
mpl::identity<Attribute>,
mpl::identity<T>,
mpl::deref<iter>
>::type
type;

View File

@@ -13,22 +13,22 @@
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_has_substitute_impl
{
// Find a type from the variant that can be a substitute for Attribute.
// Find a type from the Variant that can be a substitute for T.
// return true_ if one is found, else false_
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename mpl::find<types, Attribute>::type iter_1;
typedef typename mpl::find<types, T>::type iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
mpl::find_if<types, traits::is_substitute<T, mpl::_1>>,
mpl::identity<iter_1>
>::type
iter;
@@ -36,15 +36,15 @@ namespace boost { namespace spirit { namespace x3 { namespace traits
typedef mpl::not_<is_same<iter, end>> type;
};
template <typename Variant, typename Attribute>
template <typename Variant, typename T>
struct variant_has_substitute
: variant_has_substitute_impl<Variant, Attribute>::type {};
: variant_has_substitute_impl<Variant, T>::type {};
template <typename Attribute>
struct variant_has_substitute<unused_type, Attribute> : mpl::true_ {};
template <typename T>
struct variant_has_substitute<unused_type, T> : mpl::true_ {};
template <typename Attribute>
struct variant_has_substitute<unused_type const, Attribute> : mpl::true_ {};
template <typename T>
struct variant_has_substitute<unused_type const, T> : mpl::true_ {};
}}}}

View File

@@ -10,19 +10,12 @@
#include <iosfwd>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4522) // multiple assignment operators specified warning
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3
{
struct unused_type
{
unused_type()
{
}
unused_type() = default;
template <typename T>
unused_type(T const&)
@@ -43,18 +36,6 @@ namespace boost { namespace spirit { namespace x3
return *this;
}
unused_type const&
operator=(unused_type const&) const
{
return *this;
}
unused_type&
operator=(unused_type const&)
{
return *this;
}
// unused_type can also masquerade as an empty context (see context.hpp)
template <typename ID>
@@ -62,23 +43,19 @@ namespace boost { namespace spirit { namespace x3
{
return {};
}
friend std::ostream& operator<<(std::ostream& out, unused_type const&)
{
return out;
}
friend std::istream& operator>>(std::istream& in, unused_type&)
{
return in;
}
};
auto const unused = unused_type{};
inline std::ostream& operator<<(std::ostream& out, unused_type const&)
{
return out;
}
inline std::istream& operator>>(std::istream& in, unused_type&)
{
return in;
}
constexpr auto unused = unused_type{};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -11,6 +11,7 @@
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/utility/error_reporting.hpp>
#include <boost/spirit/home/x3/support/utility/lambda_visitor.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
namespace boost { namespace spirit { namespace x3
{
@@ -40,9 +41,16 @@ namespace boost { namespace spirit { namespace x3
template <typename T, typename Iterator, typename Context>
inline void on_success(Iterator const& first, Iterator const& last
, forward_ast<T>& ast, Context const& context)
{
this->on_success(first, last, ast.get(), context);
}
template <typename T, typename Iterator, typename Context>
inline typename disable_if<traits::is_variant<T>>::type on_success(Iterator const& first, Iterator const& last
, T& ast, Context const& context)
{
auto& error_handler = get<error_handler_tag>(context).get();
auto& error_handler = x3::get<error_handler_tag>(context).get();
error_handler.tag(ast, first, last);
}
};

View File

@@ -7,12 +7,8 @@
#if !defined(BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM)
#define BOOST_SPIRIT_X3_ERROR_REPORTING_MAY_19_2014_00405PM
#ifndef BOOST_SPIRIT_X3_NO_FILESYSTEM
#include <boost/filesystem/path.hpp>
#endif
#include <boost/locale/encoding_utf.hpp>
#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <ostream>
// Clang-style error handling utilities
@@ -68,8 +64,6 @@ namespace boost { namespace spirit { namespace x3
void print_file_line(std::size_t line) const;
void print_line(Iterator line_start, Iterator last) const;
void print_indicator(Iterator& line_start, Iterator last, char ind) const;
void skip_whitespace(Iterator& err_pos, Iterator last) const;
void skip_non_whitespace(Iterator& err_pos, Iterator last) const;
Iterator get_line_start(Iterator first, Iterator pos) const;
std::size_t position(Iterator i) const;
@@ -84,12 +78,7 @@ namespace boost { namespace spirit { namespace x3
{
if (file != "")
{
#ifdef BOOST_SPIRIT_X3_NO_FILESYSTEM
err_out << "In file " << file << ", ";
#else
namespace fs = boost::filesystem;
err_out << "In file " << fs::path(file).generic_string() << ", ";
#endif
}
else
{
@@ -113,7 +102,7 @@ namespace boost { namespace spirit { namespace x3
}
typedef typename std::iterator_traits<Iterator>::value_type char_type;
std::basic_string<char_type> line{start, end};
err_out << locale::conv::utf_to_utf<char>(line) << std::endl;
err_out << x3::to_utf8(line) << std::endl;
}
template <typename Iterator>
@@ -132,41 +121,15 @@ namespace boost { namespace spirit { namespace x3
}
}
template <typename Iterator>
void error_handler<Iterator>::skip_whitespace(Iterator& err_pos, Iterator last) const
{
// make sure err_pos does not point to white space
while (err_pos != last)
{
char c = *err_pos;
if (std::isspace(c))
++err_pos;
else
break;
}
}
template <typename Iterator>
void error_handler<Iterator>::skip_non_whitespace(Iterator& err_pos, Iterator last) const
{
// make sure err_pos does not point to white space
while (err_pos != last)
{
char c = *err_pos;
if (std::isspace(c))
break;
else
++err_pos;
}
}
template <class Iterator>
inline Iterator error_handler<Iterator>::get_line_start(Iterator first, Iterator pos) const
{
Iterator latest = first;
for (Iterator i = first; i != pos; ++i)
for (Iterator i = first; i != pos;)
if (*i == '\r' || *i == '\n')
latest = i;
latest = ++i;
else
++i;
return latest;
}
@@ -201,15 +164,10 @@ namespace boost { namespace spirit { namespace x3
Iterator first = pos_cache.first();
Iterator last = pos_cache.last();
// make sure err_pos does not point to white space
skip_whitespace(err_pos, last);
print_file_line(position(err_pos));
err_out << error_message << std::endl;
Iterator start = get_line_start(first, err_pos);
if (start != first)
++start;
print_line(start, last);
print_indicator(start, err_pos, '_');
err_out << "^_" << std::endl;
@@ -222,15 +180,10 @@ namespace boost { namespace spirit { namespace x3
Iterator first = pos_cache.first();
Iterator last = pos_cache.last();
// make sure err_pos does not point to white space
skip_whitespace(err_first, last);
print_file_line(position(err_first));
err_out << error_message << std::endl;
Iterator start = get_line_start(first, err_first);
if (start != first)
++start;
print_line(start, last);
print_indicator(start, err_first, ' ');
print_indicator(start, err_last, '~');

View File

@@ -8,7 +8,6 @@
#define BOOST_SPIRIT_X3_IS_CALLABLE_HPP_INCLUDED
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
@@ -16,8 +15,8 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
struct is_callable_impl : mpl::false_ {};
template <typename F, typename... A>
struct is_callable_impl<F(A...), typename disable_if_substitution_failure<
decltype(std::declval<F>()(std::declval<A>()...))>::type>
struct is_callable_impl<F(A...),
decltype(void(std::declval<F>()(std::declval<A>()...)))>
: mpl::true_
{};
}}}}

View File

@@ -1,269 +0,0 @@
/*=============================================================================
Copyright (c) 2001-2015 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_TEST_UTILITIES)
#define BOOST_SPIRIT_X3_TEST_UTILITIES
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
namespace boost { namespace spirit { namespace x3 { namespace testing
{
namespace fs = boost::filesystem;
////////////////////////////////////////////////////////////////////////////
// compare
//
// Compares the contents of in with the template tem. The template
// may include embedded regular expressions marked up within re_prefix
// and re_suffix tags. For example, given the default RE markup, this
// template <%[0-9]+%> will match any integer in in. The function
// will return the first non-matching position. The flag full_match
// indicates a full match. It is possible for returned pos to be
// at the end of in (in.end()) while still returning full_match ==
// false. In that case, we have a partial match.
////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct compare_result
{
compare_result(
Iterator pos
, bool full_match
) : pos(pos), full_match(full_match) {}
Iterator pos;
bool full_match;
};
template <typename Range>
compare_result<typename Range::const_iterator>
compare(
Range const& in
, Range const& tem
, char const* re_prefix = "<%"
, char const* re_suffix = "%>"
);
////////////////////////////////////////////////////////////////////////////
// compare
//
// 1) Call f, given the contents of input_path loaded in a string.
// The result of calling f is the output string.
// 2) Compare the result of calling f with expected template
// file (expect_path) using the low-level compare utility
// abive
////////////////////////////////////////////////////////////////////////////
template <typename F>
bool compare(
fs::path input_path, fs::path expect_path
, F f
, char const* re_prefix = "<%"
, char const* re_suffix = "%>"
);
////////////////////////////////////////////////////////////////////////////
// for_each_file
//
// For each *.input and *.expect file in a given directory,
// call the function f, passing in the *.input and *.expect paths.
////////////////////////////////////////////////////////////////////////////
template <typename F>
int for_each_file(fs::path p, F f);
////////////////////////////////////////////////////////////////////////////
// load_file
//
// Load file into a string.
////////////////////////////////////////////////////////////////////////////
std::string load(fs::path p);
////////////////////////////////////////////////////////////////////////////
// Implementation
////////////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline bool is_regex(
Iterator& first
, Iterator last
, std::string& re
, char const* re_prefix
, char const* re_suffix
)
{
boost::regex e(re_prefix + std::string("(.*?)") + re_suffix);
boost::match_results<Iterator> what;
if (boost::regex_search(
first, last, what, e
, boost::match_default | boost::match_continuous))
{
re = what[1].str();
first = what[0].second;
return true;
}
return false;
}
template <typename Range>
inline compare_result<typename Range::const_iterator>
compare(
Range const& in
, Range const& tem
, char const* re_prefix
, char const* re_suffix
)
{
typedef typename Range::const_iterator iter_t;
typedef compare_result<iter_t> compare_result_t;
iter_t in_first = in.begin();
iter_t in_last = in.end();
iter_t tem_first = tem.begin();
iter_t tem_last = tem.end();
std::string re;
while (in_first != in_last && tem_first != tem_last)
{
if (is_regex(tem_first, tem_last, re, re_prefix, re_suffix))
{
boost::match_results<iter_t> what;
boost::regex e(re);
if (!boost::regex_search(
in_first, in_last, what, e
, boost::match_default | boost::match_continuous))
{
// RE mismatch: exit now.
return compare_result_t(in_first, false);
}
else
{
// RE match: gobble the matching string.
in_first = what[0].second;
}
}
else
{
// Char by char comparison. Exit if we have a mismatch.
if (*in_first++ != *tem_first++)
return compare_result_t(in_first, false);
}
}
// Ignore trailing spaces in template
bool has_trailing_nonspaces = false;
while (tem_first != tem_last)
{
if (!std::isspace(*tem_first++))
{
has_trailing_nonspaces = true;
break;
}
}
while (in_first != in_last)
{
if (!std::isspace(*in_first++))
{
has_trailing_nonspaces = true;
break;
}
}
// return a full match only if the template is fully matched and if there
// are no more characters to match in the source
return compare_result_t(in_first, !has_trailing_nonspaces);
}
template <typename F>
inline int for_each_file(fs::path p, F f)
{
try
{
if (fs::exists(p) && fs::is_directory(p))
{
for (auto i = fs::directory_iterator(p); i != fs::directory_iterator(); ++i)
{
auto ext = fs::extension(i->path());
if (ext == ".input")
{
auto input_path = i->path();
auto expect_path = input_path;
expect_path.replace_extension(".expect");
f(input_path, expect_path);
}
}
}
else
{
std::cerr << "Directory: " << fs::absolute(p) << " does not exist." << std::endl;
return 1;
}
}
catch (const fs::filesystem_error& ex)
{
std::cerr << ex.what() << '\n';
return 1;
}
return 0;
}
inline std::string load(fs::path p)
{
boost::filesystem::ifstream file(p);
if (!file)
return "";
std::string contents((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
return contents;
}
template <typename F>
inline bool compare(
fs::path input_path, fs::path expect_path
, F f
, char const* re_prefix
, char const* re_suffix
)
{
std::string output = f(load(input_path), input_path);
std::string expected = load(expect_path);
auto result = compare(output, expected, re_prefix, re_suffix);
if (!result.full_match)
{
std::cout << "=============================================" << std::endl;
std::cout << "==== Mismatch Found:" << std::endl;
int line = 1;
int col = 1;
for (auto i = output.begin(); i != result.pos; ++i)
{
if (*i == '\n')
{
line++;
col = 0;
}
++col;
}
std::cerr
<< "==== File: " << expect_path
<< ", Line: " << line
<< ", Column: " << col
<< std::endl;
std::cerr << "=============================================" << std::endl;
// Print output
std::cerr << output;
std::cerr << "=============================================" << std::endl;
std::cerr << "==== End" << std::endl;
std::cerr << "=============================================" << std::endl;
return false;
}
return true;
}
}}}}
#endif

View File

@@ -1,25 +0,0 @@
/*//////////////////////////////////////////////////////////////////////////////
Copyright (c) 2014 Jamboree
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_UNREFCV_HPP_INCLUDED
#define BOOST_SPIRIT_X3_UNREFCV_HPP_INCLUDED
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename T>
struct unrefcv : remove_cv<typename remove_reference<T>::type> {};
template <typename T>
using unrefcv_t = typename unrefcv<T>::type;
}}}
#endif

View File

@@ -1,5 +1,6 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2023 Nikita Kniazev
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)
@@ -7,42 +8,62 @@
#if !defined(BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)
#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
#include <boost/cstdint.hpp>
#include <boost/regex/pending/unicode_iterator.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/config.hpp>
#include <type_traits>
#include <string>
namespace boost { namespace spirit { namespace x3
{
typedef ::boost::uint32_t ucs4_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 {
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)));
}
}
}
template <typename Char>
inline utf8_string to_utf8(Char value)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
*utf8_iter = (UChar)value;
typedef typename std::make_unsigned<Char>::type UChar;
detail::utf8_put_encode(result, static_cast<UChar>(value));
return result;
}
template <typename Char>
inline utf8_string to_utf8(Char const* str)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
typedef typename std::make_unsigned<Char>::type UChar;
while (*str)
*utf8_iter++ = (UChar)*str++;
detail::utf8_put_encode(result, static_cast<UChar>(*str++));
return result;
}
@@ -50,46 +71,49 @@ namespace boost { namespace spirit { namespace x3
inline utf8_string
to_utf8(std::basic_string<Char, Traits, Allocator> const& str)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
typedef typename std::make_unsigned<Char>::type UChar;
for (Char ch : str)
{
*utf8_iter++ = (UChar)ch;
}
detail::utf8_put_encode(result, static_cast<UChar>(ch));
return result;
}
// Assume wchar_t content is UTF-16 on Windows and UCS-4 on Unix
#if defined(_WIN32) || defined(__CYGWIN__)
// 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
inline utf8_string to_utf8(wchar_t value)
{
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
u16_to_u32_iterator<wchar_t const*, ucs4_char> ucs4_iter(&value);
*utf8_iter++ = *ucs4_iter;
detail::utf8_put_encode(result, static_cast<std::make_unsigned<wchar_t>::type>(value));
return result;
}
namespace detail {
inline ucs4_char decode_utf16(wchar_t const*& s)
{
typedef std::make_unsigned<wchar_t>::type uwchar_t;
uwchar_t x(*s);
if (x < 0xD800ul || x > 0xDFFFul)
return x;
// expected high-surrogate
if (BOOST_UNLIKELY((x >> 10) != 0b110110ul))
return 0xFFFDul;
uwchar_t y(*++s);
// expected low-surrogate
if (BOOST_UNLIKELY((y >> 10) != 0b110111ul))
return 0xFFFDul;
return ((x & 0x3FFul) << 10) + (y & 0x3FFul) + 0x10000ul;
}
}
inline utf8_string to_utf8(wchar_t const* str)
{
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
u16_to_u32_iterator<wchar_t const*, ucs4_char> ucs4_iter(str);
for (ucs4_char c; (c = *ucs4_iter) != ucs4_char(); ++ucs4_iter) {
*utf8_iter++ = c;
}
for (ucs4_char c; (c = detail::decode_utf16(str)) != ucs4_char(); ++str)
detail::utf8_put_encode(result, c);
return result;
}

View File

@@ -6,14 +6,14 @@
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(SPIRIT_X3_VERSION_INCLUDED)
#define SPIRIT_X3_VERSION_INCLUDED
#ifndef BOOST_SPIRIT_X3_VERSION_HPP
#define BOOST_SPIRIT_X3_VERSION_HPP
///////////////////////////////////////////////////////////////////////////////
//
// This is the version of the current Spirit X3 distribution
//
///////////////////////////////////////////////////////////////////////////////
#define SPIRIT_X3_VERSION 0x3004
#define SPIRIT_X3_VERSION 0x3010
#endif