stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -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
|
||||
+293
@@ -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
|
||||
+20
@@ -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
|
||||
+110
@@ -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
|
||||
+146
@@ -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
|
||||
+300
@@ -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
|
||||
+503
@@ -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
|
||||
+60
@@ -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
|
||||
+85
@@ -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
|
||||
+96
@@ -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
|
||||
+508
@@ -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
|
||||
+143
@@ -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
|
||||
+267
@@ -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
|
||||
+112
@@ -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
|
||||
+44
@@ -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
|
||||
+78
@@ -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
|
||||
+55
@@ -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
|
||||
+26
@@ -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
|
||||
+356
@@ -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
|
||||
+27
@@ -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
|
||||
+59
@@ -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
|
||||
+160
@@ -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
|
||||
+41
@@ -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
|
||||
+82
@@ -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
|
||||
+124
@@ -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
|
||||
+74
@@ -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
|
||||
+146
@@ -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
|
||||
+75
@@ -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
|
||||
+287
@@ -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
Reference in New Issue
Block a user