update boost
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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]) };
|
||||
}
|
||||
|
||||
@@ -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] };
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}}}}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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_<
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) };
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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&); \
|
||||
/***/
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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_)
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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{});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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()))
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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{};
|
||||
|
||||
}}}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ {};
|
||||
|
||||
}}}}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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, '~');
|
||||
|
||||
@@ -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_
|
||||
{};
|
||||
}}}}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user