stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,18 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_AUXILIARY_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM
#include <boost/spirit/home/x3/auxiliary/any_parser.hpp>
#include <boost/spirit/home/x3/auxiliary/eps.hpp>
#include <boost/spirit/home/x3/auxiliary/guard.hpp>
#include <boost/spirit/home/x3/auxiliary/eol.hpp>
#include <boost/spirit/home/x3/auxiliary/eoi.hpp>
#include <boost/spirit/home/x3/auxiliary/attr.hpp>
#endif
@@ -0,0 +1,151 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013-2014 Agustin Berge
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_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM)
#define BOOST_SPIRIT_X3_AUXILIARY_ANY_PARSER_APR_09_2014_1145PM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/subcontext.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/is_parser.hpp>
#include <memory>
#include <string>
namespace boost { namespace spirit { namespace x3
{
template <
typename Iterator
, typename Attribute = unused_type
, typename Context = subcontext<>>
struct any_parser : parser<any_parser<Iterator, Attribute, Context>>
{
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
public:
any_parser()
: _content(nullptr) {}
template <typename Expr,
typename Enable = typename enable_if<traits::is_parser<Expr>>::type>
any_parser(Expr const& expr)
: _content(new holder<Expr>(expr)) {}
any_parser(any_parser const& other)
: _content(other._content ? other._content->clone() : nullptr) {}
any_parser(any_parser&& other) = default;
any_parser& operator=(any_parser const& other)
{
_content.reset(other._content ? other._content->clone() : nullptr);
return *this;
}
any_parser& operator=(any_parser&& other) = default;
template <typename Iterator_, typename Context_>
bool parse(Iterator_& first, Iterator_ const& last
, Context_ const& context, unused_type, Attribute& attr) const
{
BOOST_STATIC_ASSERT_MSG(
(is_same<Iterator, Iterator_>::value)
, "Incompatible iterator used"
);
BOOST_ASSERT_MSG(
(_content != nullptr)
, "Invalid use of uninitialized any_parser"
);
return _content->parse(first, last, context, attr);
}
template <typename Iterator_, typename Context_, typename Attribute_>
bool parse(Iterator_& first, Iterator_ const& last
, Context_ const& context, unused_type, Attribute_& attr_) const
{
Attribute attr;
if (parse(first, last, context, unused, attr))
{
traits::move_to(attr, attr_);
return true;
}
return false;
}
std::string get_info() const
{
return _content ? _content->get_info() : "";
}
private:
struct placeholder
{
virtual placeholder* clone() const = 0;
virtual bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const = 0;
virtual std::string get_info() const = 0;
virtual ~placeholder() {}
};
template <typename Expr>
struct holder : placeholder
{
typedef typename extension::as_parser<Expr>::value_type parser_type;
explicit holder(Expr const& p)
: _parser(as_parser(p)) {}
holder* clone() const override
{
return new holder(*this);
}
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const override
{
return _parser.parse(first, last, context, unused, attr);
}
std::string get_info() const override
{
return x3::what(_parser);
}
parser_type _parser;
};
private:
std::unique_ptr<placeholder> _content;
};
template <typename Iterator, typename Attribute, typename Context>
struct get_info<any_parser<Iterator, Attribute, Context>>
{
typedef std::string result_type;
std::string operator()(
any_parser<Iterator, Attribute, Context> const& p) const
{
return p.get_info();
}
};
}}}
#endif
@@ -0,0 +1,131 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_ATTR_JUL_23_2008_0956AM
#define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#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
{
template <typename Value>
struct attr_parser : parser<attr_parser<Value>>
{
typedef Value attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<attribute_type>::value;
attr_parser(Value const& value)
: value_(value) {}
attr_parser(Value&& value)
: value_(std::move(value)) {}
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext&, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
traits::move_to(value_, attr_);
return true;
}
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]>>
{
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>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext&, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
traits::move_to(value_ + 0, 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>
struct get_info<attr_parser<Value>>
{
typedef std::string result_type;
std::string operator()(attr_parser<Value> const& /*p*/) const
{
return "attr";
}
};
struct attr_gen
{
template <typename Value>
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{};
}}}
#endif
@@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_EOI_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct eoi_parser : parser<eoi_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute&) const
{
x3::skip_over(first, last, context);
return first == last;
}
};
template<>
struct get_info<eoi_parser>
{
typedef std::string result_type;
result_type operator()(eoi_parser const &) const { return "eoi"; }
};
auto const eoi = eoi_parser{};
}}}
#endif
@@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_EOL_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct eol_parser : parser<eol_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& /*attr*/) const
{
x3::skip_over(first, last, context);
Iterator iter = first;
bool matched = false;
if (iter != last && *iter == '\r') // CR
{
matched = true;
++iter;
}
if (iter != last && *iter == '\n') // LF
{
matched = true;
++iter;
}
if (matched) first = iter;
return matched;
}
};
template<>
struct get_info<eol_parser>
{
typedef std::string result_type;
result_type operator()(eol_parser const &) const { return "eol"; }
};
auto const eol = eol_parser{};
}}}
#endif
@@ -0,0 +1,86 @@
/*=============================================================================
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_EPS_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct rule_context_tag;
struct semantic_predicate : parser<semantic_predicate>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
semantic_predicate(bool predicate)
: predicate(predicate) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute&) const
{
x3::skip_over(first, last, context);
return predicate;
}
bool predicate;
};
template <typename F>
struct lazy_semantic_predicate : parser<lazy_semantic_predicate<F>>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
lazy_semantic_predicate(F f)
: f(f) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
return f(x3::get<rule_context_tag>(context));
}
F f;
};
struct eps_parser : parser<eps_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext&, Attribute&) const
{
x3::skip_over(first, last, context);
return true;
}
inline semantic_predicate operator()(bool predicate) const
{
return { predicate };
}
template <typename F>
lazy_semantic_predicate<F> operator()(F f) const
{
return { f };
}
};
auto const eps = eps_parser{};
}}}
#endif
@@ -0,0 +1,69 @@
/*=============================================================================
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_GUARD_FERBRUARY_02_2013_0649PM)
#define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
namespace boost { namespace spirit { namespace x3
{
enum class error_handler_result
{
fail
, retry
, accept
, rethrow
};
template <typename Subject, typename Handler>
struct guard : unary_parser<Subject, guard<Subject, Handler>>
{
typedef unary_parser<Subject, guard<Subject, Handler>> base_type;
static bool const is_pass_through_unary = true;
guard(Subject const& subject, Handler handler)
: base_type(subject), handler(handler) {}
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr) const
{
for (;;)
{
try
{
Iterator i = first;
bool r = this->subject.parse(i, last, context, rcontext, attr);
if (r)
first = i;
return r;
}
catch (expectation_failure<Iterator> const& x)
{
switch (handler(first, last, x, context))
{
case error_handler_result::fail:
return false;
case error_handler_result::retry:
continue;
case error_handler_result::accept:
return true;
case error_handler_result::rethrow:
throw;
}
}
}
return false;
}
Handler handler;
};
}}}
#endif
@@ -0,0 +1,16 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
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_BINARY_MAY_08_2007_0906AM)
#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0906AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/binary/binary.hpp>
#endif
@@ -0,0 +1,176 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 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_BINARY_MAY_08_2007_0808AM)
#define BOOST_SPIRIT_X3_BINARY_MAY_08_2007_0808AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <cstdint>
#include <boost/endian/conversion.hpp>
#include <boost/endian/arithmetic.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/config.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename V, typename T
, boost::endian::order endian, std::size_t bits>
struct binary_lit_parser
: parser<binary_lit_parser<V, T, endian, bits> >
{
static bool const has_attribute = false;
typedef unused_type attribute_type;
binary_lit_parser(V n_)
: n(n_) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, Attribute& attr_param) const
{
x3::skip_over(first, last, context);
auto bytes = reinterpret_cast<const unsigned char*>(&n);
Iterator it = first;
for (unsigned int i = 0; i < sizeof(n); ++i)
{
if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
return false;
}
first = it;
x3::traits::move_to(n, attr_param);
return true;
}
boost::endian::endian_arithmetic<endian, T, bits> n;
};
///////////////////////////////////////////////////////////////////////////
template <typename T, boost::endian::order endian, std::size_t bits>
struct any_binary_parser : parser<any_binary_parser<T, endian, bits > >
{
typedef T attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, Attribute& attr_param) const
{
x3::skip_over(first, last, context);
attribute_type attr_;
auto bytes = reinterpret_cast<unsigned char*>(&attr_);
Iterator it = first;
for (unsigned int i = 0; i < sizeof(attr_); ++i)
{
if (it == last)
return false;
*bytes++ = *it++;
}
first = it;
x3::traits::move_to(
endian::conditional_reverse<endian, endian::order::native>(attr_)
, attr_param );
return true;
}
template <typename V>
binary_lit_parser< V, T, endian, bits> operator()(V n) const
{
return {n};
}
};
#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();
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, uint_least8_t, 8)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, uint_least16_t, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, uint_least16_t, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, uint_least16_t, 16)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, uint_least32_t, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, uint_least32_t, 32)
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, uint_least32_t, 32)
#ifdef BOOST_HAS_LONG_LONG
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, uint_least64_t, 64)
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
#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
///////////////////////////////////////////////////////////////////////////
template <typename T, std::size_t bits>
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
{
return "little-endian binary";
}
};
template <typename T, std::size_t bits>
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
{
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>>
{
typedef std::string result_type;
std::string operator()(binary_lit_parser<V, T, endian::order::little, bits> const& p) 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>>
{
typedef std::string result_type;
std::string operator()(binary_lit_parser<V, T, endian::order::big, bits> const& p) const
{
return "big-endian binary";
}
};
}}}
#endif
@@ -0,0 +1,20 @@
/*=============================================================================
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_CHAR_FEBRUARY_02_2007_0921AM)
#define BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/negated_char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/char_class.hpp>
#include <boost/spirit/home/x3/char/char_set.hpp>
#if defined(BOOST_SPIRIT_X3_UNICODE)
#include <boost/spirit/home/x3/char/unicode.hpp>
#endif
#endif
@@ -0,0 +1,68 @@
/*=============================================================================
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_ANY_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM
#include <boost/type_traits/extent.hpp>
#include <boost/spirit/home/x3/char/literal_char.hpp>
#include <boost/spirit/home/x3/char/char_set.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding>
struct any_char : char_parser<any_char<Encoding>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
}
template <typename Char>
literal_char<Encoding> operator()(Char ch) const
{
return { ch };
}
template <typename Char>
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
{
return { ch };
}
template <typename Char>
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
{
return { static_cast<char_type>(from[0]), static_cast<char_type>(to[0]) };
}
template <typename Char>
char_set<Encoding> operator()(std::basic_string<Char> const& s) const
{
return { s };
}
};
}}}
#endif
@@ -0,0 +1,155 @@
/*=============================================================================
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_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM
#include <boost/spirit/home/x3/char/any_char.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
namespace boost { namespace spirit { namespace x3
{
namespace standard
{
typedef any_char<char_encoding::standard> char_type;
auto const char_ = char_type{};
inline literal_char<char_encoding::standard, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::standard, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
using standard::char_type;
using standard::char_;
using standard::lit;
namespace standard_wide
{
typedef any_char<char_encoding::standard_wide> char_type;
auto const char_ = char_type{};
inline literal_char<char_encoding::standard_wide, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
namespace ascii
{
typedef any_char<char_encoding::ascii> char_type;
auto const char_ = char_type{};
inline literal_char<char_encoding::ascii, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::ascii, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
namespace iso8859_1
{
typedef any_char<char_encoding::iso8859_1> char_type;
auto const char_ = char_type{};
inline literal_char<char_encoding::iso8859_1, unused_type>
lit(char ch)
{
return { ch };
}
inline literal_char<char_encoding::iso8859_1, unused_type>
lit(wchar_t ch)
{
return { ch };
}
}
namespace extension
{
template <>
struct as_parser<char>
{
typedef literal_char<
char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char ch)
{
return { ch };
}
};
template <>
struct as_parser<wchar_t>
{
typedef literal_char<
char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static type call(wchar_t ch)
{
return { ch };
}
};
template <>
struct as_parser<char [2]>
{
typedef literal_char<
char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char const ch[])
{
return { ch[0] };
}
};
template <>
struct as_parser<wchar_t [2]>
{
typedef literal_char<
char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static type call(wchar_t const ch[] )
{
return { ch[0] };
}
};
}
}}}
#endif
@@ -0,0 +1,130 @@
/*=============================================================================
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_CHAR_CLASS_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <typename Encoding>
struct char_class_base
{
typedef typename Encoding::char_type char_type;
#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)); \
} \
/***/
BOOST_SPIRIT_X3_CLASSIFY(char)
BOOST_SPIRIT_X3_CLASSIFY(alnum)
BOOST_SPIRIT_X3_CLASSIFY(alpha)
BOOST_SPIRIT_X3_CLASSIFY(digit)
BOOST_SPIRIT_X3_CLASSIFY(xdigit)
BOOST_SPIRIT_X3_CLASSIFY(cntrl)
BOOST_SPIRIT_X3_CLASSIFY(graph)
BOOST_SPIRIT_X3_CLASSIFY(lower)
BOOST_SPIRIT_X3_CLASSIFY(print)
BOOST_SPIRIT_X3_CLASSIFY(punct)
BOOST_SPIRIT_X3_CLASSIFY(space)
BOOST_SPIRIT_X3_CLASSIFY(blank)
BOOST_SPIRIT_X3_CLASSIFY(upper)
#undef BOOST_SPIRIT_X3_CLASSIFY
};
template <typename Encoding, typename Tag>
struct char_class
: char_parser<char_class<Encoding, Tag>>
{
typedef Encoding encoding;
typedef Tag tag;
typedef typename Encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch, Context const& context) const
{
return ((sizeof(Char) <= sizeof(char_type)) || 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(); \
/***/
#define BOOST_SPIRIT_X3_CHAR_CLASSES(encoding) \
namespace encoding \
{ \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alnum) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alpha) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, digit) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, xdigit) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, cntrl) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, graph) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, lower) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, print) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, punct) \
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)
BOOST_SPIRIT_X3_CHAR_CLASSES(standard_wide)
BOOST_SPIRIT_X3_CHAR_CLASSES(ascii)
BOOST_SPIRIT_X3_CHAR_CLASSES(iso8859_1)
#undef BOOST_SPIRIT_X3_CHAR_CLASS
#undef BOOST_SPIRIT_X3_CHAR_CLASSES
using standard::alnum_type;
using standard::alpha_type;
using standard::digit_type;
using standard::xdigit_type;
using standard::cntrl_type;
using standard::graph_type;
using standard::lower_type;
using standard::print_type;
using standard::punct_type;
using standard::space_type;
using standard::blank_type;
using standard::upper_type;
using standard::alnum;
using standard::alpha;
using standard::digit;
using standard::xdigit;
using standard::cntrl;
using standard::graph;
using standard::lower;
using standard::print;
using standard::punct;
using standard::space;
using standard::blank;
using standard::upper;
}}}
#endif
@@ -0,0 +1,29 @@
/*=============================================================================
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_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_CLASS_TAGS_APRIL_16_2006_1051AM
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
struct char_tag {};
struct alnum_tag {};
struct alpha_tag {};
struct blank_tag {};
struct cntrl_tag {};
struct digit_tag {};
struct graph_tag {};
struct print_tag {};
struct punct_tag {};
struct space_tag {};
struct xdigit_tag {};
struct lower_tag {};
struct upper_tag {};
}}}
#endif
@@ -0,0 +1,40 @@
/*=============================================================================
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_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// The base char_parser
///////////////////////////////////////////////////////////////////////////
template <typename Derived>
struct char_parser : parser<Derived>
{
template <typename Iterator, typename Context, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (first != last && this->derived().test(*first, context))
{
x3::traits::move_to(*first, attr);
++first;
return true;
}
return false;
}
};
}}}
#endif
@@ -0,0 +1,136 @@
/*=============================================================================
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_CHAR_SET_OCT_12_2014_1051AM)
#define BOOST_SPIRIT_X3_CHAR_SET_OCT_12_2014_1051AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/support/char_set/basic_chset.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Parser for a character range
///////////////////////////////////////////////////////////////////////////
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct char_range
: char_parser< char_range<Encoding, Attribute> >
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
char_range(char_type from_, char_type to_)
: from(from_), to(to_) {}
template <typename Char, typename Context>
bool test(Char ch_, Context& context) const
{
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 );
}
char_type from, to;
};
///////////////////////////////////////////////////////////////////////////
// Parser for a character set
///////////////////////////////////////////////////////////////////////////
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct char_set : char_parser<char_set<Encoding, Attribute>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template <typename String>
char_set(String const& str)
{
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++;
while (ch)
{
in_type next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
chset.set(cast_char<char_type>(ch));
chset.set('-');
break;
}
chset.set(
cast_char<char_type>(ch),
cast_char<char_type>(next)
);
}
else
{
chset.set(cast_char<char_type>(ch));
}
ch = next;
}
}
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);
}
support::detail::basic_chset<char_type> chset;
};
template <typename Encoding, typename Attribute>
struct get_info<char_set<Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(char_set<Encoding, Attribute> const& p) const
{
return "char-set";
}
};
template <typename Encoding, typename Attribute>
struct get_info<char_range<Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(char_range<Encoding, Attribute> const& p) const
{
return "char_range \"" + to_utf8(Encoding::toucs4(p.from)) + '-' + to_utf8(Encoding::toucs4(p.to))+ '"';
}
};
}}}
#endif
@@ -0,0 +1,54 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_CAST_CHAR_NOVEMBER_10_2006_0907AM)
#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/make_signed.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// Here's the thing... typical encodings (except ASCII) deal with unsigned
// integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.
// Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you
// cast this to an unsigned int with 32 bits, you get 4294967273!
//
// The trick is to cast to an unsigned version of the source char first
// before casting to the target. {P.S. Don't worry about the code, the
// optimizer will optimize the if-else branches}
template <typename TargetChar, typename SourceChar>
TargetChar cast_char(SourceChar ch)
{
if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
{
if (is_signed<SourceChar>::value)
{
// source is signed, target is unsigned
typedef typename make_unsigned<SourceChar>::type USourceChar;
return TargetChar(USourceChar(ch));
}
else
{
// source is unsigned, target is signed
typedef typename make_signed<SourceChar>::type SSourceChar;
return TargetChar(SSourceChar(ch));
}
}
else
{
// source and target has same signedness
return TargetChar(ch); // just cast
}
}
}}}}
#endif
@@ -0,0 +1,50 @@
/*=============================================================================
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_LITERAL_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct literal_char : char_parser<literal_char<Encoding, Attribute>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template <typename Char>
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);
}
char_type ch;
};
template <typename Encoding, typename Attribute>
struct get_info<literal_char<Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(literal_char<Encoding, Attribute> const& p) const
{
return '\'' + to_utf8(Encoding::toucs4(p.ch)) + '\'';
}
};
}}}
#endif
@@ -0,0 +1,61 @@
/*=============================================================================
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_NEGATED_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/char/char_parser.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// negated_char_parser handles ~cp expressions (cp is a char_parser)
///////////////////////////////////////////////////////////////////////////
template <typename Positive>
struct negated_char_parser :
char_parser<negated_char_parser<Positive>>
{
negated_char_parser(Positive const& positive)
: positive(positive) {}
template <typename CharParam, typename Context>
bool test(CharParam ch, Context const& context) const
{
return !positive.test(ch, context);
}
Positive positive;
};
template <typename Positive>
inline negated_char_parser<Positive>
operator~(char_parser<Positive> const& cp)
{
return { cp.derived() };
}
template <typename Positive>
inline Positive const&
operator~(negated_char_parser<Positive> const& cp)
{
return cp.positive;
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Positive, typename Context>
struct attribute_of<x3::negated_char_parser<Positive>, Context>
: attribute_of<Positive, Context> {};
template <typename Positive, typename Context>
struct has_attribute<x3::negated_char_parser<Positive>, Context>
: has_attribute<Positive, Context> {};
}}}}
#endif
@@ -0,0 +1,613 @@
/*=============================================================================
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_UNICODE_JAN_20_2012_1218AM)
#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/support/char_encoding/unicode.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct char_tag;
struct alnum_tag;
struct alpha_tag;
struct blank_tag;
struct cntrl_tag;
struct digit_tag;
struct graph_tag;
struct print_tag;
struct punct_tag;
struct space_tag;
struct xdigit_tag;
struct lower_tag;
struct upper_tag;
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct letter_tag {};
struct mark_tag {};
struct number_tag {};
struct separator_tag {};
struct other_tag {};
struct punctuation_tag {};
struct symbol_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
struct uppercase_letter_tag {};
struct lowercase_letter_tag {};
struct titlecase_letter_tag {};
struct modifier_letter_tag {};
struct other_letter_tag {};
struct nonspacing_mark_tag {};
struct enclosing_mark_tag {};
struct spacing_mark_tag {};
struct decimal_number_tag {};
struct letter_number_tag {};
struct other_number_tag {};
struct space_separator_tag {};
struct line_separator_tag {};
struct paragraph_separator_tag {};
struct control_tag {};
struct format_tag {};
struct private_use_tag {};
struct surrogate_tag {};
struct unassigned_tag {};
struct dash_punctuation_tag {};
struct open_punctuation_tag {};
struct close_punctuation_tag {};
struct connector_punctuation_tag {};
struct other_punctuation_tag {};
struct initial_punctuation_tag {};
struct final_punctuation_tag {};
struct math_symbol_tag {};
struct currency_symbol_tag {};
struct modifier_symbol_tag {};
struct other_symbol_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
struct alphabetic_tag {};
struct uppercase_tag {};
struct lowercase_tag {};
struct white_space_tag {};
struct hex_digit_tag {};
struct noncharacter_code_point_tag {};
struct default_ignorable_code_point_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
struct arabic_tag {};
struct imperial_aramaic_tag {};
struct armenian_tag {};
struct avestan_tag {};
struct balinese_tag {};
struct bamum_tag {};
struct bengali_tag {};
struct bopomofo_tag {};
struct braille_tag {};
struct buginese_tag {};
struct buhid_tag {};
struct canadian_aboriginal_tag {};
struct carian_tag {};
struct cham_tag {};
struct cherokee_tag {};
struct coptic_tag {};
struct cypriot_tag {};
struct cyrillic_tag {};
struct devanagari_tag {};
struct deseret_tag {};
struct egyptian_hieroglyphs_tag {};
struct ethiopic_tag {};
struct georgian_tag {};
struct glagolitic_tag {};
struct gothic_tag {};
struct greek_tag {};
struct gujarati_tag {};
struct gurmukhi_tag {};
struct hangul_tag {};
struct han_tag {};
struct hanunoo_tag {};
struct hebrew_tag {};
struct hiragana_tag {};
struct katakana_or_hiragana_tag {};
struct old_italic_tag {};
struct javanese_tag {};
struct kayah_li_tag {};
struct katakana_tag {};
struct kharoshthi_tag {};
struct khmer_tag {};
struct kannada_tag {};
struct kaithi_tag {};
struct tai_tham_tag {};
struct lao_tag {};
struct latin_tag {};
struct lepcha_tag {};
struct limbu_tag {};
struct linear_b_tag {};
struct lisu_tag {};
struct lycian_tag {};
struct lydian_tag {};
struct malayalam_tag {};
struct mongolian_tag {};
struct meetei_mayek_tag {};
struct myanmar_tag {};
struct nko_tag {};
struct ogham_tag {};
struct ol_chiki_tag {};
struct old_turkic_tag {};
struct oriya_tag {};
struct osmanya_tag {};
struct phags_pa_tag {};
struct inscriptional_pahlavi_tag {};
struct phoenician_tag {};
struct inscriptional_parthian_tag {};
struct rejang_tag {};
struct runic_tag {};
struct samaritan_tag {};
struct old_south_arabian_tag {};
struct saurashtra_tag {};
struct shavian_tag {};
struct sinhala_tag {};
struct sundanese_tag {};
struct syloti_nagri_tag {};
struct syriac_tag {};
struct tagbanwa_tag {};
struct tai_le_tag {};
struct new_tai_lue_tag {};
struct tamil_tag {};
struct tai_viet_tag {};
struct telugu_tag {};
struct tifinagh_tag {};
struct tagalog_tag {};
struct thaana_tag {};
struct thai_tag {};
struct tibetan_tag {};
struct ugaritic_tag {};
struct vai_tag {};
struct old_persian_tag {};
struct cuneiform_tag {};
struct yi_tag {};
struct inherited_tag {};
struct common_tag {};
struct unknown_tag {};
///////////////////////////////////////////////////////////////////////////
struct unicode_char_class_base
{
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_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)); \
} \
/***/
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_BASIC_CLASSIFY(char)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alnum)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alpha)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(digit)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(xdigit)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(cntrl)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(graph)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(lower)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(print)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(punct)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(space)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(blank)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(upper)
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(letter)
BOOST_SPIRIT_X3_CLASSIFY(mark)
BOOST_SPIRIT_X3_CLASSIFY(number)
BOOST_SPIRIT_X3_CLASSIFY(separator)
BOOST_SPIRIT_X3_CLASSIFY(other)
BOOST_SPIRIT_X3_CLASSIFY(punctuation)
BOOST_SPIRIT_X3_CLASSIFY(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(uppercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(lowercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(titlecase_letter)
BOOST_SPIRIT_X3_CLASSIFY(modifier_letter)
BOOST_SPIRIT_X3_CLASSIFY(other_letter)
BOOST_SPIRIT_X3_CLASSIFY(nonspacing_mark)
BOOST_SPIRIT_X3_CLASSIFY(enclosing_mark)
BOOST_SPIRIT_X3_CLASSIFY(spacing_mark)
BOOST_SPIRIT_X3_CLASSIFY(decimal_number)
BOOST_SPIRIT_X3_CLASSIFY(letter_number)
BOOST_SPIRIT_X3_CLASSIFY(other_number)
BOOST_SPIRIT_X3_CLASSIFY(space_separator)
BOOST_SPIRIT_X3_CLASSIFY(line_separator)
BOOST_SPIRIT_X3_CLASSIFY(paragraph_separator)
BOOST_SPIRIT_X3_CLASSIFY(control)
BOOST_SPIRIT_X3_CLASSIFY(format)
BOOST_SPIRIT_X3_CLASSIFY(private_use)
BOOST_SPIRIT_X3_CLASSIFY(surrogate)
BOOST_SPIRIT_X3_CLASSIFY(unassigned)
BOOST_SPIRIT_X3_CLASSIFY(dash_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(open_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(close_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(connector_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(other_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(initial_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(final_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(math_symbol)
BOOST_SPIRIT_X3_CLASSIFY(currency_symbol)
BOOST_SPIRIT_X3_CLASSIFY(modifier_symbol)
BOOST_SPIRIT_X3_CLASSIFY(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(alphabetic)
BOOST_SPIRIT_X3_CLASSIFY(uppercase)
BOOST_SPIRIT_X3_CLASSIFY(lowercase)
BOOST_SPIRIT_X3_CLASSIFY(white_space)
BOOST_SPIRIT_X3_CLASSIFY(hex_digit)
BOOST_SPIRIT_X3_CLASSIFY(noncharacter_code_point)
BOOST_SPIRIT_X3_CLASSIFY(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
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(bengali)
BOOST_SPIRIT_X3_CLASSIFY(bopomofo)
BOOST_SPIRIT_X3_CLASSIFY(braille)
BOOST_SPIRIT_X3_CLASSIFY(buginese)
BOOST_SPIRIT_X3_CLASSIFY(buhid)
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(coptic)
BOOST_SPIRIT_X3_CLASSIFY(cypriot)
BOOST_SPIRIT_X3_CLASSIFY(cyrillic)
BOOST_SPIRIT_X3_CLASSIFY(devanagari)
BOOST_SPIRIT_X3_CLASSIFY(deseret)
BOOST_SPIRIT_X3_CLASSIFY(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CLASSIFY(ethiopic)
BOOST_SPIRIT_X3_CLASSIFY(georgian)
BOOST_SPIRIT_X3_CLASSIFY(glagolitic)
BOOST_SPIRIT_X3_CLASSIFY(gothic)
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(hebrew)
BOOST_SPIRIT_X3_CLASSIFY(hiragana)
BOOST_SPIRIT_X3_CLASSIFY(katakana_or_hiragana)
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(kharoshthi)
BOOST_SPIRIT_X3_CLASSIFY(khmer)
BOOST_SPIRIT_X3_CLASSIFY(kannada)
BOOST_SPIRIT_X3_CLASSIFY(kaithi)
BOOST_SPIRIT_X3_CLASSIFY(tai_tham)
BOOST_SPIRIT_X3_CLASSIFY(lao)
BOOST_SPIRIT_X3_CLASSIFY(latin)
BOOST_SPIRIT_X3_CLASSIFY(lepcha)
BOOST_SPIRIT_X3_CLASSIFY(limbu)
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(malayalam)
BOOST_SPIRIT_X3_CLASSIFY(mongolian)
BOOST_SPIRIT_X3_CLASSIFY(meetei_mayek)
BOOST_SPIRIT_X3_CLASSIFY(myanmar)
BOOST_SPIRIT_X3_CLASSIFY(nko)
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(osmanya)
BOOST_SPIRIT_X3_CLASSIFY(phags_pa)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CLASSIFY(phoenician)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_parthian)
BOOST_SPIRIT_X3_CLASSIFY(rejang)
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(shavian)
BOOST_SPIRIT_X3_CLASSIFY(sinhala)
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(tai_le)
BOOST_SPIRIT_X3_CLASSIFY(new_tai_lue)
BOOST_SPIRIT_X3_CLASSIFY(tamil)
BOOST_SPIRIT_X3_CLASSIFY(tai_viet)
BOOST_SPIRIT_X3_CLASSIFY(telugu)
BOOST_SPIRIT_X3_CLASSIFY(tifinagh)
BOOST_SPIRIT_X3_CLASSIFY(tagalog)
BOOST_SPIRIT_X3_CLASSIFY(thaana)
BOOST_SPIRIT_X3_CLASSIFY(thai)
BOOST_SPIRIT_X3_CLASSIFY(tibetan)
BOOST_SPIRIT_X3_CLASSIFY(ugaritic)
BOOST_SPIRIT_X3_CLASSIFY(vai)
BOOST_SPIRIT_X3_CLASSIFY(old_persian)
BOOST_SPIRIT_X3_CLASSIFY(cuneiform)
BOOST_SPIRIT_X3_CLASSIFY(yi)
BOOST_SPIRIT_X3_CLASSIFY(inherited)
BOOST_SPIRIT_X3_CLASSIFY(common)
BOOST_SPIRIT_X3_CLASSIFY(unknown)
#undef BOOST_SPIRIT_X3_BASIC_CLASSIFY
#undef BOOST_SPIRIT_X3_CLASSIFY
};
template <typename Tag>
struct unicode_char_class
: char_parser<unicode_char_class<Tag>>
{
typedef char_encoding::unicode encoding;
typedef Tag tag;
typedef typename encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || 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(); \
/***/
namespace unicode
{
typedef any_char<char_encoding::unicode> char_type;
auto const char_ = char_type{};
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alnum)
BOOST_SPIRIT_X3_CHAR_CLASS(alpha)
BOOST_SPIRIT_X3_CHAR_CLASS(digit)
BOOST_SPIRIT_X3_CHAR_CLASS(xdigit)
BOOST_SPIRIT_X3_CHAR_CLASS(cntrl)
BOOST_SPIRIT_X3_CHAR_CLASS(graph)
BOOST_SPIRIT_X3_CHAR_CLASS(lower)
BOOST_SPIRIT_X3_CHAR_CLASS(print)
BOOST_SPIRIT_X3_CHAR_CLASS(punct)
BOOST_SPIRIT_X3_CHAR_CLASS(space)
BOOST_SPIRIT_X3_CHAR_CLASS(blank)
BOOST_SPIRIT_X3_CHAR_CLASS(upper)
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(letter)
BOOST_SPIRIT_X3_CHAR_CLASS(mark)
BOOST_SPIRIT_X3_CHAR_CLASS(number)
BOOST_SPIRIT_X3_CHAR_CLASS(separator)
BOOST_SPIRIT_X3_CHAR_CLASS(other)
BOOST_SPIRIT_X3_CHAR_CLASS(punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(titlecase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(modifier_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(other_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(nonspacing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(enclosing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(spacing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(decimal_number)
BOOST_SPIRIT_X3_CHAR_CLASS(letter_number)
BOOST_SPIRIT_X3_CHAR_CLASS(other_number)
BOOST_SPIRIT_X3_CHAR_CLASS(space_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(line_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(paragraph_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(control)
BOOST_SPIRIT_X3_CHAR_CLASS(format)
BOOST_SPIRIT_X3_CHAR_CLASS(private_use)
BOOST_SPIRIT_X3_CHAR_CLASS(surrogate)
BOOST_SPIRIT_X3_CHAR_CLASS(unassigned)
BOOST_SPIRIT_X3_CHAR_CLASS(dash_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(open_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(close_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(connector_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(other_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(initial_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(final_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(math_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(currency_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(modifier_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alphabetic)
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase)
BOOST_SPIRIT_X3_CHAR_CLASS(white_space)
BOOST_SPIRIT_X3_CHAR_CLASS(hex_digit)
BOOST_SPIRIT_X3_CHAR_CLASS(noncharacter_code_point)
BOOST_SPIRIT_X3_CHAR_CLASS(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
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(bengali)
BOOST_SPIRIT_X3_CHAR_CLASS(bopomofo)
BOOST_SPIRIT_X3_CHAR_CLASS(braille)
BOOST_SPIRIT_X3_CHAR_CLASS(buginese)
BOOST_SPIRIT_X3_CHAR_CLASS(buhid)
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(coptic)
BOOST_SPIRIT_X3_CHAR_CLASS(cypriot)
BOOST_SPIRIT_X3_CHAR_CLASS(cyrillic)
BOOST_SPIRIT_X3_CHAR_CLASS(devanagari)
BOOST_SPIRIT_X3_CHAR_CLASS(deseret)
BOOST_SPIRIT_X3_CHAR_CLASS(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CHAR_CLASS(ethiopic)
BOOST_SPIRIT_X3_CHAR_CLASS(georgian)
BOOST_SPIRIT_X3_CHAR_CLASS(glagolitic)
BOOST_SPIRIT_X3_CHAR_CLASS(gothic)
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(hebrew)
BOOST_SPIRIT_X3_CHAR_CLASS(hiragana)
BOOST_SPIRIT_X3_CHAR_CLASS(katakana_or_hiragana)
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(kharoshthi)
BOOST_SPIRIT_X3_CHAR_CLASS(khmer)
BOOST_SPIRIT_X3_CHAR_CLASS(kannada)
BOOST_SPIRIT_X3_CHAR_CLASS(kaithi)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_tham)
BOOST_SPIRIT_X3_CHAR_CLASS(lao)
BOOST_SPIRIT_X3_CHAR_CLASS(latin)
BOOST_SPIRIT_X3_CHAR_CLASS(lepcha)
BOOST_SPIRIT_X3_CHAR_CLASS(limbu)
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(malayalam)
BOOST_SPIRIT_X3_CHAR_CLASS(mongolian)
BOOST_SPIRIT_X3_CHAR_CLASS(meetei_mayek)
BOOST_SPIRIT_X3_CHAR_CLASS(myanmar)
BOOST_SPIRIT_X3_CHAR_CLASS(nko)
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(osmanya)
BOOST_SPIRIT_X3_CHAR_CLASS(phags_pa)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CHAR_CLASS(phoenician)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_parthian)
BOOST_SPIRIT_X3_CHAR_CLASS(rejang)
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(shavian)
BOOST_SPIRIT_X3_CHAR_CLASS(sinhala)
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(tai_le)
BOOST_SPIRIT_X3_CHAR_CLASS(new_tai_lue)
BOOST_SPIRIT_X3_CHAR_CLASS(tamil)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_viet)
BOOST_SPIRIT_X3_CHAR_CLASS(telugu)
BOOST_SPIRIT_X3_CHAR_CLASS(tifinagh)
BOOST_SPIRIT_X3_CHAR_CLASS(tagalog)
BOOST_SPIRIT_X3_CHAR_CLASS(thaana)
BOOST_SPIRIT_X3_CHAR_CLASS(thai)
BOOST_SPIRIT_X3_CHAR_CLASS(tibetan)
BOOST_SPIRIT_X3_CHAR_CLASS(ugaritic)
BOOST_SPIRIT_X3_CHAR_CLASS(vai)
BOOST_SPIRIT_X3_CHAR_CLASS(old_persian)
BOOST_SPIRIT_X3_CHAR_CLASS(cuneiform)
BOOST_SPIRIT_X3_CHAR_CLASS(yi)
BOOST_SPIRIT_X3_CHAR_CLASS(inherited)
BOOST_SPIRIT_X3_CHAR_CLASS(common)
BOOST_SPIRIT_X3_CHAR_CLASS(unknown)
}
#undef BOOST_SPIRIT_X3_CHAR_CLASS
}}}
#endif
@@ -0,0 +1,16 @@
/*=============================================================================
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_CORE_APRIL_04_2012_0318PM)
#define BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM
#include <boost/spirit/home/x3/core/parse.hpp>
//~ #include <boost/spirit/home/x3/core/parse_attr.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/action.hpp>
#endif
@@ -0,0 +1,116 @@
/*=============================================================================
Copyright (arg) 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(SPIRIT_ACTION_JANUARY_07_2007_1128AM)
#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.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>
namespace boost { namespace spirit { namespace x3
{
struct raw_attribute_type;
struct parse_pass_context_tag;
template <typename Context>
inline bool& _pass(Context const& context)
{
return x3::get<parse_pass_context_tag>(context);
}
template <typename Subject, typename Action>
struct action : unary_parser<Subject, action<Subject, Action>>
{
typedef unary_parser<Subject, action<Subject, Action>> base_type;
static bool const is_pass_through_unary = true;
static bool const has_action = true;
action(Subject const& subject, Action f)
: base_type(subject), f(f) {}
template <typename Iterator, typename Context, typename RuleContext, typename Attribute>
bool call_action(
Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr) const
{
bool pass = true;
auto action_context = make_context<parse_pass_context_tag>(pass, context);
call(f, first, last, action_context, rcontext, attr);
return pass;
}
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse_main(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr) const
{
Iterator save = first;
if (this->subject.parse(first, last, context, rcontext, attr))
{
if (call_action(first, last, context, rcontext, attr))
return true;
// reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
// attr==raw_attribute_type, action wants iterator_range (see raw.hpp)
template <typename Iterator, typename Context, typename RuleContext>
bool parse_main(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, raw_attribute_type&) const
{
boost::iterator_range<Iterator> rng;
// synthesize the attribute since one is not supplied
return parse_main(first, last, context, rcontext, rng);
}
// attr==unused, action wants attribute
template <typename Iterator, typename Context, typename RuleContext>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, unused_type) const
{
typedef typename
traits::attribute_of<action<Subject, Action>, Context>::type
attribute_type;
typedef traits::make_attribute<attribute_type, unused_type> make_attribute;
typedef traits::transform_attribute<
typename make_attribute::type, attribute_type, parser_id>
transform;
// synthesize the attribute since one is not supplied
typename make_attribute::type made_attr = make_attribute::call(unused_type());
typename transform::type attr = transform::pre(made_attr);
return parse_main(first, last, context, rcontext, attr);
}
// main parse function
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr) const
{
return parse_main(first, last, context, rcontext, attr);
}
Action f;
};
template <typename P, typename Action>
inline action<typename extension::as_parser<P>::value_type, Action>
operator/(P const& p, Action f)
{
return { as_parser(p), f };
}
}}}
#endif
@@ -0,0 +1,76 @@
/*=============================================================================
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(SPIRIT_CALL_CONTEXT_MAY_26_2014_0234PM)
#define SPIRIT_CALL_CONTEXT_MAY_26_2014_0234PM
#include <type_traits>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/utility/is_callable.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit { namespace x3
{
////////////////////////////////////////////////////////////////////////////
struct rule_val_context_tag;
template <typename Context>
inline decltype(auto) _val(Context const& context)
{
return x3::get<rule_val_context_tag>(context);
}
////////////////////////////////////////////////////////////////////////////
struct where_context_tag;
template <typename Context>
inline decltype(auto) _where(Context const& context)
{
return x3::get<where_context_tag>(context);
}
////////////////////////////////////////////////////////////////////////////
struct attr_context_tag;
template <typename Context>
inline decltype(auto) _attr(Context const& context)
{
return x3::get<attr_context_tag>(context);
}
////////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename F, typename Context>
auto call(F f, Context const& context, mpl::true_)
{
return f(context);
}
template <typename F, typename Context>
auto call(F f, Context const& context, mpl::false_)
{
return f();
}
}
template <
typename F, typename Iterator
, typename Context, typename RuleContext, typename Attribute>
auto call(
F f, Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr)
{
boost::iterator_range<Iterator> rng(first, last);
auto val_context = make_context<rule_val_context_tag>(rcontext, context);
auto where_context = make_context<where_context_tag>(rng, val_context);
auto attr_context = make_context<attr_context_tag>(attr, where_context);
return detail::call(f, attr_context, is_callable<F(decltype(attr_context) const&)>());
}
}}}
#endif
@@ -0,0 +1,293 @@
/*=============================================================================
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(SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM)
#define SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM
#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/handles_container.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/mpl/and.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/back.hpp>
#include <boost/variant/apply_visitor.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Attribute, typename Value>
struct saver_visitor;
// save to associative fusion container where Key is simple type
template <typename Key, typename Enable = void>
struct save_to_assoc_attr
{
template <typename Value, typename Attribute>
static void call(const Key, Value& value, Attribute& attr)
{
traits::move_to(value, fusion::at_key<Key>(attr));
}
};
/* $$$ clang reports: warning: class template partial specialization contains
* a template parameter that can not be deduced; this partial specialization
* will never be used $$$
*
// save to associative fusion container where Key
// is variant over possible keys
template <typename ...T>
struct save_to_assoc_attr<variant<T...> >
{
typedef variant<T...> variant_t;
template <typename Value, typename Attribute>
static void call(const variant_t key, Value& value, Attribute& attr)
{
apply_visitor(saver_visitor<Attribute, Value>(attr, value), key);
}
};
*/
template <typename Attribute, typename Value>
struct saver_visitor : boost::static_visitor<void>
{
saver_visitor(Attribute& attr, Value& value)
: attr(attr), value(value) {};
Attribute& attr;
Value& value;
template <typename Key>
void operator()(Key) const
{
save_to_assoc_attr<Key>::call(Key(), value,attr);
}
};
template <typename Parser, typename Container, typename Context>
struct parser_accepts_container
: traits::is_substitute<
typename traits::attribute_of<Parser, Context>::type
, Container
>
{};
template <typename Parser>
struct parse_into_container_base_impl
{
private:
// Parser has attribute (synthesize; Attribute is a container)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
static bool call_synthesize_x(
Parser const& parser
, Iterator& first, Iterator const& last
, 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();
if (!parser.parse(first, last, context, rcontext, val))
return false;
// push the parsed value into our attribute
traits::push_back(attr, val);
return true;
}
// Parser has attribute (synthesize; Attribute is a container)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
static bool call_synthesize_x(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
{
return parser.parse(first, last, context, rcontext, attr);
}
// Parser has attribute (synthesize; Attribute is a container)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
static bool call_synthesize(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
typedef
parser_accepts_container<Parser, Attribute, Context>
parser_accepts_container;
return call_synthesize_x(parser, first, last, context, rcontext, attr
, parser_accepts_container());
}
// Parser has attribute (synthesize; Attribute is a single element fusion sequence)
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
static bool call_synthesize_into_fusion_seq(Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::false_ /* is_associative */)
{
static_assert(traits::has_size<Attribute, 1>::value,
"Expecting a single element fusion sequence");
return call_synthesize(parser, first, last, context, rcontext,
fusion::front(attr));
}
// Parser has attribute (synthesize; Attribute is fusion map sequence)
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call_synthesize_into_fusion_seq(
Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::true_ /*is_associative*/)
{
using attribute_type = typename traits::attribute_of<Parser, Context>::type;
static_assert(traits::has_size<attribute_type, 2>::value,
"To parse directly into fusion map parser must produce 2 element attr");
// use type of first element of attribute as key
using key = typename std::remove_reference<
typename fusion::result_of::front<attribute_type>::type>::type;
attribute_type attr_;
if (!parser.parse(first, last, context, rcontext, attr_))
return false;
save_to_assoc_attr<key>::call(fusion::front(attr_), fusion::back(attr_), attr);
return true;
}
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call_synthesize_dispatch_by_seq(Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::true_ /*is_sequence*/)
{
return call_synthesize_into_fusion_seq(
parser, first, last, context, rcontext, attr
, fusion::traits::is_associative<Attribute>());
}
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call_synthesize_dispatch_by_seq(Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::false_ /*is_sequence*/)
{
return call_synthesize(parser, first, last, context, rcontext, attr);
}
// Parser has attribute (synthesize)
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call(Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::true_)
{
return call_synthesize_dispatch_by_seq(parser, first, last, context, rcontext, attr
, fusion::traits::is_sequence<Attribute>());
}
// Parser has no attribute (pass unused)
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr, mpl::false_)
{
return parser.parse(first, last, context, rcontext, unused);
}
public:
template <typename Iterator, typename Context, typename RContext, typename Attribute>
static bool call(Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr)
{
return call(parser, first, last, context, rcontext, attr
, mpl::bool_<traits::has_attribute<Parser, Context>::value>());
}
};
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>
struct parser_attr_is_substitute_for_container_value
: traits::is_substitute<
typename traits::attribute_of<Parser, Context>::type
, typename traits::container_value<Container>::type
>
{};
template <typename Parser, typename Context, typename RContext>
struct parse_into_container_impl<Parser, Context, RContext,
typename enable_if<traits::handles_container<Parser, Context>>::type>
{
template <typename Iterator, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_)
{
return parse_into_container_base_impl<Parser>::call(
parser, first, last, context, rcontext, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_)
{
return parser.parse(first, last, context, rcontext, attr);
}
template <typename Iterator, typename Attribute>
static bool call(Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
typedef parser_accepts_container<
Parser, Attribute, Context>
parser_accepts_container;
typedef parser_attr_is_substitute_for_container_value<
Parser, Attribute, Context>
parser_attr_is_substitute_for_container_value;
typedef mpl::or_<
parser_accepts_container
, mpl::not_<parser_attr_is_substitute_for_container_value>>
pass_attibute_as_is;
return call(parser, first, last, context, rcontext, attr,
pass_attibute_as_is());
}
};
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_into_container(
Parser const& parser
, Iterator& first, Iterator const& last, Context const& context
, RContext& rcontext, Attribute& attr)
{
return parse_into_container_impl<Parser, Context, RContext>::call(
parser, first, last, context, rcontext, attr);
}
}}}}
#endif
@@ -0,0 +1,189 @@
/*=============================================================================
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_PARSE_APRIL_16_2006_0442PM)
#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/concept_check.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Attribute>
inline bool
parse_main(
Iterator& first
, Iterator last
, Parser const& p
, Attribute& attr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function. You need to supply at least a forward_iterator
// instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// If you get an error no matching function for call to 'as_parser'
// here, then p is not a parser or there is no suitable conversion
// from p to a parser.
return as_parser(p).parse(first, last, unused, unused, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Attribute>
inline bool
parse(
Iterator& first
, Iterator last
, Parser const& p
, Attribute& attr)
{
return parse_main(first, last, p, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Attribute>
inline bool
parse(
Iterator const& first_
, Iterator last
, Parser const& p
, Attribute& attr)
{
Iterator first = first_;
return parse_main(first, last, p, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser>
inline bool
parse(
Iterator& first
, Iterator last
, Parser const& p)
{
return parse_main(first, last, p, unused);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser>
inline bool
parse(
Iterator const& first_
, Iterator last
, Parser const& p)
{
Iterator first = first_;
return parse_main(first, last, p, unused);
}
///////////////////////////////////////////////////////////////////////////
enum class skip_flag
{
post_skip, // force post-skipping in phrase_parse()
dont_post_skip // inhibit post-skipping in phrase_parse()
};
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
inline bool
phrase_parse_main(
Iterator& first
, Iterator last
, Parser const& p
, Skipper const& s
, Attribute& attr
, skip_flag post_skip = skip_flag::post_skip)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function. You need to supply at least a forward_iterator
// instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
static_assert(!std::is_same<Skipper, unused_type>::value,
"Error! Skipper cannot be unused_type.");
// If you get an error no matching function for call to 'as_parser'
// here, for either p or s, then p or s is not a parser or there is
// no suitable conversion from p to a parser.
auto skipper_ctx = make_context<skipper_tag>(as_parser(s));
bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr);
if (post_skip == skip_flag::post_skip)
x3::skip_over(first, last, skipper_ctx);
return r;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Parser const& p
, Skipper const& s
, Attribute& attr
, skip_flag post_skip = skip_flag::post_skip)
{
return phrase_parse_main(first, last, p, s, attr, post_skip);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Parser const& p
, Skipper const& s
, Attribute& attr
, skip_flag post_skip = skip_flag::post_skip)
{
Iterator first = first_;
return phrase_parse_main(first, last, p, s, attr, post_skip);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Parser const& p
, Skipper const& s
, skip_flag post_skip = skip_flag::post_skip)
{
return phrase_parse_main(first, last, p, s, unused, post_skip);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper>
inline bool
phrase_parse(
Iterator const& first_
, Iterator last
, Parser const& p
, Skipper const& s
, skip_flag post_skip = skip_flag::post_skip)
{
Iterator first = first_;
return phrase_parse_main(first, last, p, s, unused, post_skip);
}
///////////////////////////////////////////////////////////////////////////
template <typename Skipper>
struct phrase_parse_context
{
typedef decltype(
make_context<skipper_tag>(as_parser(std::declval<Skipper>())))
type;
};
}}}
#endif
@@ -0,0 +1,231 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_PARSER_OCTOBER_16_2008_0254PM)
#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
#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 <string>
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
#include <typeinfo>
#endif
namespace boost { namespace spirit { namespace x3
{
template <typename Subject, typename Action>
struct action;
template <typename Subject, typename Handler>
struct guard;
struct parser_base {};
struct parser_id;
template <typename Derived>
struct parser : parser_base
{
typedef Derived derived_type;
static bool const handles_container = false;
static bool const is_pass_through_unary = false;
static bool const has_action = false;
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
template <typename Action>
action<Derived, Action>
operator[](Action f) const
{
return action<Derived, Action>(this->derived(), f);
}
template <typename Handler>
guard<Derived, Handler>
on_error(Handler f) const
{
return guard<Derived, Handler>(this->derived(), f);
}
};
struct unary_category;
struct binary_category;
template <typename Subject, typename Derived>
struct unary_parser : parser<Derived>
{
typedef unary_category category;
typedef Subject subject_type;
static bool const has_action = Subject::has_action;
unary_parser(Subject const& subject)
: subject(subject) {}
unary_parser const& get_unary() const { return *this; }
Subject subject;
};
template <typename Left, typename Right, typename Derived>
struct binary_parser : parser<Derived>
{
typedef binary_category category;
typedef Left left_type;
typedef Right right_type;
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) {}
binary_parser const& get_binary() const { return *this; }
Left left;
Right right;
};
///////////////////////////////////////////////////////////////////////////
// as_parser: convert a type, T, into a parser.
///////////////////////////////////////////////////////////////////////////
namespace extension
{
namespace detail
{
namespace as_parser_guard
{
void as_spirit_parser(...);
template<typename T, typename R =
decltype(as_spirit_parser(boost::declval<T const&>()))>
struct deduce_as_parser
{
typedef R type;
typedef typename
boost::remove_cv<
typename boost::remove_reference<R>::type
>::type
value_type;
static type call(T const& v)
{
return as_spirit_parser(v);
}
};
template<typename T>
struct deduce_as_parser<T, void>
{};
}
using as_parser_guard::deduce_as_parser;
}
template <typename T, typename Enable = void>
struct as_parser : detail::deduce_as_parser<T> {};
template <>
struct as_parser<unused_type>
{
typedef unused_type type;
typedef unused_type value_type;
static type call(unused_type)
{
return unused;
}
};
template <typename Derived>
struct as_parser<Derived
, typename enable_if<is_base_of<parser_base, Derived>>::type>
{
typedef Derived const& type;
typedef Derived value_type;
static type call(Derived const& p)
{
return p;
}
};
template <typename Derived>
struct as_parser<parser<Derived>>
{
typedef Derived const& type;
typedef Derived value_type;
static type call(parser<Derived> const& p)
{
return p.derived();
}
};
}
template <typename T>
inline typename extension::as_parser<T>::type
as_parser(T const& x)
{
return extension::as_parser<T>::call(x);
}
template <typename Derived>
inline Derived const&
as_parser(parser<Derived> const& p)
{
return p.derived();
}
///////////////////////////////////////////////////////////////////////////
// The main what function
//
// Note: unlike Spirit2, spirit parsers are no longer required to have a
// "what" member function. In X3, we specialize the get_info struct
// below where needed. If a specialization is not provided, the default
// below will be used. The default "what" result will be the typeid
// name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
// "undefined"
///////////////////////////////////////////////////////////////////////////
template <typename Parser, typename Enable = void>
struct get_info
{
typedef std::string result_type;
std::string operator()(Parser const&) const
{
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
return typeid(Parser).name();
#else
return "undefined";
#endif
}
};
template <typename Parser>
std::string what(Parser const& p)
{
return get_info<Parser>()(p);
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Derived, typename Context>
struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
: has_attribute<Subject, Context> {};
template <typename Left, typename Right, typename Derived, typename Context>
struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
: mpl::bool_<has_attribute<Left, Context>::value ||
has_attribute<Right, Context>::value> {};
}}}}
#endif
@@ -0,0 +1,48 @@
/*=============================================================================
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_PROXY_FEBRUARY_1_2013_0211PM)
#define BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject, typename Derived>
struct proxy : unary_parser<Subject, Derived>
{
static bool const is_pass_through_unary = true;
proxy(Subject const& subject)
: unary_parser<Subject, Derived>(subject) {}
// Overload this when appropriate. The proxy parser will pick up
// the most derived overload.
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute, typename Category>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr, Category) const
{
this->subject.parse(first, last, context, rcontext, attr);
return true;
}
// Main entry point.
template <typename Iterator, typename Context
, typename RuleContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RuleContext& rcontext, Attribute& attr) const
{
return this->derived().parse_subject(first, last, context, rcontext, attr
, typename traits::attribute_category<Attribute>::type());
}
};
}}}
#endif
@@ -0,0 +1,100 @@
/*=============================================================================
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_SKIP_APRIL_16_2006_0625PM)
#define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Move the /first/ iterator to the first non-matching position
// given a skip-parser. The function is a no-op if unused_type or
// unused_skipper is passed as the skip-parser.
///////////////////////////////////////////////////////////////////////////
template <typename Skipper>
struct unused_skipper : unused_type
{
unused_skipper(Skipper const& skipper)
: skipper(skipper) {}
Skipper const& skipper;
};
namespace detail
{
template <typename Skipper>
struct is_unused_skipper
: mpl::false_ {};
template <typename Skipper>
struct is_unused_skipper<unused_skipper<Skipper>>
: mpl::true_ {};
template <>
struct is_unused_skipper<unused_type>
: mpl::true_ {};
template <typename Skipper>
inline Skipper const&
get_unused_skipper(Skipper const& skipper)
{
return skipper;
}
template <typename Skipper>
inline Skipper const&
get_unused_skipper(unused_skipper<Skipper> const& unused_skipper)
{
return unused_skipper.skipper;
}
template <typename Iterator, typename Skipper>
inline void skip_over(
Iterator& first, Iterator const& last, Skipper const& skipper)
{
while (first != last && skipper.parse(first, last, unused, unused, unused))
/***/;
}
template <typename Iterator>
inline void skip_over(Iterator&, Iterator const&, unused_type)
{
}
template <typename Iterator, typename Skipper>
inline void skip_over(
Iterator&, Iterator const&, unused_skipper<Skipper> const&)
{
}
}
// this tag is used to find the skipper from the context
struct skipper_tag;
template <typename Context>
struct has_skipper
: mpl::not_<detail::is_unused_skipper<
typename remove_cv<typename remove_reference<
decltype(x3::get<skipper_tag>(boost::declval<Context>()))
>::type>::type
>> {};
template <typename Iterator, typename Context>
inline void skip_over(
Iterator& first, Iterator const& last, Context const& context)
{
detail::skip_over(first, last, x3::get<skipper_tag>(context));
}
}}}
#endif
@@ -0,0 +1,26 @@
/*=============================================================================
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_DIRECTIVE_FEBRUARY_05_2007_0313PM)
#define BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM
//~ #include <boost/spirit/home/x3/directive/as.hpp>
#include <boost/spirit/home/x3/directive/confix.hpp>
//~ #include <boost/spirit/home/x3/directive/encoding.hpp>
//~ #include <boost/spirit/home/x3/directive/hold.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/spirit/home/x3/directive/lexeme.hpp>
#include <boost/spirit/home/x3/directive/matches.hpp>
#include <boost/spirit/home/x3/directive/no_case.hpp>
#include <boost/spirit/home/x3/directive/no_skip.hpp>
#include <boost/spirit/home/x3/directive/omit.hpp>
#include <boost/spirit/home/x3/directive/raw.hpp>
#include <boost/spirit/home/x3/directive/repeat.hpp>
#include <boost/spirit/home/x3/directive/seek.hpp>
#include <boost/spirit/home/x3/directive/skip.hpp>
#include <boost/spirit/home/x3/directive/with.hpp>
#endif
@@ -0,0 +1,83 @@
/*=============================================================================
Copyright (c) 2009 Chris Hoeppler
Copyright (c) 2014 Lee Clagett
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_CONFIX_MAY_30_2014_1819PM)
#define BOOST_SPIRIT_X3_CONFIX_MAY_30_2014_1819PM
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename Prefix, typename Subject, typename Postfix>
struct confix_directive :
unary_parser<Subject, confix_directive<Prefix, Subject, Postfix>>
{
typedef unary_parser<
Subject, confix_directive<Prefix, Subject, Postfix>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
confix_directive(Prefix const& prefix
, Subject const& subject
, Postfix const& postfix) :
base_type(subject),
prefix(prefix),
postfix(postfix)
{
}
template<typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context& context, RContext& rcontext, Attribute& attr) const
{
Iterator save = first;
if (!(prefix.parse(first, last, context, rcontext, unused) &&
this->subject.parse(first, last, context, rcontext, attr) &&
postfix.parse(first, last, context, rcontext, unused)))
{
first = save;
return false;
}
return true;
}
Prefix prefix;
Postfix postfix;
};
template<typename Prefix, typename Postfix>
struct confix_gen
{
template<typename Subject>
confix_directive<
Prefix, typename extension::as_parser<Subject>::value_type, Postfix>
operator[](Subject const& subject) const
{
return { prefix, as_parser(subject), postfix };
}
Prefix prefix;
Postfix postfix;
};
template<typename Prefix, typename Postfix>
confix_gen<typename extension::as_parser<Prefix>::value_type,
typename extension::as_parser<Postfix>::value_type>
confix(Prefix const& prefix, Postfix const& postfix)
{
return { as_parser(prefix), as_parser(postfix) };
}
}}}
#endif
@@ -0,0 +1,104 @@
/*=============================================================================
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(SPIRIT_EXPECT_MARCH_16_2012_1024PM)
#define SPIRIT_EXPECT_MARCH_16_2012_1024PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>
namespace boost { namespace spirit { namespace x3
{
template <typename Iterator>
struct expectation_failure : std::runtime_error
{
public:
expectation_failure(Iterator where, std::string const& which)
: std::runtime_error("boost::spirit::x3::expectation_failure")
, where_(where), which_(which)
{}
~expectation_failure() throw() {}
std::string which() const { return which_; }
Iterator const& where() const { return where_; }
private:
Iterator where_;
std::string which_;
};
template <typename Subject>
struct expect_directive : unary_parser<Subject, expect_directive<Subject>>
{
typedef unary_parser<Subject, expect_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
expect_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
bool r = this->subject.parse(first, last, context, rcontext, attr);
if (!r)
{
boost::throw_exception(
expectation_failure<Iterator>(
first, what(this->subject)));
}
return r;
}
};
struct expect_gen
{
template <typename Subject>
expect_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const expect = expect_gen{};
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// Special case handling for expect expressions.
template <typename Subject, typename Context, typename RContext>
struct parse_into_container_impl<expect_directive<Subject>, Context, RContext>
{
template <typename Iterator, typename Attribute>
static bool call(
expect_directive<Subject> const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
bool r = parse_into_container(
parser.subject, first, last, context, rcontext, attr);
if (!r)
{
boost::throw_exception(
expectation_failure<Iterator>(
first, what(parser.subject)));
}
return r;
}
};
}}}}
#endif
@@ -0,0 +1,78 @@
/*=============================================================================
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(SPIRIT_LEXEME_MARCH_24_2007_0802AM)
#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct lexeme_directive : unary_parser<Subject, lexeme_directive<Subject>>
{
typedef unary_parser<Subject, lexeme_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
lexeme_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
x3::skip_over(first, last, context);
auto const& skipper = x3::get<skipper_tag>(context);
typedef unused_skipper<
typename remove_reference<decltype(skipper)>::type>
unused_skipper_type;
unused_skipper_type unused_skipper(skipper);
return this->subject.parse(
first, last
, make_context<skipper_tag>(unused_skipper, context)
, rcontext
, attr);
}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
// no need to pre-skip if skipper is unused
return this->subject.parse(
first, last
, context
, rcontext
, attr);
}
};
struct lexeme_gen
{
template <typename Subject>
lexeme_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const lexeme = lexeme_gen{};
}}}
#endif
@@ -0,0 +1,51 @@
/*=============================================================================
Copyright (c) 2015 Mario Lang
Copyright (c) 2001-2011 Hartmut Kaiser
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_HOME_X3_EXTENSIONS_MATCHES_HPP)
#define BOOST_SPIRIT_HOME_X3_EXTENSIONS_MATCHES_HPP
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct matches_directive : unary_parser<Subject, matches_directive<Subject>>
{
using base_type = unary_parser<Subject, matches_directive<Subject>>;
static bool const has_attribute = true;
using attribute_type = bool;
matches_directive(Subject const& subject) : base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
bool const result = this->subject.parse(
first, last, context, rcontext, unused);
traits::move_to(result, attr);
return true;
}
};
struct matches_gen
{
template <typename Subject>
matches_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const matches = matches_gen{};
}}}
#endif
@@ -0,0 +1,54 @@
/*=============================================================================
Copyright (c) 2014 Thomas Bernard
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_NO_CASE_SEPT_16_2014_0912PM)
#define SPIRIT_NO_CASE_SEPT_16_2014_0912PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
// propagate no_case information through the context
template <typename Subject>
struct no_case_directive : unary_parser<Subject, no_case_directive<Subject>>
{
typedef unary_parser<Subject, no_case_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
no_case_directive(Subject const& subject)
: base_type(subject) {}
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 this->subject.parse(
first, last
, make_context<no_case_tag>(no_case_compare_, context)
, rcontext
, attr);
}
};
struct no_case_gen
{
template <typename Subject>
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{};
}}}
#endif
@@ -0,0 +1,78 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2013 Agustin Berge
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_NO_SKIP_JAN_16_2010_0802PM)
#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
// same as lexeme[], but does not pre-skip
template <typename Subject>
struct no_skip_directive : unary_parser<Subject, no_skip_directive<Subject>>
{
typedef unary_parser<Subject, no_skip_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
no_skip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
auto const& skipper = x3::get<skipper_tag>(context);
typedef unused_skipper<
typename remove_reference<decltype(skipper)>::type>
unused_skipper_type;
unused_skipper_type unused_skipper(skipper);
return this->subject.parse(
first, last
, make_context<skipper_tag>(unused_skipper, context)
, rcontext
, attr);
}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
return this->subject.parse(
first, last
, context
, rcontext
, attr);
}
};
struct no_skip_gen
{
template <typename Subject>
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{};
}}}
#endif
@@ -0,0 +1,51 @@
/*=============================================================================
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(SPIRIT_OMIT_MARCH_24_2007_0802AM)
#define SPIRIT_OMIT_MARCH_24_2007_0802AM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// omit_directive forces the attribute of subject parser
// to be unused_type
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct omit_directive : unary_parser<Subject, omit_directive<Subject>>
{
typedef unary_parser<Subject, omit_directive<Subject> > base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
typedef Subject subject_type;
omit_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename RContext>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
return this->subject.parse(first, last, context, rcontext, unused);
}
};
struct omit_gen
{
template <typename Subject>
omit_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const omit = omit_gen{};
}}}
#endif
@@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_X3_RAW_APRIL_9_2007_0912AM)
#define SPIRIT_X3_RAW_APRIL_9_2007_0912AM
#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>
namespace boost { namespace spirit { namespace x3
{
// this is a pseudo attribute type indicating that the parser wants the
// iterator range pointing to the [first, last) matching characters from
// the input iterators.
struct raw_attribute_type {};
template <typename Subject>
struct raw_directive : unary_parser<Subject, raw_directive<Subject>>
{
typedef unary_parser<Subject, raw_directive<Subject> > base_type;
typedef raw_attribute_type attribute_type;
static bool const handles_container = Subject::handles_container;
typedef Subject subject_type;
raw_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
x3::skip_over(first, last, context);
Iterator i = first;
if (this->subject.parse(i, last, context, rcontext, unused))
{
traits::move_to(first, i, attr);
first = i;
return true;
}
return false;
}
template <typename Iterator, typename Context, typename RContext>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
return this->subject.parse(first, last, context, rcontext, unused);
}
};
struct raw_gen
{
template <typename Subject>
raw_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const raw = raw_gen{};
}}}
#endif
@@ -0,0 +1,157 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2014 Thomas Bernard
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
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/kleene.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename T>
struct exact_count // handles repeat(exact)[p]
{
typedef T type;
bool got_max(T i) const { return i >= exact_value; }
bool got_min(T i) const { return i >= exact_value; }
T const exact_value;
};
template <typename T>
struct finite_count // handles repeat(min, max)[p]
{
typedef T type;
bool got_max(T i) const { return i >= max_value; }
bool got_min(T i) const { return i >= min_value; }
T const min_value;
T const max_value;
};
template <typename T>
struct infinite_count // handles repeat(min, inf)[p]
{
typedef T type;
bool got_max(T /*i*/) const { return false; }
bool got_min(T i) const { return i >= min_value; }
T const min_value;
};
}}}}
namespace boost { namespace spirit { namespace x3
{
template<typename Subject, typename RepeatCountLimit>
struct repeat_directive : unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>>
{
typedef unary_parser<Subject, repeat_directive<Subject,RepeatCountLimit>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = true;
repeat_directive(Subject const& subject, RepeatCountLimit const& repeat_limit_)
: base_type(subject)
, repeat_limit(repeat_limit_)
{}
template<typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator local_iterator = first;
typename RepeatCountLimit::type i{};
for (/**/; !repeat_limit.got_min(i); ++i)
{
if (!detail::parse_into_container(
this->subject, local_iterator, last, context, rcontext, attr))
return false;
}
first = local_iterator;
// parse some more up to the maximum specified
for (/**/; !repeat_limit.got_max(i); ++i)
{
if (!detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
break;
}
return true;
}
RepeatCountLimit repeat_limit;
};
// Infinite loop tag type
struct inf_type {};
const inf_type inf = inf_type();
struct repeat_gen
{
template<typename Subject>
kleene<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
template <typename T>
struct repeat_gen_lvl1
{
repeat_gen_lvl1(T&& repeat_limit_)
: repeat_limit(repeat_limit_)
{}
template<typename Subject>
repeat_directive< typename extension::as_parser<Subject>::value_type, T>
operator[](Subject const& subject) const
{
return { as_parser(subject),repeat_limit };
}
T repeat_limit;
};
template <typename T>
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>>
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>>
operator()(T const min_val, inf_type const &) const
{
return { detail::infinite_count<T>{min_val} };
}
};
auto const repeat = repeat_gen{};
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename RepeatCountLimit, typename Context>
struct attribute_of<x3::repeat_directive<Subject,RepeatCountLimit>, Context>
: build_container<typename attribute_of<Subject, Context>::type> {};
}}}}
#endif
@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2011 Jamboree
Copyright (c) 2014 Lee Clagett
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_SEEK_APRIL_13_2014_1920PM)
#define BOOST_SPIRIT_X3_SEEK_APRIL_13_2014_1920PM
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename Subject>
struct seek_directive : unary_parser<Subject, seek_directive<Subject>>
{
typedef unary_parser<Subject, seek_directive<Subject>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
seek_directive(Subject const& subject) :
base_type(subject) {}
template<typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator current(first);
for (/**/; current != last; ++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;
}
return false;
}
};
struct seek_gen
{
template<typename Subject>
seek_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const seek = seek_gen{};
}}}
#endif
@@ -0,0 +1,120 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_SKIP_JANUARY_26_2008_0422PM)
#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct reskip_directive : unary_parser<Subject, reskip_directive<Subject>>
{
typedef unary_parser<Subject, reskip_directive<Subject>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
reskip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
auto const& skipper =
detail::get_unused_skipper(x3::get<skipper_tag>(context));
return this->subject.parse(
first, last
, make_context<skipper_tag>(skipper, context)
, rcontext
, attr);
}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
return this->subject.parse(
first, last
, context
, rcontext
, attr);
}
};
template <typename Subject, typename Skipper>
struct skip_directive : unary_parser<Subject, skip_directive<Subject, Skipper>>
{
typedef unary_parser<Subject, skip_directive<Subject, Skipper>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
skip_directive(Subject const& subject, Skipper const& skipper)
: base_type(subject)
, skipper(skipper)
{}
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 this->subject.parse(
first, last
, make_context<skipper_tag>(skipper, context)
, rcontext
, attr);
}
Skipper const skipper;
};
struct reskip_gen
{
template <typename Skipper>
struct skip_gen
{
skip_gen(Skipper const& skipper)
: skipper_(skipper) {}
template <typename Subject>
skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
operator[](Subject const& subject) const
{
return { as_parser(subject), skipper_ };
}
Skipper skipper_;
};
template <typename Skipper>
skip_gen<Skipper> const operator()(Skipper const& skipper) const
{
return { skipper };
}
template <typename Subject>
reskip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return { as_parser(subject) };
}
};
auto const skip = reskip_gen{};
}}}
#endif
@@ -0,0 +1,107 @@
/*=============================================================================
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_X3_WITH_MAY_02_2014_0749AM)
#define SPIRIT_X3_WITH_MAY_02_2014_0749AM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// with directive injects a value into the context prior to parsing.
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Derived, typename T>
struct with_value_holder
: unary_parser<Subject, Derived>
{
typedef unary_parser<Subject, Derived> base_type;
mutable T val;
with_value_holder(Subject const& subject, T const& val)
: base_type(subject)
, val(val) {}
};
template <typename Subject, typename Derived, typename T>
struct with_value_holder<Subject, Derived, T const>
: unary_parser<Subject, Derived>
{
typedef unary_parser<Subject, Derived> base_type;
T val;
with_value_holder(Subject const& subject, T const& val)
: base_type(subject)
, val(val) {}
};
template <typename Subject, typename ID, typename T>
struct with_directive
: with_value_holder<Subject, with_directive<Subject, ID, T>, T>
{
typedef with_value_holder<Subject, with_directive<Subject, ID, T>, T> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
typedef Subject subject_type;
with_directive(Subject const& subject, T const& val)
: base_type(subject, val) {}
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 this->subject.parse(
first, last
, make_context<ID>(this->val, context)
, rcontext
, attr);
}
};
template <typename ID, typename T, typename NextContext = unused_type>
struct with_context
{
typedef context<ID, T, NextContext> type;
};
template <typename ID, typename T>
struct with_context<ID, T, unused_type>
{
typedef context<ID, T> type;
};
template <typename ID, typename T>
struct with_gen
{
T& val;
with_gen(T& val)
: val(val) {}
template <typename Subject>
with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
operator[](Subject const& subject) const
{
return { as_parser(subject), val };
}
};
template <typename ID, typename T>
inline with_gen<ID, T> with(T& val)
{
return { val };
}
template <typename ID, typename T>
inline with_gen<ID, T const> with(T const& val)
{
return { val };
}
}}}
#endif
@@ -0,0 +1,15 @@
/*=============================================================================
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_NONTERMINAL_FEBRUARY_12_2007_1018AM)
#define BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM
#include <boost/spirit/home/x3/nonterminal/rule.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/error_handler.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/debug_handler.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/success_handler.hpp>
#endif
@@ -0,0 +1,20 @@
/*=============================================================================
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_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
namespace boost { namespace spirit { namespace x3
{
enum debug_handler_state
{
pre_parse
, successful_parse
, failed_parse
};
}}}
#endif
@@ -0,0 +1,351 @@
/*=============================================================================
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_DETAIL_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
#include <boost/spirit/home/x3/auxiliary/guard.hpp>
#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/traits/make_attribute.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>
#if defined(BOOST_SPIRIT_X3_DEBUG)
#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
#endif
namespace boost { namespace spirit { namespace x3
{
template <typename ID>
struct identity;
template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
struct rule;
struct parse_pass_context_tag;
namespace detail
{
// we use this so we can detect if the default parse_rule
// is the being called.
struct default_parse_rule_result
{
default_parse_rule_result(bool r)
: r(r) {}
operator bool() const { return r; }
bool r;
};
}
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
, typename Context, typename ActualAttribute>
inline detail::default_parse_rule_result
parse_rule(
rule<ID, Attribute> rule_
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr);
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
#if defined(BOOST_SPIRIT_X3_DEBUG)
template <typename Iterator, typename Attribute>
struct context_debug
{
context_debug(
char const* rule_name
, Iterator const& first, Iterator const& last
, Attribute const& attr
, bool const& ok_parse //was parse successful?
)
: ok_parse(ok_parse), rule_name(rule_name)
, first(first), last(last)
, attr(attr)
, f(detail::get_simple_trace())
{
f(first, last, attr, pre_parse, rule_name);
}
~context_debug()
{
auto status = ok_parse ? successful_parse : failed_parse ;
f(first, last, attr, status, rule_name);
}
bool const& ok_parse;
char const* rule_name;
Iterator const& first;
Iterator const& last;
Attribute const& attr;
detail::simple_trace_type& f;
};
#endif
template <typename ID, typename Iterator, typename Context, typename Enable = void>
struct has_on_error : mpl::false_ {};
template <typename ID, typename Iterator, typename Context>
struct has_on_error<ID, Iterator, Context,
typename disable_if_substitution_failure<
decltype(
std::declval<ID>().on_error(
std::declval<Iterator&>()
, std::declval<Iterator>()
, std::declval<expectation_failure<Iterator>>()
, std::declval<Context>()
)
)>::type
>
: mpl::true_
{};
template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
struct has_on_success : mpl::false_ {};
template <typename ID, typename Iterator, typename Attribute, typename Context>
struct has_on_success<ID, Iterator, Context, Attribute,
typename disable_if_substitution_failure<
decltype(
std::declval<ID>().on_success(
std::declval<Iterator&>()
, std::declval<Iterator>()
, std::declval<Attribute&>()
, std::declval<Context>()
)
)>::type
>
: mpl::true_
{};
template <typename ID>
struct make_id
{
typedef identity<ID> type;
};
template <typename ID>
struct make_id<identity<ID>>
{
typedef identity<ID> type;
};
template <typename ID, typename RHS, typename Context>
Context const&
make_rule_context(RHS const& rhs, Context const& context
, mpl::false_ /* is_default_parse_rule */)
{
return context;
}
template <typename ID, typename RHS, typename Context>
auto make_rule_context(RHS const& rhs, Context const& context
, mpl::true_ /* is_default_parse_rule */ )
{
return make_unique_context<ID>(rhs, context);
}
template <typename Attribute, typename ID>
struct rule_parser
{
template <typename Iterator, typename Context, typename ActualAttribute>
static bool call_on_success(
Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr
, mpl::false_ /* No on_success handler */ )
{
return true;
}
template <typename Iterator, typename Context, typename ActualAttribute>
static bool call_on_success(
Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr
, mpl::true_ /* Has on_success handler */)
{
bool pass = true;
ID().on_success(
first
, last
, attr
, make_context<parse_pass_context_tag>(pass, context)
);
return pass;
}
template <typename RHS, typename Iterator, typename Context
, typename RContext, typename ActualAttribute>
static bool parse_rhs_main(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, ActualAttribute& attr
, mpl::false_)
{
// 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))
parse_rule_result;
// If there is no BOOST_SPIRIT_DEFINE for this rule,
// we'll make a context for this rule tagged by its ID
// so we can extract the rule later on in the default
// (generic) parse_rule function.
typedef
is_same<parse_rule_result, default_parse_rule_result>
is_default_parse_rule;
Iterator i = first;
bool r = rhs.parse(
i
, last
, make_rule_context<ID>(rhs, context, 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
, has_on_success<ID, Iterator, Context, ActualAttribute>());
}
if (r)
first = i;
return r;
}
template <typename RHS, typename Iterator, typename Context
, typename RContext, typename ActualAttribute>
static bool parse_rhs_main(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, ActualAttribute& attr
, mpl::true_ /* on_error is found */)
{
for (;;)
{
try
{
return parse_rhs_main(
rhs, first, last, context, rcontext, attr, mpl::false_());
}
catch (expectation_failure<Iterator> const& x)
{
switch (ID().on_error(first, last, x, context))
{
case error_handler_result::fail:
return false;
case error_handler_result::retry:
continue;
case error_handler_result::accept:
return true;
case error_handler_result::rethrow:
throw;
}
}
}
}
template <typename RHS, typename Iterator
, typename Context, typename RContext, typename ActualAttribute>
static bool parse_rhs_main(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, ActualAttribute& attr)
{
return parse_rhs_main(
rhs, first, last, context, rcontext, attr
, has_on_error<ID, Iterator, Context>()
);
}
template <typename RHS, typename Iterator
, typename Context, typename RContext, typename ActualAttribute>
static bool parse_rhs(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, ActualAttribute& attr
, mpl::false_)
{
return parse_rhs_main(rhs, first, last, context, rcontext, attr);
}
template <typename RHS, typename Iterator
, typename Context, typename RContext, typename ActualAttribute>
static bool parse_rhs(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, ActualAttribute& attr
, mpl::true_)
{
return parse_rhs_main(rhs, first, last, context, rcontext, unused);
}
template <typename RHS, typename Iterator, typename Context
, typename ActualAttribute, typename ExplicitAttrPropagation>
static bool call_rule_definition(
RHS const& rhs
, char const* rule_name
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr
, ExplicitAttrPropagation)
{
typedef traits::make_attribute<Attribute, ActualAttribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, Attribute, parser_id>
transform;
typedef typename make_attribute::value_type value_type;
typedef typename transform::type transform_attr;
value_type made_attr = make_attribute::call(attr);
transform_attr attr_ = transform::pre(made_attr);
bool ok_parse
//Creates a place to hold the result of parse_rhs
//called inside the following scope.
;
{
// Create a scope to cause the dbg variable below (within
// the #if...#endif) to call it's DTOR before any
// modifications are made to the attribute, attr_ passed
// to parse_rhs (such as might be done in
// traits::post_transform when, for example,
// ActualAttribute is a recursive variant).
#if defined(BOOST_SPIRIT_X3_DEBUG)
typedef typename make_attribute::type dbg_attribute_type;
context_debug<Iterator, dbg_attribute_type>
dbg(rule_name, first, last, dbg_attribute_type(attr_), ok_parse);
#endif
ok_parse = parse_rhs(rhs, first, last, context, attr_, attr_
, mpl::bool_
< ( RHS::has_action
&& !ExplicitAttrPropagation::value
)
>()
);
}
if (ok_parse)
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr, std::forward<transform_attr>(attr_));
}
return ok_parse;
}
};
}}}}
#endif
@@ -0,0 +1,110 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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
#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <utility>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3
{
struct parser_id;
template <typename Exposed, typename Transformed>
struct default_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed&& attr)
{
traits::move_to(std::forward<Transformed>(attr), val);
}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct default_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
};
// main specialization for x3
template <typename Exposed, typename Transformed, typename Enable = void>
struct transform_attribute
: default_transform_attribute<Exposed, Transformed> {};
// reference types need special handling
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
};
// unused_type needs some special handling as well
template <>
struct transform_attribute<unused_type, unused_type>
{
typedef unused_type type;
static unused_type pre(unused_type) { return unused; }
static void post(unused_type, unused_type) {}
};
template <>
struct transform_attribute<unused_type const, unused_type>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<unused_type, Attribute>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<unused_type const, Attribute>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<Attribute, unused_type>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<Attribute const, unused_type>
: transform_attribute<unused_type, unused_type> {};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed, Transformed, x3::parser_id>
: x3::transform_attribute<Exposed, Transformed> {};
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed&, Transformed, x3::parser_id>
: transform_attribute<Exposed, Transformed, x3::parser_id> {};
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute, x3::parser_id>
: x3::transform_attribute<Attribute&, Attribute> {};
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void post_transform(Exposed& dest, Transformed&& attr)
{
return transform_attribute<Exposed, Transformed, x3::parser_id>
::post(dest, std::forward<Transformed>(attr));
}
}}}}
#endif
@@ -0,0 +1,183 @@
/*=============================================================================
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_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
#include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
#include <boost/preprocessor/variadic/elem.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
#include <typeinfo>
#endif
namespace boost { namespace spirit { namespace x3
{
template <typename ID>
struct identity {};
// default parse_rule implementation
template <typename ID, typename Attribute, typename Iterator
, typename Context, typename ActualAttribute>
inline detail::default_parse_rule_result
parse_rule(
rule<ID, Attribute> rule_
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr)
{
static_assert(!is_same<decltype(get<ID>(context)), unused_type>::value,
"BOOST_SPIRIT_DEFINE undefined for this rule.");
return 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_>>
{
typedef rule_definition<ID, RHS, Attribute, force_attribute_> this_type;
typedef ID id;
typedef RHS rhs_type;
typedef rule<ID, Attribute> lhs_type;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<Attribute, unused_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
static bool const force_attribute =
force_attribute_;
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>
::call_rule_definition(
rhs, name, first, last
, context
, attr
, mpl::bool_<force_attribute>());
}
RHS rhs;
char const* name;
};
template <typename ID, typename Attribute, bool force_attribute_>
struct rule : parser<rule<ID, Attribute>>
{
typedef ID id;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<Attribute, unused_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
static bool const force_attribute = force_attribute_;
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
rule() : name(typeid(rule).name()) {}
#else
rule() : name("unnamed") {}
#endif
rule(char const* name)
: name(name) {}
template <typename RHS>
rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
operator=(RHS const& rhs) const
{
return { as_parser(rhs), name };
}
template <typename RHS>
rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
operator%=(RHS const& rhs) const
{
return { as_parser(rhs), name };
}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
return parse_rule(*this, first, last, context, attr);
}
char const* name;
};
namespace traits
{
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, typename RHS, bool force_attribute>
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute>> : mpl::true_ {};
}
template <typename T>
struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
{
typedef std::string result_type;
std::string operator()(T const& r) const
{
return r.name;
}
};
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
template <typename Iterator, typename Context, typename Attribute> \
bool parse_rule( \
rule_type rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, Attribute& attr); \
/***/
#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
/***/
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
template <typename Iterator, typename Context, typename Attribute> \
inline bool parse_rule( \
decltype(rule_name) rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, Attribute& 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); \
} \
/***/
#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
/***/
#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
template bool parse_rule<Iterator, Context, rule_type::attribute_type>( \
rule_type rule_ \
, Iterator& first, Iterator const& last \
, Context const& context, rule_type::attribute_type& attr); \
/***/
}}}
#endif
@@ -0,0 +1,146 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/print_token.hpp>
#include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/debug_handler_state.hpp>
#include <boost/fusion/include/out.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iostream>
// The stream to use for debug output
#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
#endif
// number of tokens to print while debugging
#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
#endif
// number of spaces to indent
#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
#define BOOST_SPIRIT_X3_DEBUG_INDENT 2
#endif
namespace boost { namespace spirit { namespace x3
{
namespace detail
{
template <typename Char>
inline void token_printer(std::ostream& o, Char c)
{
// allow customization of the token printer routine
x3::traits::print_token(o, c);
}
}
template <int IndentSpaces = 2, int CharsToPrint = 20>
struct simple_trace
{
simple_trace(std::ostream& out)
: out(out), indent(0) {}
void print_indent(int n) const
{
n *= IndentSpaces;
for (int i = 0; i != n; ++i)
out << ' ';
}
template <typename Iterator>
void print_some(
char const* tag
, Iterator first, Iterator const& last) const
{
print_indent(indent);
out << '<' << tag << '>';
int const n = CharsToPrint;
for (int i = 0; first != last && i != n && *first; ++i, ++first)
detail::token_printer(out, *first);
out << "</" << tag << '>' << std::endl;
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
// character entities. $$$
}
template <typename Iterator, typename Attribute, typename State>
void operator()(
Iterator const& first
, Iterator const& last
, Attribute const& attr
, State state
, std::string const& rule_name) const
{
switch (state)
{
case pre_parse:
print_indent(indent++);
out
<< '<' << rule_name << '>'
<< std::endl;
print_some("try", first, last);
break;
case successful_parse:
print_some("success", first, last);
if (!is_same<Attribute, unused_type>::value)
{
print_indent(indent);
out
<< "<attributes>";
traits::print_attribute(out, attr);
out
<< "</attributes>";
out << std::endl;
}
//~ if (!fusion::empty(context.locals))
//~ out
//~ << "<locals>"
//~ << context.locals
//~ << "</locals>";
print_indent(--indent);
out
<< "</" << rule_name << '>'
<< std::endl;
break;
case failed_parse:
print_indent(indent);
out << "<fail/>" << std::endl;
print_indent(--indent);
out
<< "</" << rule_name << '>'
<< std::endl;
break;
}
}
std::ostream& out;
mutable int indent;
};
namespace detail
{
typedef simple_trace<
BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
simple_trace_type;
inline simple_trace_type&
get_simple_trace()
{
static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
return tracer;
}
}
}}}
#endif
@@ -0,0 +1,15 @@
/*=============================================================================
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_NUMERIC_FEBRUARY_05_2007_1231PM)
#define BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM
#include <boost/spirit/home/x3/numeric/bool.hpp>
#include <boost/spirit/home/x3/numeric/int.hpp>
#include <boost/spirit/home/x3/numeric/uint.hpp>
#include <boost/spirit/home/x3/numeric/real.hpp>
#endif
@@ -0,0 +1,159 @@
/*=============================================================================
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(SPIRIT_X3_BOOL_SEP_29_2009_0709AM)
#define SPIRIT_X3_BOOL_SEP_29_2009_0709AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/numeric/bool_policies.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>
struct bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>
{
typedef Encoding encoding;
typedef T attribute_type;
static bool const has_attribute = true;
bool_parser()
: policies() {}
bool_parser(BoolPolicies const& policies)
: policies(policies) {}
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, T& attr) const
{
x3::skip_over(first, last, context);
return policies.parse_true(first, last, attr, get_case_compare<encoding>(context))
|| policies.parse_false(first, last, attr, get_case_compare<encoding>(context));
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
if (parse(first, last, context, unused, attr_))
{
traits::move_to(attr_, attr_param);
return true;
}
return false;
}
BoolPolicies policies;
};
template <typename T, typename Encoding, typename BoolPolicies = bool_policies<T>>
struct literal_bool_parser : parser<bool_parser<T, Encoding, BoolPolicies>>
{
typedef Encoding encoding;
typedef T attribute_type;
static bool const has_attribute = true;
template <typename Value>
literal_bool_parser(Value const& n)
: policies(), n_(n) {}
template <typename Value>
literal_bool_parser(Value const& n, BoolPolicies const& policies)
: policies(policies), n_(n) {}
template <typename Iterator, typename Context>
bool parse_main(Iterator& first, Iterator const& last
, Context& context, T& attr) const
{
x3::skip_over(first, last, context);
return (n_ && policies.parse_true(first, last, attr, get_case_compare<encoding>(context)))
|| (!n_ && policies.parse_false(first, last, attr, get_case_compare<encoding>(context)));
}
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, T& attr) const
{
return parse_main(first, last, context, attr);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
if (parse_main(first, last, context, attr_))
{
traits::move_to(attr_, attr_param);
return true;
}
return false;
}
BoolPolicies policies;
T n_;
};
namespace standard
{
typedef bool_parser<bool, char_encoding::standard> bool_type;
bool_type const bool_ = {};
typedef literal_bool_parser<bool, char_encoding::standard> true_type;
true_type const true_ = { true };
typedef literal_bool_parser<bool, char_encoding::standard> false_type;
false_type const false_ = { false };
}
namespace standard_wide
{
typedef bool_parser<bool, char_encoding::standard_wide> bool_type;
bool_type const bool_ = {};
typedef literal_bool_parser<bool, char_encoding::standard_wide> true_type;
true_type const true_ = { true };
typedef literal_bool_parser<bool, char_encoding::standard_wide> false_type;
false_type const false_ = { false };
}
namespace ascii
{
typedef bool_parser<bool, char_encoding::ascii> bool_type;
bool_type const bool_ = {};
typedef literal_bool_parser<bool, char_encoding::ascii> true_type;
true_type const true_ = { true };
typedef literal_bool_parser<bool, char_encoding::ascii> false_type;
false_type const false_ = { false };
}
namespace iso8859_1
{
typedef bool_parser<bool, char_encoding::iso8859_1> bool_type;
bool_type const bool_ = {};
typedef literal_bool_parser<bool, char_encoding::iso8859_1> true_type;
true_type const true_ = { true };
typedef literal_bool_parser<bool, char_encoding::iso8859_1> false_type;
false_type const false_ = { false };
}
using standard::bool_;
using standard::true_;
using standard::false_;
}}}
#endif
@@ -0,0 +1,48 @@
/*=============================================================================
Copyright (c) 2009 Hartmut Kaiser
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM)
#define SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Default boolean policies
///////////////////////////////////////////////////////////////////////////
template <typename T = bool>
struct bool_policies
{
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
parse_true(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
if (detail::string_parse("true", first, last, unused, case_compare))
{
traits::move_to(T(true), attr_); // result is true
return true;
}
return false;
}
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool
parse_false(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const& case_compare)
{
if (detail::string_parse("false", first, last, unused, case_compare))
{
traits::move_to(T(false), attr_); // result is false
return true;
}
return false;
}
};
}}}
#endif
@@ -0,0 +1,62 @@
/*=============================================================================
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_INT_APR_17_2006_0830AM)
#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
#include <cstdint>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <
typename T
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1>
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits>>
{
// check template parameter 'Radix' for validity
static_assert(
(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
"Error Unsupported Radix");
typedef T attribute_type;
static bool const has_attribute = true;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
x3::skip_over(first, last, context);
return extract::call(first, last, attr);
}
};
#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name) \
typedef int_parser<int_type> name##type; \
name##type const name = {}; \
/***/
BOOST_SPIRIT_X3_INT_PARSER(long, long_)
BOOST_SPIRIT_X3_INT_PARSER(short, short_)
BOOST_SPIRIT_X3_INT_PARSER(int, int_)
BOOST_SPIRIT_X3_INT_PARSER(long long, long_long)
BOOST_SPIRIT_X3_INT_PARSER(int8_t, int8)
BOOST_SPIRIT_X3_INT_PARSER(int16_t, int16)
BOOST_SPIRIT_X3_INT_PARSER(int32_t, int32)
BOOST_SPIRIT_X3_INT_PARSER(int64_t, int64)
#undef BOOST_SPIRIT_X3_INT_PARSER
}}}
#endif
@@ -0,0 +1,62 @@
/*=============================================================================
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_REAL_APRIL_18_2006_0850AM)
#define BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/numeric/real_policies.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_real.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename T, typename RealPolicies = real_policies<T> >
struct real_parser : parser<real_parser<T, RealPolicies> >
{
typedef T attribute_type;
static bool const has_attribute = true;
real_parser()
: policies() {}
real_parser(RealPolicies const& policies)
: policies(policies) {}
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, T& attr_) const
{
x3::skip_over(first, last, context);
return extract_real<T, RealPolicies>::parse(first, last, attr_, policies);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, unused_type, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
if (parse(first, last, context, unused, attr_))
{
traits::move_to(attr_, attr_param);
return true;
}
return false;
}
RealPolicies policies;
};
typedef real_parser<float> float_type;
float_type const float_ = {};
typedef real_parser<double> double_type;
double_type const double_ = {};
}}}
#endif
@@ -0,0 +1,182 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_REAL_POLICIES_APRIL_17_2006_1158PM)
#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Default (unsigned) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct ureal_policies
{
// trailing dot policy suggested by Gustavo Guerra
static bool const allow_leading_dot = true;
static bool const allow_trailing_dot = true;
static bool const expect_dot = false;
template <typename Iterator>
static bool
parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
{
return false;
}
template <typename Iterator, typename Attribute>
static bool
parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
{
return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
}
template <typename Iterator>
static bool
parse_dot(Iterator& first, Iterator const& last)
{
if (first == last || *first != '.')
return false;
++first;
return true;
}
template <typename Iterator, typename Attribute>
static bool
parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
{
return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
}
template <typename Iterator>
static bool
parse_exp(Iterator& first, Iterator const& last)
{
if (first == last || (*first != 'e' && *first != 'E'))
return false;
++first;
return true;
}
template <typename Iterator>
static bool
parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
{
return extract_int<int, 10, 1, -1>::call(first, last, attr_);
}
///////////////////////////////////////////////////////////////////////
// The parse_nan() and parse_inf() functions get called whenever:
//
// - a number to parse does not start with a digit (after having
// successfully parsed an optional sign)
//
// or
//
// - after a floating point number of the value 1 (having no
// exponential part and a fractional part value of 0) has been
// parsed.
//
// The first call allows to recognize representations of NaN or Inf
// starting with a non-digit character (such as NaN, Inf, QNaN etc.).
//
// The second call allows to recognize representation formats starting
// with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
//
// The functions should return true if a Nan or Inf has been found. In
// this case the attr should be set to the matched value (NaN or
// Inf). The optional sign will be automatically applied afterwards.
//
// The default implementation below recognizes representations of NaN
// and Inf as mandated by the C99 Standard and as proposed for
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
// (the matching is performed case-insensitively).
///////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Attribute>
static bool
parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
{
if (first == last)
return false; // end of input reached
if (*first != 'n' && *first != 'N')
return false; // not "nan"
// nan[(...)] ?
if (detail::string_parse("nan", "NAN", first, last, unused))
{
if (*first == '(')
{
// skip trailing (...) part
Iterator i = first;
while (++i != last && *i != ')')
;
if (i == last)
return false; // no trailing ')' found, give up
first = ++i;
}
attr_ = std::numeric_limits<T>::quiet_NaN();
return true;
}
return false;
}
template <typename Iterator, typename Attribute>
static bool
parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
{
if (first == last)
return false; // end of input reached
if (*first != 'i' && *first != 'I')
return false; // not "inf"
// inf or infinity ?
if (detail::string_parse("inf", "INF", first, last, unused))
{
// skip allowed 'inity' part of infinity
detail::string_parse("inity", "INITY", first, last, unused);
attr_ = std::numeric_limits<T>::infinity();
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////
// Default (signed) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct real_policies : ureal_policies<T>
{
template <typename Iterator>
static bool
parse_sign(Iterator& first, Iterator const& last)
{
return extract_sign(first, last);
}
};
template <typename T>
struct strict_ureal_policies : ureal_policies<T>
{
static bool const expect_dot = true;
};
template <typename T>
struct strict_real_policies : real_policies<T>
{
static bool const expect_dot = true;
};
}}}
#endif
@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2011 Jan Frederick Eick
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_UINT_APR_17_2006_0901AM)
#define BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
#include <cstdint>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <
typename T
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1>
struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits>>
{
// check template parameter 'Radix' for validity
static_assert(
(Radix >= 2 && Radix <= 36),
"Error Unsupported Radix");
typedef T attribute_type;
static bool const has_attribute = true;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
x3::skip_over(first, last, context);
return extract::call(first, last, attr);
}
};
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, name) \
typedef uint_parser<uint_type> name##type; \
name##type const name = {}; \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned long, ulong_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned short, ushort_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned int, uint_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned long long, ulong_long)
BOOST_SPIRIT_X3_UINT_PARSER(uint8_t, uint8)
BOOST_SPIRIT_X3_UINT_PARSER(uint16_t, uint16)
BOOST_SPIRIT_X3_UINT_PARSER(uint32_t, uint32)
BOOST_SPIRIT_X3_UINT_PARSER(uint64_t, uint64)
#undef BOOST_SPIRIT_X3_UINT_PARSER
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, radix, name) \
typedef uint_parser<uint_type, radix> name##type; \
name##type const name = name##type(); \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 2, bin)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 8, oct)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 16, hex)
#undef BOOST_SPIRIT_X3_UINT_PARSER
}}}
#endif
@@ -0,0 +1,22 @@
/*=============================================================================
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_OPERATOR_FEBRUARY_02_2007_0558PM)
#define BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM
#include <boost/spirit/home/x3/operator/sequence.hpp>
#include <boost/spirit/home/x3/operator/alternative.hpp>
//~ #include <boost/spirit/home/x3/operator/sequential_or.hpp>
//~ #include <boost/spirit/home/x3/operator/permutation.hpp>
#include <boost/spirit/home/x3/operator/difference.hpp>
#include <boost/spirit/home/x3/operator/list.hpp>
#include <boost/spirit/home/x3/operator/optional.hpp>
#include <boost/spirit/home/x3/operator/kleene.hpp>
#include <boost/spirit/home/x3/operator/plus.hpp>
#include <boost/spirit/home/x3/operator/and_predicate.hpp>
#include <boost/spirit/home/x3/operator/not_predicate.hpp>
#endif
@@ -0,0 +1,61 @@
/*=============================================================================
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(SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM)
#define SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/alternative.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
{
typedef binary_parser<Left, Right, alternative<Left, Right>> base_type;
alternative(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
return this->left.parse(first, last, context, rcontext, unused)
|| this->right.parse(first, last, context, rcontext, unused);
}
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->left, first, last, context, rcontext, attr)
|| detail::parse_alternative(this->right, first, last, context, rcontext, attr);
}
};
template <typename Left, typename Right>
inline alternative<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator|(Left const& left, Right const& right)
{
return { as_parser(left), as_parser(right) };
}
}}}
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> {};
}}}}
#endif
@@ -0,0 +1,43 @@
/*=============================================================================
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(SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM)
#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct and_predicate : unary_parser<Subject, and_predicate<Subject>>
{
typedef unary_parser<Subject, and_predicate<Subject>> base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
and_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& /*attr*/) const
{
Iterator i = first;
return this->subject.parse(i, last, context, rcontext, unused);
}
};
template <typename Subject>
inline and_predicate<typename extension::as_parser<Subject>::value_type>
operator&(Subject const& subject)
{
return { as_parser(subject) };
}
}}}
#endif
@@ -0,0 +1,300 @@
/*=============================================================================
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(SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM)
#define SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM
#include <boost/spirit/home/x3/support/traits/attribute_of.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>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct alternative;
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
struct pass_variant_unused
{
typedef unused_type type;
template <typename T>
static unused_type
call(T&)
{
return unused_type();
}
};
template <typename Attribute>
struct pass_variant_used
{
typedef Attribute& type;
static Attribute&
call(Attribute& v)
{
return v;
}
};
template <>
struct pass_variant_used<unused_type> : pass_variant_unused {};
template <typename Parser, typename Attribute, typename Context
, typename Enable = void>
struct pass_parser_attribute
{
typedef typename
traits::attribute_of<Parser, Context>::type
attribute_type;
typedef typename
traits::variant_find_substitute<Attribute, attribute_type>::type
substitute_type;
typedef typename
mpl::if_<
is_same<Attribute, substitute_type>
, Attribute&
, substitute_type
>::type
type;
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr, mpl::true_)
{
return attr;
}
template <typename Attribute_>
static type
call(Attribute_&, mpl::false_)
{
return type();
}
template <typename Attribute_>
static type
call(Attribute_& attr)
{
return call(attr, is_same<Attribute_, typename remove_reference<type>::type>());
}
};
// Pass non-variant attributes as-is
template <typename Parser, typename Attribute, typename Context
, typename Enable = void>
struct pass_non_variant_attribute
{
typedef Attribute& type;
static Attribute&
call(Attribute& attr)
{
return attr;
}
};
// Unwrap single element sequences
template <typename Parser, typename Attribute, typename Context>
struct pass_non_variant_attribute<Parser, Attribute, Context,
typename enable_if<traits::is_size_one_sequence<Attribute>>::type>
{
typedef typename remove_reference<
typename fusion::result_of::front<Attribute>::type>::type
attr_type;
typedef pass_parser_attribute<Parser, attr_type, Context> pass;
typedef typename pass::type type;
template <typename Attribute_>
static type
call(Attribute_& attr)
{
return pass::call(fusion::front(attr));
}
};
template <typename Parser, typename Attribute, typename Context>
struct pass_parser_attribute<Parser, Attribute, Context,
typename enable_if_c<(!traits::is_variant<Attribute>::value)>::type>
: pass_non_variant_attribute<Parser, Attribute, Context>
{};
template <typename Parser, typename Context>
struct pass_parser_attribute<Parser, unused_type, Context>
: pass_variant_unused {};
template <typename Parser, typename Attribute, typename Context>
struct pass_variant_attribute :
mpl::if_c<traits::has_attribute<Parser, Context>::value
, 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>
struct pass_variant_attribute<alternative<L, R>, Attribute, Context> :
mpl::if_c<traits::has_attribute<alternative<L, R>, Context>::value
, 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<typename T1, typename T2>
static void call(T1& attr_, T2& attr) {}
};
template <>
struct move_if_not_alternative<mpl::false_ /*is alternative*/>
{
template<typename T1, typename T2>
static void call(T1& attr_, T2& attr)
{
traits::move_to(attr_, attr);
}
};
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)
{
typedef detail::pass_variant_attribute<Parser, Attribute, Context> pass;
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);
return true;
}
return false;
}
template <typename Left, typename Right, typename Context, typename RContext>
struct parse_into_container_impl<alternative<Left, Right>, Context, RContext>
{
typedef alternative<Left, Right> parser_type;
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::true_)
{
return parse_alternative(parser, first, last, context, rcontext, attr);
}
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_)
{
return parse_into_container_base_impl<parser_type>::call(
parser, first, last, context, rcontext, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
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>());
}
};
}}}}
#endif
@@ -0,0 +1,503 @@
/*=============================================================================
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(SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/advance.hpp>
#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>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct sequence;
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Parser, typename Context, typename Enable = void>
struct sequence_size
{
static int const value = traits::has_attribute<Parser, Context>::value;
};
template <typename Parser, typename Context>
struct sequence_size_subject
: sequence_size<typename Parser::subject_type, Context> {};
template <typename Parser, typename Context>
struct sequence_size<Parser, Context
, typename enable_if_c<(Parser::is_pass_through_unary)>::type>
: sequence_size_subject<Parser, Context> {};
template <typename L, typename R, typename Context>
struct sequence_size<sequence<L, R>, Context>
{
static int const value =
sequence_size<L, Context>::value +
sequence_size<R, Context>::value;
};
struct pass_sequence_attribute_unused
{
typedef unused_type type;
template <typename T>
static unused_type
call(T&)
{
return unused_type();
}
};
template <typename Attribute>
struct pass_sequence_attribute_front
{
typedef typename fusion::result_of::front<Attribute>::type type;
static typename add_reference<type>::type
call(Attribute& attr)
{
return fusion::front(attr);
}
};
template <typename Attribute>
struct pass_through_sequence_attribute
{
typedef Attribute& type;
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr)
{
return attr;
}
};
template <typename Parser, typename Attribute, bool pass_through>
struct pass_sequence_attribute_used :
mpl::if_c<
(!pass_through && traits::is_size_one_sequence<Attribute>::value)
, pass_sequence_attribute_front<Attribute>
, pass_through_sequence_attribute<Attribute>>::type {};
template <typename Parser, typename Attribute, bool pass_through = false, typename Enable = void>
struct pass_sequence_attribute :
mpl::if_<
fusion::result_of::empty<Attribute>
, pass_sequence_attribute_unused
, pass_sequence_attribute_used<Parser, Attribute, pass_through>>::type {};
template <typename L, typename R, typename Attribute, bool pass_through>
struct pass_sequence_attribute<sequence<L, R>, Attribute, pass_through>
: pass_through_sequence_attribute<Attribute> {};
template <typename Parser, typename Attribute>
struct pass_sequence_attribute_subject :
pass_sequence_attribute<typename Parser::subject_type, Attribute> {};
template <typename Parser, typename Attribute, bool pass_through>
struct pass_sequence_attribute<Parser, Attribute, pass_through
, typename enable_if_c<(Parser::is_pass_through_unary)>::type>
: pass_sequence_attribute_subject<Parser, Attribute> {};
template <typename L, typename R, typename Attribute, typename Context
, typename Enable = void>
struct partition_attribute
{
static int const l_size = sequence_size<L, Context>::value;
static int const r_size = sequence_size<R, Context>::value;
// If you got an error here, then you are trying to pass
// a fusion sequence with the wrong number of elements
// as that expected by the (sequence) parser.
static_assert(
fusion::result_of::size<Attribute>::value == (l_size + r_size)
, "Attribute does not have the expected size."
);
typedef typename fusion::result_of::begin<Attribute>::type l_begin;
typedef typename fusion::result_of::advance_c<l_begin, l_size>::type l_end;
typedef typename fusion::result_of::end<Attribute>::type r_end;
typedef fusion::iterator_range<l_begin, l_end> l_part;
typedef fusion::iterator_range<l_end, r_end> r_part;
typedef pass_sequence_attribute<L, l_part, false> l_pass;
typedef pass_sequence_attribute<R, r_part, false> r_pass;
static l_part left(Attribute& s)
{
auto i = fusion::begin(s);
return l_part(i, fusion::advance_c<l_size>(i));
}
static r_part right(Attribute& s)
{
return r_part(
fusion::advance_c<l_size>(fusion::begin(s))
, fusion::end(s));
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
traits::has_attribute<R, Context>::value)>::type>
{
typedef unused_type l_part;
typedef Attribute& r_part;
typedef pass_sequence_attribute_unused l_pass;
typedef pass_sequence_attribute<R, Attribute, true> r_pass;
static unused_type left(Attribute&)
{
return unused;
}
static Attribute& right(Attribute& s)
{
return s;
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(traits::has_attribute<L, Context>::value &&
!traits::has_attribute<R, Context>::value)>::type>
{
typedef Attribute& l_part;
typedef unused_type r_part;
typedef pass_sequence_attribute<L, Attribute, true> l_pass;
typedef pass_sequence_attribute_unused r_pass;
static Attribute& left(Attribute& s)
{
return s;
}
static unused_type right(Attribute&)
{
return unused;
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
!traits::has_attribute<R, Context>::value)>::type>
{
typedef unused_type l_part;
typedef unused_type r_part;
typedef pass_sequence_attribute_unused l_pass;
typedef pass_sequence_attribute_unused r_pass;
static unused_type left(Attribute&)
{
return unused;
}
static unused_type right(Attribute&)
{
return unused;
}
};
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>
bool parse_sequence(
Parser const& parser, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::tuple_attribute)
{
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;
typename partition::l_part l_part = partition::left(attr);
typename partition::r_part r_part = partition::right(attr);
typename l_pass::type l_attr = l_pass::call(l_part);
typename r_pass::type r_attr = r_pass::call(r_part);
Iterator save = first;
if (parser.left.parse(first, last, context, rcontext, l_attr)
&& parser.right.parse(first, last, context, rcontext, r_attr))
return true;
first = save;
return false;
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence_plain(
Parser const& parser, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
typedef typename Parser::left_type Left;
typedef typename Parser::right_type Right;
typedef typename traits::attribute_of<Left, Context>::type l_attr_type;
typedef typename traits::attribute_of<Right, Context>::type r_attr_type;
typedef traits::make_attribute<l_attr_type, Attribute> l_make_attribute;
typedef traits::make_attribute<r_attr_type, Attribute> r_make_attribute;
typename l_make_attribute::type l_attr = l_make_attribute::call(attr);
typename r_make_attribute::type r_attr = r_make_attribute::call(attr);
Iterator save = first;
if (parser.left.parse(first, last, context, rcontext, l_attr)
&& parser.right.parse(first, last, context, rcontext, r_attr))
return true;
first = save;
return false;
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence(
Parser const& parser, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::plain_attribute)
{
return parse_sequence_plain(parser, first, last, context, rcontext, attr);
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence(
Parser const& parser, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::variant_attribute)
{
return parse_sequence_plain(parser, first, last, context, rcontext, attr);
}
template <typename Left, typename Right, typename Iterator
, typename Context, typename RContext, typename Attribute>
bool parse_sequence(
Left const& left, Right const& right
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::container_attribute);
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence(
Parser const& parser , Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::container_attribute)
{
Iterator save = first;
if (parse_into_container(parser.left, first, last, context, rcontext, attr)
&& parse_into_container(parser.right, first, last, context, rcontext, attr))
return true;
first = save;
return false;
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence_assoc(
Parser const& parser , Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::false_ /*should_split*/)
{
return parse_into_container(parser, first, last, context, rcontext, attr);
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence_assoc(
Parser const& parser , Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_ /*should_split*/)
{
Iterator save = first;
if (parser.left.parse( first, last, context, rcontext, attr)
&& parser.right.parse(first, last, context, rcontext, attr))
return true;
first = save;
return false;
}
template <typename Parser, typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_sequence(
Parser const& parser, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::associative_attribute)
{
// we can come here in 2 cases:
// - when sequence is key >> value and therefore must
// be parsed with tuple synthesized attribute and then
// that tuple is used to save into associative attribute provided here.
// Example: key >> value;
//
// - when either this->left or this->right provides full key-value
// pair (like in case 1) and another one provides nothing.
// Example: eps >> rule<class x; fusion::map<...> >
//
// first case must be parsed as whole, and second one should
// be parsed separately for left and right.
typedef typename traits::attribute_of<
decltype(parser.left), Context>::type l_attr_type;
typedef typename traits::attribute_of<
decltype(parser.right), Context>::type r_attr_type;
typedef typename
mpl::or_<
is_same<l_attr_type, unused_type>
, is_same<r_attr_type, unused_type> >
should_split;
return parse_sequence_assoc(parser, first, last, context, rcontext, attr
, should_split());
}
template <typename Left, typename Right, typename Context, typename RContext>
struct parse_into_container_impl<sequence<Left, Right>, Context, RContext>
{
typedef sequence<Left, Right> parser_type;
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_)
{
// inform user what went wrong if we jumped here in attempt to
// parse incompatible sequence into fusion::map
static_assert(!is_same< typename traits::attribute_category<Attribute>::type,
traits::associative_attribute>::value,
"To parse directly into fusion::map sequence must produce tuple attribute "
"where type of first element is existing key in fusion::map and second element "
"is value to be stored under that key");
Attribute attr_;
if (!parse_sequence(parser
, first, last, context, rcontext, attr_, traits::container_attribute()))
{
return false;
}
traits::append(attr, traits::begin(attr_), traits::end(attr_));
return true;
}
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::true_)
{
return parse_into_container_base_impl<parser_type>::call(
parser, first, last, context, rcontext, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr)
{
typedef typename
traits::attribute_of<parser_type, Context>::type
attribute_type;
typedef typename
traits::container_value<Attribute>::type
value_type;
return call(parser, first, last, context, rcontext, attr
, typename traits::is_substitute<attribute_type, value_type>::type());
}
};
}}}}
#endif
@@ -0,0 +1,71 @@
/*=============================================================================
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(SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM)
#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct difference : binary_parser<Left, Right, difference<Left, Right>>
{
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)
: base_type(left, right) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
// Try Right first
Iterator start = first;
if (this->right.parse(first, last, context, rcontext, unused))
{
// Right succeeds, we fail.
first = start;
return false;
}
// Right fails, now try Left
return this->left.parse(first, last, context, rcontext, attr);
}
template <typename Left_, typename Right_>
difference<Left_, Right_>
make(Left_ const& left, Right_ const& right) const
{
return { left, right };
}
};
template <typename Left, typename Right>
inline difference<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator-(Left const& left, Right const& right)
{
return { as_parser(left), as_parser(right) };
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::difference<Left, Right>, Context>
: attribute_of<Left, Context> {};
template <typename Left, typename Right, typename Context>
struct has_attribute<x3::difference<Left, Right>, Context>
: has_attribute<Left, Context> {};
}}}}
#endif
@@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_KLEENE_JANUARY_07_2007_0818AM)
#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct kleene : unary_parser<Subject, kleene<Subject>>
{
typedef unary_parser<Subject, kleene<Subject>> base_type;
static bool const handles_container = true;
kleene(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
while (detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
;
return true;
}
};
template <typename Subject>
inline kleene<typename extension::as_parser<Subject>::value_type>
operator*(Subject const& subject)
{
return { as_parser(subject) };
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::kleene<Subject>, Context>
: build_container<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif
@@ -0,0 +1,69 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_LIST_MARCH_24_2007_1031AM)
#define SPIRIT_LIST_MARCH_24_2007_1031AM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct list : binary_parser<Left, Right, list<Left, Right>>
{
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)
: base_type(left, right) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
// in order to succeed we need to match at least one element
if (!detail::parse_into_container(
this->left, first, last, context, rcontext, attr))
return false;
Iterator save = first;
while (this->right.parse(first, last, context, rcontext, unused)
&& detail::parse_into_container(
this->left, first, last, context, rcontext, attr))
{
save = first;
}
first = save;
return true;
}
};
template <typename Left, typename Right>
inline list<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator%(Left const& left, Right const& right)
{
return { as_parser(left), as_parser(right) };
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::list<Left, Right>, Context>
: traits::build_container<
typename attribute_of<Left, Context>::type> {};
}}}}
#endif
@@ -0,0 +1,43 @@
/*=============================================================================
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(SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM)
#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct not_predicate : unary_parser<Subject, not_predicate<Subject>>
{
typedef unary_parser<Subject, not_predicate<Subject>> base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
not_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& /*attr*/) const
{
Iterator i = first;
return !this->subject.parse(i, last, context, rcontext, unused);
}
};
template <typename Subject>
inline not_predicate<typename extension::as_parser<Subject>::value_type>
operator!(Subject const& subject)
{
return { as_parser(subject) };
}
}}}
#endif
@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_OPTIONAL_MARCH_23_2007_1117PM)
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
#include <boost/spirit/home/x3/core/proxy.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/optional_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct optional : proxy<Subject, optional<Subject>>
{
typedef proxy<Subject, optional<Subject>> base_type;
static bool const handles_container = true;
optional(Subject const& subject)
: base_type(subject) {}
using base_type::parse_subject;
// Attribute is a container
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::container_attribute) const
{
detail::parse_into_container(
this->subject, first, last, context, rcontext, attr);
return true;
}
// Attribute is an optional
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, traits::optional_attribute) const
{
typedef typename
x3::traits::optional_value<Attribute>::type
value_type;
// create a local value
value_type val = value_type();
if (this->subject.parse(first, last, context, rcontext, val))
{
// assign the parsed value into our attribute
x3::traits::move_to(val, attr);
}
return true;
}
};
template <typename Subject>
inline optional<typename extension::as_parser<Subject>::value_type>
operator-(Subject const& subject)
{
return { as_parser(subject) };
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::optional<Subject>, Context>
: build_optional<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif
@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_PLUS_MARCH_13_2007_0127PM)
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct plus : unary_parser<Subject, plus<Subject>>
{
typedef unary_parser<Subject, plus<Subject>> base_type;
static bool const handles_container = true;
plus(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context
, typename RContext, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
if (!detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
return false;
while (detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
;
return true;
}
};
template <typename Subject>
inline plus<typename extension::as_parser<Subject>::value_type>
operator+(Subject const& subject)
{
return { as_parser(subject) };
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::plus<Subject>, Context>
: build_container<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif
@@ -0,0 +1,72 @@
/*=============================================================================
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(SPIRIT_SEQUENCE_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_JAN_06_2013_1015AM
#include <boost/spirit/home/x3/support/traits/attribute_of.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>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
{
typedef binary_parser<Left, Right, sequence<Left, Right>> base_type;
sequence(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename RContext>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
Iterator save = first;
if (this->left.parse(first, last, context, rcontext, unused)
&& this->right.parse(first, last, context, rcontext, unused))
return true;
first = save;
return false;
}
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_sequence(*this, first, last, context, rcontext, attr
, typename traits::attribute_category<Attribute>::type());
}
};
template <typename Left, typename Right>
inline sequence<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator>>(Left const& left, Right const& right)
{
return { as_parser(left), as_parser(right) };
}
template <typename Left, typename Right>
auto operator>(Left const& left, Right const& right)
{
return left >> expect[right];
}
}}}
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> {};
}}}}
#endif
@@ -0,0 +1,13 @@
/*=============================================================================
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_STRING_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM
#include <boost/spirit/home/x3/string/literal_string.hpp>
#include <boost/spirit/home/x3/string/symbols.hpp>
#endif
@@ -0,0 +1,60 @@
/*=============================================================================
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
@@ -0,0 +1,85 @@
/*=============================================================================
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_STRING_PARSE_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Char, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
Char const* str
, Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
if (i == last || (compare(ch, *i) != 0))
return false;
ch = *++str;
}
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute, typename CaseCompareFunc>
inline bool string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr, CaseCompareFunc const& compare)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
if (i == last || (compare(*stri, *i) != 0))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* uc_i, Char const* lc_i
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& ucstr, String const& lcstr
, Iterator& first, Iterator const& last, Attribute& attr)
{
typename String::const_iterator uc_i = ucstr.begin();
typename String::const_iterator uc_last = ucstr.end();
typename String::const_iterator lc_i = lcstr.begin();
Iterator i = first;
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
}}}}
#endif
@@ -0,0 +1,205 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
#include <boost/call_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// This file contains low level TST routines, not for
// public consumption.
template <typename Char, typename T>
struct tst_node
{
tst_node(Char id)
: id(id), data(0), lt(0), eq(0), gt(0)
{
}
template <typename Alloc>
static void
destruct_node(tst_node* p, Alloc* alloc)
{
if (p)
{
if (p->data)
alloc->delete_data(p->data);
destruct_node(p->lt, alloc);
destruct_node(p->eq, alloc);
destruct_node(p->gt, alloc);
alloc->delete_node(p);
}
}
template <typename Alloc>
static tst_node*
clone_node(tst_node* p, Alloc* alloc)
{
if (p)
{
tst_node* clone = alloc->new_node(p->id);
if (p->data)
clone->data = alloc->new_data(*p->data);
clone->lt = clone_node(p->lt, alloc);
clone->eq = clone_node(p->eq, alloc);
clone->gt = clone_node(p->gt, alloc);
return clone;
}
return 0;
}
template <typename Iterator, typename CaseCompare>
static T*
find(tst_node* start, Iterator& first, Iterator last, CaseCompare comp)
{
if (first == last)
return 0;
Iterator i = first;
Iterator latest = first;
tst_node* p = start;
T* found = 0;
while (p && i != last)
{
int32_t c = comp(*i,p->id);
if (c == 0)
{
if (p->data)
{
found = p->data;
latest = i;
}
p = p->eq;
i++;
}
else if (c < 0)
{
p = p->lt;
}
else
{
p = p->gt;
}
}
if (found)
first = ++latest; // one past the last matching char
return found;
}
template <typename Iterator, typename Alloc>
static T*
add(
tst_node*& start
, Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val
, Alloc* alloc)
{
if (first == last)
return 0;
tst_node** pp = &start;
for (;;)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (*pp == 0)
*pp = alloc->new_node(c);
tst_node* p = *pp;
if (c == p->id)
{
if (++first == last)
{
if (p->data == 0)
p->data = alloc->new_data(val);
return p->data;
}
pp = &p->eq;
}
else if (c < p->id)
{
pp = &p->lt;
}
else
{
pp = &p->gt;
}
}
}
template <typename Iterator, typename Alloc>
static void
remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
{
if (p == 0 || first == last)
return;
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (c == p->id)
{
if (++first == last)
{
if (p->data)
{
alloc->delete_data(p->data);
p->data = 0;
}
}
remove(p->eq, first, last, alloc);
}
else if (c < p->id)
{
remove(p->lt, first, last, alloc);
}
else
{
remove(p->gt, first, last, alloc);
}
if (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)
{
alloc->delete_node(p);
p = 0;
}
}
template <typename F>
static void
for_each(tst_node* p, std::basic_string<Char> prefix, F f)
{
if (p)
{
for_each(p->lt, prefix, f);
std::basic_string<Char> s = prefix + p->id;
for_each(p->eq, s, f);
if (p->data)
f(s, *p->data);
for_each(p->gt, prefix, f);
}
}
Char id; // the node's identity character
T* data; // optional data
tst_node* lt; // left pointer
tst_node* eq; // middle pointer
tst_node* gt; // right pointer
};
}}}}
#endif
@@ -0,0 +1,248 @@
/*=============================================================================
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_LITERAL_STRING_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
#include <boost/spirit/home/x3/core/parser.hpp>
#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>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <string>
namespace boost { namespace spirit { namespace x3
{
template <typename String, typename Encoding,
typename Attribute = std::basic_string<typename Encoding::char_type>>
struct literal_string : parser<literal_string<String, Encoding, Attribute>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = has_attribute;
literal_string(typename add_reference< typename add_const<String>::type >::type str)
: str(str)
{}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute_& attr) const
{
x3::skip_over(first, last, context);
return detail::string_parse(str, first, last, attr, get_case_compare<encoding>(context));
}
String str;
};
namespace standard
{
inline literal_string<char const*, char_encoding::standard>
string(char const* s)
{
return { s };
}
inline literal_string<std::basic_string<char>, char_encoding::standard>
string(std::basic_string<char> const& s)
{
return { s };
}
inline literal_string<char const*, char_encoding::standard, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::standard, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
namespace standard_wide
{
inline literal_string<wchar_t const*, char_encoding::standard_wide>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
inline literal_string<wchar_t const*, char_encoding::standard_wide, unused_type>
lit(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::standard_wide, unused_type>
lit(std::basic_string<wchar_t> const& s)
{
return { s };
}
}
namespace ascii
{
inline literal_string<wchar_t const*, char_encoding::ascii>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::ascii>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
inline literal_string<char const*, char_encoding::ascii, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::ascii, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
namespace iso8859_1
{
inline literal_string<wchar_t const*, char_encoding::iso8859_1>
string(wchar_t const* s)
{
return { s };
}
inline literal_string<std::basic_string<wchar_t>, char_encoding::iso8859_1>
string(std::basic_string<wchar_t> const& s)
{
return { s };
}
inline literal_string<char const*, char_encoding::iso8859_1, unused_type>
lit(char const* s)
{
return { s };
}
template <typename Char>
literal_string<std::basic_string<Char>, char_encoding::iso8859_1, unused_type>
lit(std::basic_string<Char> const& s)
{
return { s };
}
}
using standard::string;
using standard::lit;
using standard_wide::string;
using standard_wide::lit;
namespace extension
{
template <int N>
struct as_parser<char[N]>
{
typedef literal_string<
char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<char const[N]> : as_parser<char[N]> {};
template <int N>
struct as_parser<wchar_t[N]>
{
typedef literal_string<
wchar_t const*, char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static type call(wchar_t const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
template <>
struct as_parser<char const*>
{
typedef literal_string<
char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char const* s)
{
return type(s);
}
};
template <typename Char>
struct as_parser< std::basic_string<Char> >
{
typedef literal_string<
Char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(std::basic_string<Char> const& s)
{
return type(s.c_str());
}
};
}
template <typename String, typename Encoding, typename Attribute>
struct get_info<literal_string<String, Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
{
return '"' + to_utf8(p.str) + '"';
}
};
}}}
#endif
@@ -0,0 +1,370 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Carl Barron
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_SYMBOLS_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/string/tst.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/no_case.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/shared_ptr.hpp>
#include <initializer_list>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
namespace boost { namespace spirit { namespace x3
{
template <
typename Encoding
, typename T = unused_type
, typename Lookup = tst<typename Encoding::char_type, T> >
struct symbols_parser : parser<symbols_parser<Encoding, T, Lookup>>
{
typedef typename Encoding::char_type char_type; // the character type
typedef Encoding encoding;
typedef T value_type; // the value associated with each entry
typedef value_type attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<attribute_type>::value;
symbols_parser(std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
}
symbols_parser(symbols_parser const& syms)
: add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{
}
template <typename Symbols>
symbols_parser(Symbols const& syms, std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
template <typename Symbols, typename Data>
symbols_parser(Symbols const& syms, Data const& data
, std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
typename range_const_iterator<Data>::type di = boost::begin(data);
while (si != boost::end(syms))
add(*si++, *di++);
}
symbols_parser(std::initializer_list<std::pair<char_type const*, T>> syms
, std::string const & name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typedef std::initializer_list<std::pair<char_type const*, T>> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
for (;si != boost::end(syms); ++si)
add(si->first, si->second);
}
symbols_parser(std::initializer_list<char_type const*> syms
, std::string const &name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typedef std::initializer_list<char_type const*> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
symbols_parser&
operator=(symbols_parser const& rhs)
{
name_ = rhs.name_;
lookup = rhs.lookup;
return *this;
}
void clear()
{
lookup->clear();
}
struct adder;
struct remover;
template <typename Str>
adder const&
operator=(Str const& str)
{
lookup->clear();
return add(str);
}
template <typename Str>
friend adder const&
operator+=(symbols_parser& sym, Str const& str)
{
return sym.add(str);
}
template <typename Str>
friend remover const&
operator-=(symbols_parser& sym, Str const& str)
{
return sym.remove(str);
}
template <typename F>
void for_each(F f) const
{
lookup->for_each(f);
}
template <typename Str>
value_type& at(Str const& str)
{
return *lookup->add(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str), T());
}
template <typename Iterator>
value_type* prefix_find(Iterator& first, Iterator const& last)
{
return lookup->find(first, last, case_compare<Encoding>());
}
template <typename Iterator>
value_type const* prefix_find(Iterator& first, Iterator const& last) const
{
return lookup->find(first, last, case_compare<Encoding>());
}
template <typename Str>
value_type* find(Str const& str)
{
return find_impl(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str));
}
template <typename Str>
value_type const* find(Str const& str) const
{
return find_impl(traits::get_string_begin<char_type>(str)
, traits::get_string_end<char_type>(str));
}
private:
template <typename Iterator>
value_type* find_impl(Iterator begin, Iterator end)
{
value_type* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
template <typename Iterator>
value_type const* find_impl(Iterator begin, Iterator end) const
{
value_type const* r = lookup->find(begin, end, case_compare<Encoding>());
return begin == end ? r : 0;
}
public:
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (value_type const* val_ptr
= lookup->find(first, last, get_case_compare<Encoding>(context)))
{
x3::traits::move_to(*val_ptr, attr);
return true;
}
return false;
}
void name(std::string const &str)
{
name_ = str;
}
std::string const &name() const
{
return name_;
}
struct adder
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef adder const& type; };
adder(symbols_parser& sym)
: sym(sym)
{
}
template <typename Iterator>
adder const&
operator()(Iterator first, Iterator last, T const& val) const
{
sym.lookup->add(first, last, val);
return *this;
}
template <typename Str>
adder const&
operator()(Str const& s, T const& val = T()) const
{
sym.lookup->add(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s), val);
return *this;
}
template <typename Str>
adder const&
operator,(Str const& s) const
{
sym.lookup->add(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s), T());
return *this;
}
symbols_parser& sym;
};
struct remover
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef remover const& type; };
remover(symbols_parser& sym)
: sym(sym)
{
}
template <typename Iterator>
remover const&
operator()(Iterator const& first, Iterator const& last) const
{
sym.lookup->remove(first, last);
return *this;
}
template <typename Str>
remover const&
operator()(Str const& s) const
{
sym.lookup->remove(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s));
return *this;
}
template <typename Str>
remover const&
operator,(Str const& s) const
{
sym.lookup->remove(traits::get_string_begin<char_type>(s)
, traits::get_string_end<char_type>(s));
return *this;
}
symbols_parser& sym;
};
adder add;
remover remove;
shared_ptr<Lookup> lookup;
std::string name_;
};
template <typename Encoding, typename T, typename Lookup>
struct get_info<symbols_parser<Encoding, T, Lookup>>
{
typedef std::string result_type;
result_type operator()(symbols_parser< Encoding, T
, Lookup
> const& symbols) const
{
return symbols.name();
}
};
namespace standard
{
template <typename T = unused_type>
using symbols = symbols_parser<char_encoding::standard, T>;
}
using standard::symbols;
namespace standard_wide
{
template <typename T = unused_type>
using symbols = symbols_parser<char_encoding::standard_wide, T>;
}
namespace ascii
{
template <typename T = unused_type>
using symbols = symbols_parser<char_encoding::ascii, T>;
}
namespace iso8859_1
{
template <typename T = unused_type>
using symbols = symbols_parser<char_encoding::iso8859_1, T>;
}
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,133 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)
#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM
#include <boost/spirit/home/x3/string/detail/tst.hpp>
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through
{
template <typename Char>
Char operator()(Char ch) const
{
return ch;
}
};
template <typename Char, typename T>
struct tst
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst()
: root(0)
{
}
~tst()
{
clear();
}
tst(tst const& rhs)
: root(0)
{
copy(rhs);
}
tst& operator=(tst const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename CaseCompare>
T* find(Iterator& first, Iterator last, CaseCompare caseCompare) const
{
return node::find(root, first, last, caseCompare);
}
/*template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, case_compare<tst_pass_through());
}*/
template <typename Iterator>
T* add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
return node::add(root, first, last, val, this);
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
node::remove(root, first, last, this);
}
void clear()
{
node::destruct_node(root, this);
root = 0;
}
template <typename F>
void for_each(F f) const
{
node::for_each(root, std::basic_string<Char>(), f);
}
private:
friend struct detail::tst_node<Char, T>;
void copy(tst const& rhs)
{
root = node::clone_node(rhs.root, this);
}
tst& assign(tst const& rhs)
{
if (this != &rhs)
{
clear();
copy(rhs);
}
return *this;
}
node* root;
node* new_node(Char id)
{
return new node(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return new T(val);
}
void delete_node(node* p)
{
delete p;
}
void delete_data(T* p)
{
delete p;
}
};
}}}
#endif
@@ -0,0 +1,212 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <unordered_map>
#include <boost/pool/object_pool.hpp>
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through; // declared in tst.hpp
template <typename Char, typename T>
struct tst_map
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst_map()
{
}
~tst_map()
{
// Nothing to do here.
// The pools do the right thing for us
}
tst_map(tst_map const& rhs)
{
copy(rhs);
}
tst_map& operator=(tst_map const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
if (first != last)
{
Iterator save = first;
typename map_type::const_iterator
i = map.find(filter(*first++));
if (i == map.end())
{
first = save;
return 0;
}
if (T* p = node::find(i->second.root, first, last, filter))
{
return p;
}
return i->second.data;
}
return 0;
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
bool add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
if (first != last)
{
map_data x = {0, 0};
std::pair<typename map_type::iterator, bool>
r = map.insert(std::pair<Char, map_data>(*first++, x));
if (first != last)
{
return node::add(r.first->second.root
, first, last, val, this) ? true : false;
}
else
{
if (r.first->second.data)
return false;
r.first->second.data = this->new_data(val);
}
return true;
}
return false;
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
if (first != last)
{
typename map_type::iterator i = map.find(*first++);
if (i != map.end())
{
if (first != last)
{
node::remove(i->second.root, first, last, this);
}
else if (i->second.data)
{
this->delete_data(i->second.data);
i->second.data = 0;
}
if (i->second.data == 0 && i->second.root == 0)
{
map.erase(i);
}
}
}
}
void clear()
{
for (typename map_type::value_type& x : map)
{
node::destruct_node(x.second.root, this);
if (x.second.data)
this->delete_data(x.second.data);
}
map.clear();
}
template <typename F>
void for_each(F f) const
{
for (typename map_type::value_type const& x : map)
{
std::basic_string<Char> s(1, x.first);
node::for_each(x.second.root, s, f);
if (x.second.data)
f(s, *x.second.data);
}
}
private:
friend struct detail::tst_node<Char, T>;
struct map_data
{
node* root;
T* data;
};
typedef std::unordered_map<Char, map_data> map_type;
void copy(tst_map const& rhs)
{
for (typename map_type::value_type const& x : rhs.map)
{
map_data xx = {node::clone_node(x.second.root, this), 0};
if (x.second.data)
xx.data = data_pool.construct(*x.second.data);
map[x.first] = xx;
}
}
tst_map& assign(tst_map const& rhs)
{
if (this != &rhs)
{
for (typename map_type::value_type& x : map)
{
node::destruct_node(x.second.root, this);
}
map.clear();
copy(rhs);
}
return *this;
}
node* new_node(Char id)
{
return node_pool.construct(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return data_pool.construct(val);
}
void delete_node(node* p)
{
node_pool.destroy(p);
}
void delete_data(T* p)
{
data_pool.destroy(p);
}
map_type map;
object_pool<node> node_pool;
object_pool<T> data_pool;
};
}}}
#endif
@@ -0,0 +1,96 @@
/*=============================================================================
Copyright (c) 2014 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#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/type_traits/is_base_of.hpp>
namespace boost { namespace spirit { namespace x3
{
struct position_tagged
{
// Use this to annotate an AST with the iterator position.
// These ids are used as a key to the position_cache (below)
// and marks the start and end of an AST node.
int id_first = -1;
int id_last = -1;
};
template <typename Container>
class position_cache
{
public:
typedef typename Container::value_type iterator_type;
position_cache(
iterator_type first
, iterator_type last)
: first_(first), last_(last) {}
// This will catch all nodes inheriting from position_tagged
boost::iterator_range<iterator_type>
position_of(position_tagged const& ast) const
{
return
boost::iterator_range<iterator_type>(
positions.at(ast.id_first) // throws if out of range
, positions.at(ast.id_last) // throws if out of range
);
}
// This will catch all nodes except those inheriting from position_tagged
template <typename AST>
boost::iterator_range<iterator_type>
position_of(AST const& ast) const
{
// returns an empty position
return boost::iterator_range<iterator_type>();
}
// This will catch all nodes except those inheriting from position_tagged
template <typename AST>
void annotate(AST& ast, iterator_type first, iterator_type last, mpl::false_)
{
// (no-op) no need for tags
}
// This will catch all nodes inheriting from position_tagged
void annotate(position_tagged& ast, iterator_type first, iterator_type last, mpl::true_)
{
ast.id_first = int(positions.size());
positions.push_back(first);
ast.id_last = int(positions.size());
positions.push_back(last);
}
template <typename AST>
void annotate(AST& ast, iterator_type first, iterator_type last)
{
annotate(ast, first, last, is_base_of<position_tagged, AST>());
}
Container const&
get_positions() const
{
return positions;
}
iterator_type first() const { return first_; }
iterator_type last() const { return last_; }
private:
Container positions;
iterator_type first_;
iterator_type last_;
};
}}}
#endif
@@ -0,0 +1,257 @@
/*=============================================================================
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_VARIANT_AUGUST_6_2011_0859AM)
#define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
#include <boost/variant.hpp>
#include <boost/mpl/list.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <type_traits>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3
{
template <typename T>
class forward_ast
{
public:
typedef T type;
public:
forward_ast() : p_(new T) {}
forward_ast(forward_ast const& operand)
: p_(new T(operand.get())) {}
forward_ast(forward_ast&& operand)
: p_(operand.p_)
{
operand.p_ = 0;
}
forward_ast(T const& operand)
: p_(new T(operand)) {}
forward_ast(T&& operand)
: p_(new T(std::move(operand))) {}
~forward_ast()
{
boost::checked_delete(p_);
}
forward_ast& operator=(forward_ast const& rhs)
{
assign(rhs.get());
return *this;
}
void swap(forward_ast& operand) BOOST_NOEXCEPT
{
T* temp = operand.p_;
operand.p_ = p_;
p_ = temp;
}
forward_ast& operator=(T const& rhs)
{
assign(rhs);
return *this;
}
forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
{
swap(rhs);
return *this;
}
forward_ast& operator=(T&& rhs)
{
get() = std::move(rhs);
return *this;
}
T& get() { return *get_pointer(); }
const T& get() const { return *get_pointer(); }
T* get_pointer() { return p_; }
const T* get_pointer() const { return p_; }
operator T const&() const { return this->get(); }
operator T&() { return this->get(); }
private:
void assign(const T& rhs)
{
this->get() = rhs;
}
T* p_;
};
// function template swap
//
// Swaps two forward_ast<T> objects of the same type T.
//
template <typename T>
inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT
{
lhs.swap(rhs);
}
namespace detail
{
template <typename T>
struct remove_forward : mpl::identity<T>
{};
template <typename T>
struct remove_forward<forward_ast<T>> : mpl::identity<T>
{};
}
template <typename ...Types>
struct variant
{
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
using variant_type = boost::variant<Types...>;
using types = mpl::list<typename detail::remove_forward<Types>::type...>;
using base_type = variant; // The current instantiation
template<typename T>
using non_self_t // used only for SFINAE checks below
= std::enable_if_t<!(std::is_base_of<base_type
,std::remove_reference_t<T>
>
::value)
>;
variant() : var() {}
template <typename T, class = non_self_t<T>>
explicit variant(T const& rhs)
: var(rhs) {}
template <typename T, class = non_self_t<T>>
explicit variant(T&& rhs)
: var(std::forward<T>(rhs)) {}
variant(variant const& rhs)
: var(rhs.var) {}
variant(variant& rhs)
: var(rhs.var) {}
variant(variant&& rhs)
: var(std::forward<variant_type>(rhs.var)) {}
variant& operator=(variant const& rhs)
{
var = rhs.get();
return *this;
}
variant& operator=(variant&& rhs)
{
var = std::forward<variant_type>(rhs.get());
return *this;
}
template <typename T, class = non_self_t<T>>
variant& operator=(T const& rhs)
{
var = rhs;
return *this;
}
template <typename T, class = non_self_t<T>>
variant& operator=(T&& rhs)
{
var = std::forward<T>(rhs);
return *this;
}
template <typename F>
typename F::result_type apply_visitor(F const& v)
{
return var.apply_visitor(v);
}
template <typename F>
typename F::result_type apply_visitor(F const& v) const
{
return var.apply_visitor(v);
}
template <typename F>
typename F::result_type apply_visitor(F& v)
{
return var.apply_visitor(v);
}
template <typename F>
typename F::result_type apply_visitor(F& v) const
{
return var.apply_visitor(v);
}
variant_type const& get() const
{
return var;
}
variant_type& get()
{
return var;
}
void swap(variant& rhs) BOOST_NOEXCEPT
{
var.swap(rhs.var);
}
variant_type var;
};
}}}
namespace boost
{
template <typename T, typename ...Types>
inline T const&
get(boost::spirit::x3::variant<Types...> const& x)
{
return boost::get<T>(x.get());
}
template <typename T, typename ...Types>
inline T&
get(boost::spirit::x3::variant<Types...>& x)
{
return boost::get<T>(x.get());
}
template <typename T, typename ...Types>
inline T const*
get(boost::spirit::x3::variant<Types...> const* x)
{
return boost::get<T>(&x->get());
}
template <typename T, typename ...Types>
inline T*
get(boost::spirit::x3::variant<Types...>* x)
{
return boost::get<T>(&x->get());
}
}
#endif
@@ -0,0 +1,103 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename ID, typename T, typename Next = unused_type>
struct context
{
context(T& val, Next const& next)
: val(val), next(next) {}
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
decltype(auto) get(ID_ id) const
{
return next.get(id);
}
T& val;
Next const& next;
};
template <typename ID, typename T>
struct context<ID, T, unused_type>
{
context(T& val)
: val(val) {}
context(T& val, unused_type)
: val(val) {}
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
unused_type get(ID_) const
{
return {};
}
T& val;
};
template <typename Tag, typename Context>
inline decltype(auto) get(Context const& context)
{
return context.get(mpl::identity<Tag>());
}
template <typename ID, typename T, typename Next>
inline context<ID, T, Next> make_context(T& val, Next const& next)
{
return { val, next };
}
template <typename ID, typename T>
inline context<ID, T> make_context(T& val)
{
return { val };
}
namespace detail
{
template <typename ID, typename T, typename Next, typename FoundVal>
inline Next const&
make_unique_context(T& val, Next const& next, FoundVal&)
{
return next;
}
template <typename ID, typename T, typename Next>
inline context<ID, T, Next>
make_unique_context(T& val, Next const& next, unused_type)
{
return { val, next };
}
}
template <typename ID, typename T, typename Next>
inline auto
make_unique_context(T& val, Next const& next)
{
return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
}
}}}
#endif
@@ -0,0 +1,102 @@
/*=============================================================================
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_SUPPORT_NO_CASE_SEPT_24_2014_1125PM)
#define BOOST_SPIRIT_X3_SUPPORT_NO_CASE_SEPT_24_2014_1125PM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/char/char_class_tags.hpp>
namespace boost { namespace spirit { namespace x3
{
struct no_case_tag {};
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)
{
return set.test(ch);
}
int32_t operator()(
typename Encoding::char_type const lc
, typename Encoding::char_type const rc) const
{
return lc - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
};
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)
{
return set.test(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
{
return Encoding::islower(rc) ? Encoding::tolower(lc) - rc : Encoding::toupper(lc) - rc;
}
template <typename CharClassTag>
CharClassTag get_char_class_tag(CharClassTag tag) const
{
return tag;
}
alpha_tag get_char_class_tag(lower_tag ) const
{
return {};
}
alpha_tag get_char_class_tag(upper_tag ) const
{
return {};
}
};
template <typename Encoding>
case_compare<Encoding> get_case_compare_impl(unused_type const&)
{
return {};
}
template <typename Encoding>
no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
{
return {};
}
template <typename Encoding, typename Context>
inline decltype(auto) get_case_compare(Context const& context)
{
return get_case_compare_impl<Encoding>(x3::get<no_case_tag>(context));
}
auto const no_case_compare_ = no_case_tag{};
}}}
#endif
@@ -0,0 +1,508 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Jan Frederick Eick
Copyright (c) 2011 Christopher Jefferson
Copyright (c) 2006 Stephen Nutt
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_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/limits.hpp>
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
#endif
namespace boost { namespace spirit { namespace x3 { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// The maximum radix digits that can be represented without
// overflow:
//
// template<typename T, unsigned Radix>
// struct digits_traits::value;
//
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix>
struct digits_traits;
// lookup table for log2(x) : 2 <= x <= 36
#define BOOST_SPIRIT_X3_LOG2 (#error)(#error) \
(1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
(3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
(3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
(4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
(4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
(5000000)(5044390)(5087460)(5129280)(5169925) \
/***/
#define BOOST_PP_LOCAL_MACRO(Radix) \
template <typename T> struct digits_traits<T, Radix> \
{ \
typedef std::numeric_limits<T> numeric_limits_type; \
BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
(numeric_limits_type::digits * 1000000) / \
BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2))); \
}; \
/***/
#define BOOST_PP_LOCAL_LIMITS (2, 36)
#include BOOST_PP_LOCAL_ITERATE()
#undef BOOST_SPIRIT_X3_LOG2
///////////////////////////////////////////////////////////////////////////
//
// Traits class for radix specific number conversion
//
// Test the validity of a single character:
//
// template<typename Char> static bool is_valid(Char ch);
//
// Convert a digit from character representation to binary
// representation:
//
// template<typename Char> static int digit(Char ch);
//
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix>
struct radix_traits
{
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));
}
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;
}
};
///////////////////////////////////////////////////////////////////////////
// positive_accumulator/negative_accumulator: Accumulator policies for
// extracting integers. Use positive_accumulator if number is positive.
// Use negative_accumulator if number is negative.
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix>
struct positive_accumulator
{
template <typename T, typename Char>
inline static void add(T& n, Char ch, mpl::false_) // unchecked add
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * T(Radix) + T(digit);
}
template <typename T, typename Char>
inline static bool add(T& n, Char ch, mpl::true_) // checked add
{
// Ensure n *= Radix will not overflow
static T const max = (std::numeric_limits<T>::max)();
static T const val = max / Radix;
if (n > val)
return false;
n *= Radix;
// Ensure n += digit will not overflow
const int digit = radix_traits<Radix>::digit(ch);
if (n > max - digit)
return false;
n += static_cast<T>(digit);
return true;
}
};
template <unsigned Radix>
struct negative_accumulator
{
template <typename T, typename Char>
inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * T(Radix) - T(digit);
}
template <typename T, typename Char>
inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
{
// Ensure n *= Radix will not underflow
static T const min = (std::numeric_limits<T>::min)();
static T const val = (min + 1) / T(Radix);
if (n < val)
return false;
n *= Radix;
// Ensure n -= digit will not underflow
int const digit = radix_traits<Radix>::digit(ch);
if (n < min + digit)
return false;
n -= static_cast<T>(digit);
return true;
}
};
///////////////////////////////////////////////////////////////////////////
// Common code for extract_int::parse specializations
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix, typename Accumulator, int MaxDigits>
struct int_extractor
{
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t count, T& n, mpl::true_)
{
static std::size_t const
overflow_free = digits_traits<T, Radix>::value - 1;
if (count < overflow_free)
{
Accumulator::add(n, ch, mpl::false_());
}
else
{
if (!Accumulator::add(n, ch, mpl::true_()))
return false; // over/underflow!
}
return true;
}
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
{
// no need to check for overflow
Accumulator::add(n, ch, mpl::false_());
return true;
}
template <typename Char>
inline static bool
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
{
return true;
}
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t count, T& n)
{
return call(ch, count, n
, mpl::bool_<
( (MaxDigits < 0)
|| (MaxDigits > digits_traits<T, Radix>::value)
)
&& traits::check_overflow<T>::value
>()
);
}
};
///////////////////////////////////////////////////////////////////////////
// End of loop checking: check if the number of digits
// being parsed exceeds MaxDigits. Note: if MaxDigits == -1
// we don't do any checking.
///////////////////////////////////////////////////////////////////////////
template <int MaxDigits>
struct check_max_digits
{
inline static bool
call(std::size_t count)
{
return count < MaxDigits; // bounded
}
};
template <>
struct check_max_digits<-1>
{
inline static bool
call(std::size_t /*count*/)
{
return true; // unbounded
}
};
///////////////////////////////////////////////////////////////////////////
// extract_int: main code for extracting integers
///////////////////////////////////////////////////////////////////////////
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
|| it == last) \
break; \
ch = *it; \
if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
break; \
++it; \
++count; \
/**/
template <
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename Accumulator = positive_accumulator<Radix>
, bool Accumulate = false
>
struct extract_int
{
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
template <typename Iterator, typename Attribute>
inline static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
Iterator it = first;
std::size_t leading_zeros = 0;
if (!Accumulate)
{
// skip leading zeros
while (it != last && *it == '0' && leading_zeros < MaxDigits)
{
++it;
++leading_zeros;
}
}
typedef typename
traits::attribute_type<Attribute>::type
attribute_type;
attribute_type val = Accumulate ? attr : attribute_type(0);
std::size_t count = 0;
char_type ch;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
if (count + leading_zeros >= MinDigits)
{
traits::move_to(val, attr);
first = it;
return true;
}
return false;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
inline static bool
parse(
Iterator& first
, Iterator const& last
, unused_type)
{
T n = 0; // must calculate value to detect over/underflow
return parse_main(first, last, n);
}
template <typename Iterator, typename Attribute>
inline static bool
parse(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
return parse_main(first, last, attr);
}
};
#undef SPIRIT_NUMERIC_INNER_LOOP
///////////////////////////////////////////////////////////////////////////
// extract_int: main code for extracting integers
// common case where MinDigits == 1 and MaxDigits = -1
///////////////////////////////////////////////////////////////////////////
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
if (it == last) \
break; \
ch = *it; \
if (!radix_check::is_valid(ch)) \
break; \
if (!extractor::call(ch, count, val)) \
return false; \
++it; \
++count; \
/**/
template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
{
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
template <typename Iterator, typename Attribute>
inline static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, -1> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
Iterator it = first;
std::size_t count = 0;
if (!Accumulate)
{
// skip leading zeros
while (it != last && *it == '0')
{
++it;
++count;
}
if (it == last)
{
if (count == 0) // must have at least one digit
return false;
attr = 0;
first = it;
return true;
}
}
typedef typename
traits::attribute_type<Attribute>::type
attribute_type;
attribute_type val = Accumulate ? attr : attribute_type(0);
char_type ch = *it;
if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
{
if (count == 0) // must have at least one digit
return false;
traits::move_to(val, attr);
first = it;
return true;
}
count = 0;
++it;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
traits::move_to(val, attr);
first = it;
return true;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
inline static bool
parse(
Iterator& first
, Iterator const& last
, unused_type)
{
T n = 0; // must calculate value to detect over/underflow
return parse_main(first, last, n);
}
template <typename Iterator, typename Attribute>
inline static bool
parse(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
return parse_main(first, last, attr);
}
};
#undef SPIRIT_NUMERIC_INNER_LOOP
///////////////////////////////////////////////////////////////////////////
// Cast an signed integer to an unsigned integer
///////////////////////////////////////////////////////////////////////////
template <typename T,
bool force_unsigned
= mpl::and_<is_integral<T>, is_signed<T> >::value>
struct cast_unsigned;
template <typename T>
struct cast_unsigned<T, true>
{
typedef typename make_unsigned<T>::type unsigned_type;
typedef typename make_unsigned<T>::type& unsigned_type_ref;
inline static unsigned_type_ref call(T& n)
{
return unsigned_type_ref(n);
}
};
template <typename T>
struct cast_unsigned<T, false>
{
inline static T& call(T& n)
{
return n;
}
};
}}}}
#endif
@@ -0,0 +1,143 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2011 Jan Frederick Eick
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_EXTRACT_INT_APRIL_17_2006_0830AM)
#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Extract the prefix sign (- or +), return true if a '-' was found
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline bool
extract_sign(Iterator& first, Iterator const& last)
{
(void)last; // silence unused warnings
BOOST_ASSERT(first != last); // precondition
// Extract the sign
bool neg = *first == '-';
if (neg || (*first == '+'))
{
++first;
return neg;
}
return false;
}
///////////////////////////////////////////////////////////////////////////
// Low level unsigned integer parser
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, bool Accumulate = false>
struct extract_uint
{
// check template parameter 'Radix' for validity
static_assert(
(Radix >= 2 && Radix <= 36),
"Error Unsupported Radix");
template <typename Iterator>
inline static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
typedef detail::extract_int<
T
, Radix
, MinDigits
, MaxDigits
, detail::positive_accumulator<Radix>
, Accumulate>
extract_type;
Iterator save = first;
if (!extract_type::parse(first, last,
detail::cast_unsigned<T>::call(attr)))
{
first = save;
return false;
}
return true;
}
template <typename Iterator, typename Attribute>
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
{
// this case is called when Attribute is not T
T attr;
if (call(first, last, attr))
{
traits::move_to(attr, attr_);
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////
// Low level signed integer parser
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct extract_int
{
// check template parameter 'Radix' for validity
static_assert(
(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
"Error Unsupported Radix");
template <typename Iterator>
inline static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
typedef detail::extract_int<
T, Radix, MinDigits, MaxDigits>
extract_pos_type;
typedef detail::extract_int<
T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
extract_neg_type;
Iterator save = first;
bool hit = extract_sign(first, last);
if (hit)
hit = extract_neg_type::parse(first, last, attr);
else
hit = extract_pos_type::parse(first, last, attr);
if (!hit)
{
first = save;
return false;
}
return true;
}
template <typename Iterator, typename Attribute>
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
{
// this case is called when Attribute is not T
T attr;
if (call(first, last, attr))
{
traits::move_to(attr, attr_);
return true;
}
return false;
}
};
}}}
#endif
@@ -0,0 +1,267 @@
/*=============================================================================
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(SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM)
#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
#include <cmath>
#include <boost/limits.hpp>
#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>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace spirit { namespace x3 { namespace extension
{
using x3::traits::pow10;
template <typename T>
inline void
scale(int exp, T& n)
{
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);
n *= pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
{
n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
}
else
{
n /= pow10<T>(-exp);
}
}
}
inline void
scale(int /*exp*/, unused_type /*n*/)
{
// no-op for unused_type
}
template <typename T>
inline void
scale(int exp, int frac, T& n)
{
scale(exp - frac, n);
}
inline void
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
}
inline float
negate(bool neg, float n)
{
return neg ? x3::changesign(n) : n;
}
inline double
negate(bool neg, double n)
{
return neg ? x3::changesign(n) : n;
}
inline long double
negate(bool neg, long double n)
{
return neg ? x3::changesign(n) : n;
}
template <typename T>
inline T
negate(bool neg, T const& n)
{
return neg ? -n : n;
}
inline unused_type
negate(bool /*neg*/, unused_type n)
{
// no-op for unused_type
return n;
}
template <typename T>
inline bool
is_equal_to_one(T const& value)
{
return value == 1.0;
}
inline bool
is_equal_to_one(unused_type)
{
// no-op for unused_type
return false;
}
}}}}
namespace boost { namespace spirit { namespace x3
{
template <typename T, typename RealPolicies>
struct extract_real
{
template <typename Iterator, typename Attribute>
static bool
parse(Iterator& first, Iterator const& last, Attribute& attr,
RealPolicies const& p)
{
if (first == last)
return false;
Iterator save = first;
// Start by parsing the sign. neg will be true if
// we got a "-" sign, false otherwise.
bool neg = p.parse_sign(first, last);
// Now attempt to parse an integer
T n = 0;
bool got_a_number = p.parse_n(first, last, n);
// If we did not get a number it might be a NaN, Inf or a leading
// dot.
if (!got_a_number)
{
// Check whether the number to parse is a NaN or Inf
if (p.parse_nan(first, last, n) ||
p.parse_inf(first, last, n))
{
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
return true; // got a NaN or Inf, return early
}
// If we did not get a number and our policies do not
// allow a leading dot, fail and return early (no-match)
if (!p.allow_leading_dot)
{
first = save;
return false;
}
}
bool e_hit = false;
int frac_digits = 0;
// Try to parse the dot ('.' decimal point)
if (p.parse_dot(first, last))
{
// We got the decimal point. Now we will try to parse
// the fraction if it is there. If not, it defaults
// to zero (0) only if we already got a number.
Iterator savef = first;
if (p.parse_frac_n(first, last, n))
{
// Optimization note: don't compute frac_digits if T is
// an unused_type. This should be optimized away by the compiler.
if (!is_same<T, unused_type>::value)
frac_digits =
static_cast<int>(std::distance(savef, first));
}
else if (!got_a_number || !p.allow_trailing_dot)
{
// We did not get a fraction. If we still haven't got a
// number and our policies do not allow a trailing dot,
// return no-match.
first = save;
return false;
}
// Now, let's see if we can parse the exponent prefix
e_hit = p.parse_exp(first, last);
}
else
{
// No dot and no number! Return no-match.
if (!got_a_number)
{
first = save;
return false;
}
// If we must expect a dot and we didn't see an exponent
// prefix, return no-match.
e_hit = p.parse_exp(first, last);
if (p.expect_dot && !e_hit)
{
first = save;
return false;
}
}
if (e_hit)
{
// We got the exponent prefix. Now we will try to parse the
// actual exponent. It is an error if it is not there.
int exp = 0;
if (p.parse_exp_n(first, last, exp))
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
extension::scale(exp, frac_digits, n);
}
else
{
// Oops, no exponent, return no-match.
first = save;
return false;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
extension::scale(-frac_digits, n);
}
else if (extension::is_equal_to_one(n))
{
// There is a chance of having to parse one of the 1.0#...
// styles some implementations use for representing NaN or Inf.
// Check whether the number to parse is a NaN or Inf
if (p.parse_nan(first, last, n) ||
p.parse_inf(first, last, n))
{
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
return true; // got a NaN or Inf, return immediately
}
}
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
// Success!!!
return true;
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
}}}
#endif
@@ -0,0 +1,112 @@
/*=============================================================================
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_POW10_DECEMBER_26_2008_1118AM)
#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
#endif
namespace boost { namespace spirit { namespace x3 { namespace traits
{
namespace detail
{
template <typename T, typename Enable = void>
struct pow10_helper
{
static T call(unsigned dim)
{
using namespace std; // allow for ADL to find the correct overload
return pow(T(10), T(dim));
}
};
template <>
struct pow10_helper<unused_type>
{
static unused_type call(unused_type)
{
return unused;
}
};
#if (DBL_MAX_10_EXP == 308) // for IEEE-754
template <>
struct pow10_helper<double>
{
static double call(unsigned dim)
{
static double const exponents[] =
{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
};
BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
return exponents[dim];
}
};
template <>
struct pow10_helper<float>
{
static float call(unsigned dim)
{
return pow10_helper<double>::call(dim);
}
};
#endif // for IEEE-754
}
template <typename T>
inline T pow10(unsigned dim)
{
return detail::pow10_helper<T>::call(dim);
}
}}}}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,44 @@
/*=============================================================================
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(SPIRIT_SIGN_MAR_11_2009_0734PM)
#define SPIRIT_SIGN_MAR_11_2009_0734PM
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#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;
}
// This routine has been taken and adapted from Johan Rade's fp_traits
// library
template<typename T>
inline T (changesign)(T x)
{
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
return -x;
#else
typedef typename math::detail::fp_traits<T>::type traits_type;
typename traits_type::bits a;
traits_type::get_bits(x, a);
a ^= traits_type::sign;
traits_type::set_bits(x, a);
return x;
#endif
}
}}}
#endif
@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustín Bergé
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_SUBCONTEXT_APR_15_2013_0840AM)
#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM
#include <boost/fusion/support/pair.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename... T>
struct subcontext;
template <>
struct subcontext<>
{
template <typename Context>
subcontext(Context const& /*context*/)
{}
template <typename ID_>
unused_type
get(ID_) const
{
return unused;
}
};
template <typename T>
struct subcontext<T>
: context<typename T::first_type, typename T::second_type>
{
typedef context<
typename T::first_type, typename T::second_type
> context_type;
template <typename Context>
subcontext(Context const& context)
: context_type(x3::get<typename T::first_type>(context))
{}
using context_type::get;
};
template <typename T, typename... Tail>
struct subcontext<T, Tail...>
: subcontext<Tail...>
, context<
typename T::first_type, typename T::second_type
, subcontext<Tail...>
>
{
typedef subcontext<Tail...> base_type;
typedef context<
typename T::first_type, typename T::second_type
, base_type
> context_type;
template <typename Context>
subcontext(Context const& context)
: base_type(context)
, context_type(
x3::get<typename T::first_type>(context)
, *static_cast<base_type*>(this))
{}
using context_type::get;
};
}}}
#endif
@@ -0,0 +1,78 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
#include <boost/mpl/identity.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/support/category_of.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
namespace boost { namespace spirit { namespace x3
{
struct unused_type;
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
struct unused_attribute {};
struct plain_attribute {};
struct container_attribute {};
struct tuple_attribute {};
struct associative_attribute {};
struct variant_attribute {};
struct optional_attribute {};
template <typename T, typename Enable = void>
struct attribute_category
: mpl::identity<plain_attribute> {};
template <>
struct attribute_category<unused_type>
: mpl::identity<unused_attribute> {};
template <>
struct attribute_category<unused_type const>
: mpl::identity<unused_attribute> {};
template <typename T>
struct attribute_category< T
, typename enable_if<
typename mpl::eval_if<
fusion::traits::is_sequence<T>
, fusion::traits::is_associative<T>
, mpl::false_
>::type >::type >
: mpl::identity<associative_attribute> {};
template <typename T>
struct attribute_category< T
, typename enable_if<
mpl::and_<
fusion::traits::is_sequence<T>
, mpl::not_<fusion::traits::is_associative<T> >
> >::type >
: mpl::identity<tuple_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<traits::is_variant<T>>::type>
: mpl::identity<variant_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<traits::is_container<T>>::type>
: mpl::identity<container_attribute> {};
}}}}
#endif
@@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_ATTRIBUTE_OF_JAN_7_2012_0914AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/enable_if.hpp>
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
// metafunction. Components may specialize this if such an attribute_type
// is not readily available (e.g. expensive to compute at compile time).
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct attribute_of;
namespace detail
{
template <typename Component, typename Context, typename Enable = void>
struct default_attribute_of;
template <typename Component, typename 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,
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,26 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Retrieve the attribute type to use from the given type
//
// This is needed to extract the correct attribute type from proxy classes
// as utilized in FUSION_ADAPT_ADT et. al.
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Enable = void>
struct attribute_type : mpl::identity<Attribute> {};
}}}}
#endif
@@ -0,0 +1,356 @@
/*=============================================================================
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_CONTAINER_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
#include <boost/fusion/support/category_of.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/fusion/include/deque.hpp>
#include <boost/tti/has_type.hpp>
#include <boost/tti/has_member_function.hpp>
#include <boost/mpl/identity.hpp>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains some container utils for stl containers.
///////////////////////////////////////////////////////////////////////////
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)
BOOST_TTI_HAS_MEMBER_FUNCTION(reserve)
}
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>;
template <typename T>
using is_associative = mpl::bool_<
detail::has_type_key_type<T>::value>;
template <typename T>
using is_reservable = mpl::bool_<
detail::has_member_function_reserve<T, void, mpl::vector<size_t>>::value>;
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct remove_value_const : mpl::identity<T> {};
template <typename T>
struct remove_value_const<T const> : remove_value_const<T> {};
template <typename F, typename S>
struct remove_value_const<std::pair<F, S>>
{
typedef typename remove_value_const<F>::type first_type;
typedef typename remove_value_const<S>::type second_type;
typedef std::pair<first_type, second_type> type;
};
}
///////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct container_value
: detail::remove_value_const<typename Container::value_type>
{};
template <typename Container>
struct container_value<Container const> : container_value<Container> {};
// There is no single container value for fusion maps, but because output
// of this metafunc is used to check wheter parser's attribute can be
// saved to container, we simply return whole fusion::map as is
// so that check can be done in traits::is_substitute specialisation
template <typename T>
struct container_value<T
, typename enable_if<typename mpl::eval_if <
fusion::traits::is_sequence<T>
, fusion::traits::is_associative<T>
, mpl::false_ >::type >::type>
: mpl::identity<T> {};
template <>
struct container_value<unused_type> : mpl::identity<unused_type> {};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct container_iterator
: mpl::identity<typename Container::iterator> {};
template <typename Container>
struct container_iterator<Container const>
: mpl::identity<typename Container::const_iterator> {};
template <>
struct container_iterator<unused_type>
: mpl::identity<unused_type const*> {};
template <>
struct container_iterator<unused_type const>
: mpl::identity<unused_type const*> {};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename T>
bool push_back(Container& c, T&& val);
template <typename Container, typename Enable = void>
struct push_back_container
{
template <typename T>
static bool call(Container& c, T&& val)
{
c.insert(c.end(), std::move(val));
return true;
}
};
template <typename Container, typename T>
inline bool push_back(Container& c, T&& val)
{
return push_back_container<Container>::call(c, std::move(val));
}
template <typename Container>
inline bool push_back(Container&, unused_type)
{
return true;
}
template <typename T>
inline bool push_back(unused_type, T&&)
{
return true;
}
inline bool push_back(unused_type, unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Iterator>
bool append(Container& c, Iterator first, Iterator last);
template <typename Container, typename Enable = void>
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_)
{
c.insert(c.end(), first, last);
}
template <typename Iterator>
static void insert(Container& c, Iterator first, Iterator last, mpl::true_)
{
c.insert(first, last);
}
public:
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;
}
};
template <typename Container, typename Iterator>
inline bool append(Container& c, Iterator first, Iterator last)
{
return append_container<Container>::call(c, first, last);
}
template <typename Iterator>
inline bool append(unused_type, Iterator first, Iterator last)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct is_empty_container
{
static bool call(Container const& c)
{
return c.empty();
}
};
template <typename Container>
inline bool is_empty(Container const& c)
{
return is_empty_container<Container>::call(c);
}
inline bool is_empty(unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct begin_container
{
static typename container_iterator<Container>::type call(Container& c)
{
return c.begin();
}
};
template <typename Container>
inline typename container_iterator<Container>::type
begin(Container& c)
{
return begin_container<Container>::call(c);
}
inline unused_type const*
begin(unused_type)
{
return &unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct end_container
{
static typename container_iterator<Container>::type call(Container& c)
{
return c.end();
}
};
template <typename Container>
inline typename container_iterator<Container>::type
end(Container& c)
{
return end_container<Container>::call(c);
}
inline unused_type const*
end(unused_type)
{
return &unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct deref_iterator
{
typedef typename boost::detail::iterator_traits<Iterator>::reference type;
static type call(Iterator& it)
{
return *it;
}
};
template <typename Iterator>
typename deref_iterator<Iterator>::type
deref(Iterator& it)
{
return deref_iterator<Iterator>::call(it);
}
inline unused_type
deref(unused_type const*)
{
return unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct next_iterator
{
static void call(Iterator& it)
{
++it;
}
};
template <typename Iterator>
void next(Iterator& it)
{
next_iterator<Iterator>::call(it);
}
inline void next(unused_type const*)
{
// do nothing
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct compare_iterators
{
static bool call(Iterator const& it1, Iterator const& it2)
{
return it1 == it2;
}
};
template <typename Iterator>
bool compare(Iterator& it1, Iterator& it2)
{
return compare_iterators<Iterator>::call(it1, it2);
}
inline bool compare(unused_type const*, unused_type const*)
{
return false;
}
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct build_container : mpl::identity<std::vector<T>> {};
template <typename T>
struct build_container<boost::fusion::deque<T> > : build_container<T> {};
template <>
struct build_container<unused_type> : mpl::identity<unused_type> {};
template <>
struct build_container<char> : mpl::identity<std::string> {};
}}}}
#endif
@@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2013 Agustin Berge
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_HANDLES_CONTAINER_DEC_18_2010_0920AM)
#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Whether a component handles container attributes intrinsically
// (or whether container attributes need to be split up separately).
// By default, this gets the Component's handles_container nested value.
// Components may specialize this if such a handles_container is not
// readily available (e.g. expensive to compute at compile time).
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct handles_container : mpl::bool_<Component::handles_container> {};
}}}}
#endif
@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
struct unused_type;
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Whether a component has an attribute. By default, this compares the
// component attribute against unused_type. If the component provides a
// nested constant expression has_attribute as a hint, that value is used
// instead. Components may specialize this.
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct has_attribute;
namespace detail
{
template <typename Component, typename Context, typename Enable = void>
struct default_has_attribute
: mpl::not_<is_same<unused_type,
typename attribute_of<Component, Context>::type>> {};
template <typename Component, typename Context>
struct default_has_attribute<Component, Context,
typename disable_if_substitution_failure<
mpl::bool_<Component::has_attribute>>::type>
: mpl::bool_<Component::has_attribute> {};
template <typename Component, typename Context>
struct default_has_attribute<Component, Context,
typename enable_if_c<Component::is_pass_through_unary>::type>
: has_attribute<typename Component::subject_type, Context> {};
}
template <typename Component, typename Context, typename Enable>
struct has_attribute : detail::default_has_attribute<Component, Context> {};
}}}}
#endif
@@ -0,0 +1,33 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2014 Agustin Berge
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_IS_PARSER_MAY_20_2013_0235PM)
#define BOOST_SPIRIT_X3_IS_PARSER_MAY_20_2013_0235PM
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// is_parser<T>: metafunction that evaluates to mpl::true_ if a type T
// can be used as a parser, mpl::false_ otherwise
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct is_parser
: mpl::false_
{};
template <typename T>
struct is_parser<T, typename disable_if_substitution_failure<
typename extension::as_parser<T>::type>::type>
: mpl::true_
{};
}}}}
#endif
@@ -0,0 +1,160 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)
#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/value_at_key.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/count_if.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/optional/optional.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Find out if T can be a (strong) substitute for Attribute
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute;
template <typename Variant, typename Attribute>
struct variant_has_substitute;
namespace detail
{
template <typename T, typename Attribute>
struct value_type_is_substitute
: is_substitute<
typename container_value<T>::type
, typename container_value<Attribute>::type>
{};
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute_impl : is_same<T, Attribute> {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
typename enable_if<
mpl::and_<
fusion::traits::is_sequence<T>,
fusion::traits::is_sequence<Attribute>,
mpl::equal<T, Attribute, is_substitute<mpl::_1, mpl::_2>>
>
>::type>
: mpl::true_ {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
typename enable_if<
mpl::and_<
is_container<T>,
is_container<Attribute>,
value_type_is_substitute<T, Attribute>
>
>::type>
: mpl::true_ {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
typename enable_if<
is_variant<Attribute>
>::type>
: mpl::or_<
is_same<T, Attribute>
, variant_has_substitute<Attribute, T>
>
{};
}
template <typename T, typename Attribute, typename Enable /*= void*/>
struct is_substitute
: detail::is_substitute_impl<T, Attribute> {};
// for reference T
template <typename T, typename Attribute, typename Enable>
struct is_substitute<T&, Attribute, Enable>
: is_substitute<T, Attribute, Enable> {};
// for reference Attribute
template <typename T, typename Attribute, typename Enable>
struct is_substitute<T, Attribute&, Enable>
: is_substitute<T, Attribute, Enable> {};
// 2 element mpl tuple is compatible with fusion::map if:
// - it's first element type is existing key in map
// - it second element type is compatible to type stored at the key in map
template <typename T, typename Attribute>
struct is_substitute<T, Attribute
, typename enable_if<
typename mpl::eval_if<
mpl::and_<fusion::traits::is_sequence<T>
, fusion::traits::is_sequence<Attribute>>
, mpl::and_<traits::has_size<T, 2>
, fusion::traits::is_associative<Attribute>>
, mpl::false_>::type>::type>
{
// checking that "p_key >> p_value" parser can
// store it's result in fusion::map attribute
typedef typename mpl::at_c<T, 0>::type p_key;
typedef typename mpl::at_c<T, 1>::type p_value;
// for simple p_key type we just check that
// such key can be found in attr and that value under that key
// matches p_value
template <typename Key, typename Value, typename Map>
struct has_kv_in_map
: mpl::eval_if<
fusion::result_of::has_key<Map, Key>
, mpl::apply<
is_substitute<
fusion::result_of::value_at_key<mpl::_1, Key>
, Value>
, Map>
, mpl::false_>
{};
// if p_key is variant over multiple types (as a result of
// "(key1|key2|key3) >> p_value" parser) check that all
// keys are found in fusion::map attribute and that values
// under these keys match p_value
template <typename Variant>
struct variant_kv
: mpl::equal_to<
mpl::size< typename Variant::types>
, mpl::size< mpl::filter_view<typename Variant::types
, has_kv_in_map<mpl::_1, p_value, Attribute>>>
>
{};
typedef typename
mpl::eval_if<
is_variant<p_key>
, variant_kv<p_key>
, has_kv_in_map<p_key, p_value, Attribute>
>::type
type;
};
template <typename T, typename Attribute>
struct is_substitute<optional<T>, optional<Attribute>>
: is_substitute<T, Attribute> {};
}}}}
#endif
@@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM)
#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM
#include <boost/variant.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
namespace detail
{
// By declaring a nested struct in your class/struct, you tell
// spirit that it is regarded as a variant type. The minimum
// required interface for such a variant is that it has constructors
// for various types supported by your variant and a typedef 'types'
// which is an mpl sequence of the contained types.
//
// This is an intrusive interface. For a non-intrusive interface,
// use the is_variant trait.
BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
}
template <typename T, typename Enable = void>
struct is_variant
: detail::has_adapted_variant_tag<T>
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
: mpl::true_
{};
}}}}
#endif
@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2012 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_MAKE_ATTRIBUTE_JAN_8_2012_0721PM)
#define BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM
#include <boost/mpl/if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Attribute>
struct make_attribute_base
{
static Attribute call(unused_type)
{
// synthesize the attribute/parameter
return Attribute();
}
template <typename T>
static T& call(T& value)
{
return value; // just pass the one provided
}
};
template <typename Attribute, typename ActualAttribute>
struct make_attribute : make_attribute_base<Attribute>
{
typedef ActualAttribute& type;
typedef ActualAttribute value_type;
};
template <typename Attribute>
struct make_attribute<Attribute, unused_type>
: make_attribute_base<Attribute>
{
typedef typename remove_const<Attribute>::type attribute_type;
typedef attribute_type type;
typedef attribute_type value_type;
};
template <typename Attribute, typename ActualAttribute>
struct make_attribute<Attribute&, ActualAttribute>
: make_attribute<Attribute, ActualAttribute> {};
template <typename Attribute, typename ActualAttribute>
struct make_attribute<Attribute const&, ActualAttribute>
: make_attribute<Attribute const, ActualAttribute> {};
template <typename ActualAttribute>
struct make_attribute<unused_type, ActualAttribute>
{
typedef unused_type type;
typedef unused_type value_type;
static unused_type call(unused_type)
{
return unused;
}
};
template <>
struct make_attribute<unused_type, unused_type>
{
typedef unused_type type;
typedef unused_type value_type;
static unused_type call(unused_type)
{
return unused;
}
};
}}}}
#endif
@@ -0,0 +1,213 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2013 Agustin Berge
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_MOVE_TO_JAN_17_2013_0859PM)
#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
#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/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/move.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/range/iterator_range.hpp>
#include <utility>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Source, typename Dest>
inline void move_to(Source&& src, Dest& dest);
template <typename T>
inline void move_to(T& src, T& dest);
template <typename T>
inline void move_to(T const& src, T& dest);
template <typename T>
inline void move_to(T&& src, T& dest);
template <typename Iterator, typename Dest>
inline void move_to(Iterator first, Iterator last, Dest& dest);
template <typename Dest>
inline void move_to(unused_type, Dest&) {}
template <typename Source>
inline void move_to(Source&, unused_type) {}
inline void move_to(unused_type, unused_type) {}
template <typename Iterator>
inline void
move_to(Iterator, Iterator, unused_type) {}
namespace detail
{
template <typename Source, typename Dest>
inline void
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
{
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
{
dest = std::move(fusion::front(src));
}
template <typename Source, typename Dest>
inline void
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);
}
template <typename Source, typename Dest>
inline typename enable_if<is_container<Source>>::type
move_to(Source&& src, Dest& dest, container_attribute)
{
traits::move_to(src.begin(), src.end(), dest);
}
template <typename Source, typename Dest>
inline typename enable_if<
mpl::and_<
is_same_size_sequence<Dest, Source>,
mpl::not_<is_size_one_sequence<Dest> > >
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
{
fusion::move(std::forward<Source>(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)
{
traits::move_to(std::forward<Source>(src), fusion::front(dest));
}
template <typename Source, typename Dest>
inline void
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_)
{
// 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.
// Make sure that the Dest variant can really hold Source
static_assert(variant_has_substitute<Dest, typename fusion::result_of::front<Source>::type>::value,
"Error! The destination variant (Dest) cannot hold the source type (Source)");
dest = std::move(fusion::front(src));
}
template <typename Source, typename Dest>
inline void
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.
dest = std::move(src);
}
template <typename Source, typename Dest>
inline void
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(src, dest, tag, is_size_one_sequence<Source>());
}
template <typename Iterator>
inline void
move_to(Iterator, Iterator, unused_type, unused_attribute) {}
template <typename Iterator, typename Dest>
inline void
move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
{
if (is_empty(dest))
dest = Dest(first, last);
else
append(dest, first, last);
}
template <typename Iterator>
inline void
move_to(Iterator first, Iterator last, boost::iterator_range<Iterator>& rng, container_attribute)
{
rng = {first, last};
}
}
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());
}
template <typename T>
inline void move_to(T& src, T& dest)
{
if (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);
}
template <typename T>
inline void move_to(T&& src, T& dest)
{
if (boost::addressof(src) != boost::addressof(dest))
dest = std::move(src);
}
template <typename Iterator, typename Dest>
inline void move_to(Iterator first, Iterator last, Dest& dest)
{
// $$$ Use std::move_iterator when iterator is not a const-iterator $$$
detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
}
}}}}
#endif
@@ -0,0 +1,124 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
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_NUMERIC_TRAITS_JAN_07_2011_0722AM)
#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Determine if T is a boolean type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_bool : mpl::false_ {};
template <typename T>
struct is_bool<T const> : is_bool<T> {};
template <>
struct is_bool<bool> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Determine if T is a signed integer type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_int : mpl::false_ {};
template <typename T>
struct is_int<T const> : is_int<T> {};
template <>
struct is_int<short> : mpl::true_ {};
template <>
struct is_int<int> : mpl::true_ {};
template <>
struct is_int<long> : mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct is_int<boost::long_long_type> : mpl::true_ {};
#endif
///////////////////////////////////////////////////////////////////////////
// Determine if T is an unsigned integer type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_uint : mpl::false_ {};
template <typename T>
struct is_uint<T const> : is_uint<T> {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct is_uint<unsigned short> : mpl::true_ {};
#endif
template <>
struct is_uint<unsigned int> : mpl::true_ {};
template <>
struct is_uint<unsigned long> : mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct is_uint<boost::ulong_long_type> : mpl::true_ {};
#endif
///////////////////////////////////////////////////////////////////////////
// Determine if T is a floating point type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_real : mpl::false_ {};
template <typename T>
struct is_real<T const> : is_uint<T> {};
template <>
struct is_real<float> : mpl::true_ {};
template <>
struct is_real<double> : mpl::true_ {};
template <>
struct is_real<long double> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// customization points for numeric operations
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct absolute_value;
template <typename T, typename Enable = void>
struct is_negative;
template <typename T, typename Enable = void>
struct is_zero;
template <typename T, typename Enable = void>
struct pow10_helper;
template <typename T, typename Enable = void>
struct is_nan;
template <typename T, typename Enable = void>
struct is_infinite;
template <typename T, typename Enable = void>
struct check_overflow : mpl::false_ {};
template <typename T>
struct check_overflow<T, typename enable_if_c<integer_traits<T>::is_integral>::type>
: mpl::true_ {};
}}}}
#endif
@@ -0,0 +1,74 @@
/*=============================================================================
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_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/optional/optional.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct is_optional
: mpl::false_
{};
template <typename T>
struct is_optional<boost::optional<T>>
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////////
// build_optional
//
// Build a boost::optional from T. Return unused_type if T is unused_type.
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct build_optional
{
typedef boost::optional<T> type;
};
template <typename T>
struct build_optional<boost::optional<T> >
{
typedef boost::optional<T> type;
};
template <>
struct build_optional<unused_type>
{
typedef unused_type type;
};
///////////////////////////////////////////////////////////////////////////
// optional_value
//
// Get the optional's value_type. Handles unused_type as well.
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct optional_value : mpl::identity<T> {};
template <typename T>
struct optional_value<boost::optional<T> >
: mpl::identity<T> {};
template <>
struct optional_value<unused_type>
: mpl::identity<unused_type> {};
template <>
struct optional_value<unused_type const>
: mpl::identity<unused_type> {};
}}}}
#endif
@@ -0,0 +1,146 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
#include <boost/variant.hpp>
#include <boost/optional/optional.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Out, typename T>
void print_attribute(Out& out, T const& val);
template <typename Out>
inline void print_attribute(Out&, unused_type) {}
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename Out>
struct print_fusion_sequence
{
print_fusion_sequence(Out& out)
: out(out), is_first(true) {}
typedef void result_type;
template <typename T>
void operator()(T const& val) const
{
if (is_first)
is_first = false;
else
out << ", ";
x3::traits::print_attribute(out, val);
}
Out& out;
mutable bool is_first;
};
// print elements in a variant
template <typename Out>
struct print_visitor : static_visitor<>
{
print_visitor(Out& out) : out(out) {}
template <typename T>
void operator()(T const& val) const
{
x3::traits::print_attribute(out, val);
}
Out& out;
};
}
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)
{
out << "unused";
}
// for plain data types
template <typename T_>
static void call(Out& out, T_ const& val, plain_attribute)
{
out << val;
}
// for fusion data types
template <typename T_>
static void call(Out& out, T_ const& val, tuple_attribute)
{
out << '[';
fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
out << ']';
}
// stl container
template <typename T_>
static void call(Out& out, T_ const& val, container_attribute)
{
out << '[';
if (!traits::is_empty(val))
{
bool first = true;
typename container_iterator<T_ const>::type iend = traits::end(val);
for (typename container_iterator<T_ const>::type i = traits::begin(val);
!traits::compare(i, iend); traits::next(i))
{
if (!first)
out << ", ";
first = false;
x3::traits::print_attribute(out, traits::deref(i));
}
}
out << ']';
}
// for variant types
template <typename T_>
static void call(Out& out, T_ const& val, variant_attribute)
{
apply_visitor(detail::print_visitor<Out>(out), val);
}
// for optional types
template <typename T_>
static void call(Out& out, T_ const& val, optional_attribute)
{
if (val)
x3::traits::print_attribute(out, *val);
else
out << "[empty]";
}
// main entry point
static void call(Out& out, T const& val)
{
call(out, val, typename attribute_category<T>::type());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Out, typename T>
inline void print_attribute(Out& out, T const& val)
{
print_attribute_debug<Out, T>::call(out, val);
}
}}}}
#endif
@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
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_PRINT_TOKEN_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cctype>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// generate debug output for lookahead token (character) stream
namespace detail
{
struct token_printer_debug_for_chars
{
template<typename Out, typename Char>
static void print(Out& o, Char c)
{
using namespace std; // allow for ADL to find the proper iscntrl
switch (c)
{
case '\a': o << "\\a"; break;
case '\b': o << "\\b"; break;
case '\f': o << "\\f"; break;
case '\n': o << "\\n"; break;
case '\r': o << "\\r"; break;
case '\t': o << "\\t"; break;
case '\v': o << "\\v"; break;
default:
if (c >= 0 && c < 127 && iscntrl(c))
o << "\\" << std::oct << int(c);
else
o << Char(c);
}
}
};
// for token types where the comparison with char constants wouldn't work
struct token_printer_debug
{
template<typename Out, typename T>
static void print(Out& o, T const& val)
{
o << val;
}
};
}
template <typename T, typename Enable = void>
struct token_printer_debug
: mpl::if_<
mpl::and_<
is_convertible<T, char>, is_convertible<char, T> >
, detail::token_printer_debug_for_chars
, detail::token_printer_debug>::type
{};
template <typename Out, typename T>
inline void print_token(Out& out, T const& val)
{
// allow to customize the token printer routine
token_printer_debug<T>::print(out, val);
}
}}}}
#endif
@@ -0,0 +1,287 @@
/*=============================================================================
Copyright (c) 2001-2014 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 Bryce Lelbach
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
================================================_==============================*/
#if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
#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
///////////////////////////////////////////////////////////////////////////
template <typename String>
struct extract_c_string;
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)
{
return (T const*)str;
}
template <typename T>
static T const* call (T const* str)
{
return str;
}
};
// Forwarder that strips const
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)
{
return extract_c_string<T>::call(str);
}
};
// Forwarder that strips references
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)
{
return extract_c_string<T>::call(str);
}
};
// Forwarder that strips const references
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)
{
return extract_c_string<T>::call(str);
}
};
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)
{
return str.c_str();
}
};
template <typename T>
typename extract_c_string<T*>::char_type const*
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)
{
return extract_c_string<T const*>::call(str);
}
template <typename String>
typename extract_c_string<String>::char_type const*
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)
{
return extract_c_string<String>::call(str);
}
///////////////////////////////////////////////////////////////////////////
// Get the begin/end iterators from a string
///////////////////////////////////////////////////////////////////////////
// Implementation for C-style strings.
template <typename T>
inline T const* get_string_begin(T const* str) { return str; }
template <typename T>
inline T* get_string_begin(T* str) { return str; }
template <typename T>
inline T const* get_string_end(T const* str)
{
T const* last = str;
while (*last)
last++;
return last;
}
template <typename T>
inline T* get_string_end(T* str)
{
T* last = str;
while (*last)
last++;
return last;
}
// Implementation for containers (includes basic_string).
template <typename T, typename Str>
inline typename Str::const_iterator get_string_begin(Str const& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_begin(Str& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::const_iterator get_string_end(Str const& str)
{ return str.end(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_end(Str& str)
{ return str.end(); }
}}}}
#endif

Some files were not shown because too many files have changed in this diff Show More