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

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,217 @@
/*=============================================================================
Copyright (c) 2001-2011 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_ACTION_DISPATCH_APRIL_18_2008_0720AM)
#define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
#if defined(_MSC_VER)
#pragma once
#endif
#include<boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
#include <utility>
#include <type_traits>
#endif
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/support/attributes.hpp>
namespace boost { namespace spirit { namespace traits
{
template <typename Component>
struct action_dispatch
{
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
// omit function parameters without specializing for each possible
// type of callable entity
// many thanks to Eelis/##iso-c++ for this contribution
private:
// this will be used to pass around POD types which are safe
// to go through the ellipsis operator (if ever used)
template <typename>
struct fwd_tag {};
// the first parameter is a placeholder to obtain SFINAE when
// doing overload resolution, the second one is the actual
// forwarder, where we can apply our implementation
template <typename, typename T>
struct fwd_storage { typedef T type; };
// gcc should accept fake<T>() but it prints a sorry, needs
// a check once the bug is sorted out, use a FAKE_CALL macro for now
template <typename T>
T fake_call();
#define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0)
// the forwarders, here we could tweak the implementation of
// how parameters are passed to the functions, if needed
struct fwd_none
{
template<typename F, typename... Rest>
auto operator()(F && f, Rest&&...) -> decltype(f())
{
return f();
}
};
struct fwd_attrib
{
template<typename F, typename A, typename... Rest>
auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a))
{
return f(a);
}
};
struct fwd_attrib_context
{
template<typename F, typename A, typename B, typename... Rest>
auto operator()(F && f, A && a, B && b, Rest&&...)
-> decltype(f(a, b))
{
return f(a, b);
}
};
struct fwd_attrib_context_pass
{
template<typename F, typename A, typename B, typename C
, typename... Rest>
auto operator()(F && f, A && a, B && b, C && c, Rest&&...)
-> decltype(f(a, b, c))
{
return f(a, b, c);
}
};
// SFINAE for our calling syntax, the forwarders are stored based
// on what function call gives a proper result
// this code can probably be more generic once implementations are
// steady
template <typename F>
static auto do_call(F && f, ...)
-> typename fwd_storage<decltype(f()), fwd_none>::type
{
return {};
}
template <typename F, typename A>
static auto do_call(F && f, fwd_tag<A>, ...)
-> typename fwd_storage<decltype(f(BOOST_SPIRIT_FAKE_CALL(A)))
, fwd_attrib>::type
{
return {};
}
template <typename F, typename A, typename B>
static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, ...)
-> typename fwd_storage<
decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)))
, fwd_attrib_context>::type
{
return {};
}
template <typename F, typename A, typename B, typename C>
static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, fwd_tag<C>, ...)
-> typename fwd_storage<
decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)
, BOOST_SPIRIT_FAKE_CALL(C)))
, fwd_attrib_context_pass>::type
{
return {};
}
// this function calls the forwarder and is responsible for
// stripping the tail of the parameters
template <typename F, typename... A>
static void caller(F && f, A && ... a)
{
do_call(f, fwd_tag<typename std::remove_reference<A>::type>()...)
(std::forward<F>(f), std::forward<A>(a)...);
}
#undef BOOST_SPIRIT_FAKE_CALL
public:
template <typename F, typename Attribute, typename Context>
bool operator()(F const& f, Attribute& attr, Context& context)
{
bool pass = true;
caller(f, attr, context, pass);
return pass;
}
#else
// general handler for everything not explicitly specialized below
template <typename F, typename Attribute, typename Context>
bool operator()(F const& f, Attribute& attr, Context& context)
{
bool pass = true;
f(attr, context, pass);
return pass;
}
#endif
// handler for phoenix actors
// If the component this action has to be invoked for is a tuple, we
// wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
// and pass through any fusion tuple.
template <typename Eval, typename Attribute, typename Context>
bool operator()(phoenix::actor<Eval> const& f
, Attribute& attr, Context& context)
{
bool pass = true;
typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
f(attr_wrap, context, pass);
return pass;
}
// specializations for plain function pointers taking different number of
// arguments
template <typename RT, typename A0, typename A1, typename A2
, typename Attribute, typename Context>
bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
{
bool pass = true;
f(attr, context, pass);
return pass;
}
template <typename RT, typename A0, typename A1
, typename Attribute, typename Context>
bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
{
f(attr, context);
return true;
}
template <typename RT, typename A0, typename Attribute, typename Context>
bool operator()(RT(*f)(A0), Attribute& attr, Context&)
{
f(attr);
return true;
}
template <typename RT, typename Attribute, typename Context>
bool operator()(RT(*f)(), Attribute&, Context&)
{
f();
return true;
}
};
}}}
#endif
@@ -0,0 +1,406 @@
// 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_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM)
#define BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/numeric_traits.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/utility/enable_if.hpp>
///////////////////////////////////////////////////////////////////////////////
// customization points allowing to use adapted classes with spirit
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, bool Const, typename Domain>
struct not_is_variant<
fusion::extension::adt_attribute_proxy<T, N, Const>, Domain>
: not_is_variant<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
, Domain>
{};
template <typename T, int N, bool Const, typename Domain>
struct not_is_optional<
fusion::extension::adt_attribute_proxy<T, N, Const>, Domain>
: not_is_optional<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
, Domain>
{};
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, bool Const>
struct is_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
: is_container<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>
{};
template <typename T, int N, bool Const>
struct container_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
: container_value<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<
T, N, Const
>::type
>::type
>
{};
template <typename T, int N, bool Const>
struct container_value<
fusion::extension::adt_attribute_proxy<T, N, Const> const>
: container_value<
typename add_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<
T, N, Const
>::type
>::type
>::type
>
{};
template <typename T, int N, typename Val>
struct push_back_container<
fusion::extension::adt_attribute_proxy<T, N, false>
, Val
, typename enable_if<is_reference<
typename fusion::extension::adt_attribute_proxy<T, N, false>::type
> >::type>
{
static bool call(
fusion::extension::adt_attribute_proxy<T, N, false>& p
, Val const& val)
{
typedef typename
fusion::extension::adt_attribute_proxy<T, N, false>::type
type;
return push_back(type(p), val);
}
};
template <typename T, int N, bool Const>
struct container_iterator<
fusion::extension::adt_attribute_proxy<T, N, Const> >
: container_iterator<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<
T, N, Const
>::type
>::type
>
{};
template <typename T, int N, bool Const>
struct container_iterator<
fusion::extension::adt_attribute_proxy<T, N, Const> const>
: container_iterator<
typename add_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<
T, N, Const
>::type
>::type
>::type
>
{};
template <typename T, int N, bool Const>
struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
typedef typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type container_type;
static typename container_iterator<container_type>::type
call(fusion::extension::adt_attribute_proxy<T, N, Const>& c)
{
return c.get().begin();
}
};
template <typename T, int N, bool Const>
struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> const>
{
typedef typename add_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type container_type;
static typename container_iterator<container_type>::type
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c)
{
return c.get().begin();
}
};
template <typename T, int N, bool Const>
struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
typedef typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type container_type;
static typename container_iterator<container_type>::type
call(fusion::extension::adt_attribute_proxy<T, N, Const>& c)
{
return c.get().end();
}
};
template <typename T, int N, bool Const>
struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> const>
{
typedef typename add_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type container_type;
static typename container_iterator<container_type>::type
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c)
{
return c.get().end();
}
};
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, typename Val>
struct assign_to_attribute_from_value<
fusion::extension::adt_attribute_proxy<T, N, false>
, Val>
{
static void
call(Val const& val
, fusion::extension::adt_attribute_proxy<T, N, false>& attr)
{
attr = val;
}
};
template <typename T, int N, bool Const, typename Exposed>
struct extract_from_attribute<
fusion::extension::adt_attribute_proxy<T, N, Const>, Exposed>
{
typedef typename remove_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type embedded_type;
typedef
typename spirit::result_of::extract_from<Exposed, embedded_type>::type
type;
template <typename Context>
static type
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val, Context& ctx)
{
return extract_from<Exposed>(val.get(), ctx);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, bool Const>
struct attribute_type<fusion::extension::adt_attribute_proxy<T, N, Const> >
: fusion::extension::adt_attribute_proxy<T, N, Const>
{};
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, bool Const>
struct optional_attribute<
fusion::extension::adt_attribute_proxy<T, N, Const> >
{
typedef typename result_of::optional_value<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type type;
static type
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return optional_value(val.get());
}
static bool
is_valid(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return has_optional_value(val.get());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename T, int N, typename Attribute, typename Domain>
struct transform_attribute<
fusion::extension::adt_attribute_proxy<T, N, false>
, Attribute
, Domain
, typename disable_if<is_reference<
typename fusion::extension::adt_attribute_proxy<T, N, false>::type
> >::type>
{
typedef Attribute type;
static Attribute
pre(fusion::extension::adt_attribute_proxy<T, N, false>& val)
{
return val;
}
static void
post(
fusion::extension::adt_attribute_proxy<T, N, false>& val
, Attribute const& attr)
{
val = attr;
}
static void
fail(fusion::extension::adt_attribute_proxy<T, N, false>&)
{
}
};
template <
typename T, int N, bool Const, typename Attribute, typename Domain>
struct transform_attribute<
fusion::extension::adt_attribute_proxy<T, N, Const>
, Attribute
, Domain
, typename enable_if<is_reference<
typename fusion::extension::adt_attribute_proxy<
T, N, Const
>::type
> >::type>
{
typedef Attribute& type;
static Attribute&
pre(fusion::extension::adt_attribute_proxy<T, N, Const>& val)
{
return val;
}
static void
post(
fusion::extension::adt_attribute_proxy<T, N, Const>&
, Attribute const&)
{
}
static void
fail(fusion::extension::adt_attribute_proxy<T, N, Const>&)
{
}
};
template <typename T, int N, bool Const>
struct clear_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
static void call(
fusion::extension::adt_attribute_proxy<T, N, Const>& val)
{
typedef typename
fusion::extension::adt_attribute_proxy<T, N, Const>::type
type;
clear(type(val));
}
};
template <typename T, int N, bool Const>
struct attribute_size<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
typedef typename remove_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type embedded_type;
typedef typename attribute_size<embedded_type>::type type;
static type
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return attribute_size<embedded_type>::call(val.get());
}
};
///////////////////////////////////////////////////////////////////////////
// customization point specializations for numeric generators
template <typename T, int N, bool Const>
struct absolute_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
typedef typename
fusion::extension::adt_attribute_proxy<T, N, Const>::type
type;
static type
call (fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return get_absolute_value(val.get());
}
};
template <typename T, int N, bool Const>
struct is_negative<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
static bool
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return test_negative(val.get());
}
};
template <typename T, int N, bool Const>
struct is_zero<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
static bool
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return test_zero(val.get());
}
};
template <typename T, int N, bool Const>
struct is_nan<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
static bool
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return test_nan(val.get());
}
};
template <typename T, int N, bool Const>
struct is_infinite<fusion::extension::adt_attribute_proxy<T, N, Const> >
{
static bool
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
{
return test_infinite(val.get());
}
};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace result_of
{
template <typename T, int N, bool Const>
struct optional_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
: result_of::optional_value<
typename remove_const<
typename remove_reference<
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
>::type
>::type>
{};
}}}
#endif
@@ -0,0 +1,76 @@
/*=============================================================================
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_ANY_APRIL_22_2006_1147AM)
#define BOOST_SPIRIT_ANY_APRIL_22_2006_1147AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/fusion/include/equal_to.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/deref.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit
{
// This is the binary version of fusion::any. This might
// be a good candidate for inclusion in fusion algorithm
namespace detail
{
template <typename First1, typename Last, typename First2, typename F>
inline bool
any(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
{
return false;
}
template <typename First1, typename Last, typename First2, typename F>
inline bool
any(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
{
return f(*first1, *first2) ||
detail::any(
fusion::next(first1)
, fusion::next(first2)
, last
, f
, fusion::result_of::equal_to<
typename fusion::result_of::next<First1>::type, Last>());
}
}
template <typename Sequence1, typename Sequence2, typename F>
inline bool
any(Sequence1 const& seq1, Sequence2& seq2, F f)
{
return detail::any(
fusion::begin(seq1)
, fusion::begin(seq2)
, fusion::end(seq1)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence1>::type
, typename fusion::result_of::end<Sequence1>::type>());
}
template <typename Sequence, typename F>
inline bool
any(Sequence const& seq, unused_type, F f)
{
return fusion::any(seq, f);
}
}}
#endif
@@ -0,0 +1,220 @@
/*=============================================================================
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_ANY_IF_MARCH_30_2007_1220PM)
#define BOOST_SPIRIT_ANY_IF_MARCH_30_2007_1220PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/include/equal_to.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/deref.hpp>
#include <boost/fusion/include/value_of.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// This is a special version for a binary fusion::any. The predicate
// is used to decide whether to advance the second iterator or not.
// This is needed for sequences containing components with unused
// attributes. The second iterator is advanced only if the attribute
// of the corresponding component iterator is not unused.
///////////////////////////////////////////////////////////////////////////
namespace detail
{
///////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Pred>
struct apply_predicate
: mpl::apply1<Pred, typename fusion::result_of::value_of<Iterator>::type>
{};
///////////////////////////////////////////////////////////////////////
// if the predicate is true, attribute_next returns next(Iterator2),
// otherwise Iterator2
namespace result_of
{
template <
typename Iterator1, typename Iterator2, typename Last2
, typename Pred>
struct attribute_next
{
typedef mpl::and_<
apply_predicate<Iterator1, Pred>
, mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
> pred;
typedef typename
mpl::eval_if<
pred
, fusion::result_of::next<Iterator2>
, mpl::identity<Iterator2>
>::type
type;
template <typename Iterator>
static type
call(Iterator const& i, mpl::true_)
{
return fusion::next(i);
}
template <typename Iterator>
static type
call(Iterator const& i, mpl::false_)
{
return i;
}
template <typename Iterator>
static type
call(Iterator const& i)
{
return call(i, pred());
}
};
}
template <
typename Pred, typename Iterator1, typename Last2
, typename Iterator2>
inline typename
result_of::attribute_next<Iterator1, Iterator2, Last2, Pred
>::type const
attribute_next(Iterator2 const& i)
{
return result_of::attribute_next<
Iterator1, Iterator2, Last2, Pred>::call(i);
}
///////////////////////////////////////////////////////////////////////
// if the predicate is true, attribute_value returns deref(Iterator2),
// otherwise unused
namespace result_of
{
template <
typename Iterator1, typename Iterator2, typename Last2
, typename Pred>
struct attribute_value
{
typedef mpl::and_<
apply_predicate<Iterator1, Pred>
, mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
> pred;
typedef typename
mpl::eval_if<
pred
, fusion::result_of::deref<Iterator2>
, mpl::identity<unused_type const>
>::type
type;
template <typename Iterator>
static type
call(Iterator const& i, mpl::true_)
{
return fusion::deref(i);
}
template <typename Iterator>
static type
call(Iterator const&, mpl::false_)
{
return unused;
}
template <typename Iterator>
static type
call(Iterator const& i)
{
return call(i, pred());
}
};
}
template <
typename Pred, typename Iterator1, typename Last2
, typename Iterator2>
inline typename
result_of::attribute_value<Iterator1, Iterator2, Last2, Pred
>::type
attribute_value(Iterator2 const& i)
{
return result_of::attribute_value<
Iterator1, Iterator2, Last2, Pred>::call(i);
}
///////////////////////////////////////////////////////////////////////
template <
typename Pred, typename First1, typename Last1, typename First2
, typename Last2, typename F>
inline bool
any_if (First1 const&, First2 const&, Last1 const&, Last2 const&
, F const&, mpl::true_)
{
return false;
}
template <
typename Pred, typename First1, typename Last1, typename First2
, typename Last2, typename F>
inline bool
any_if (First1 const& first1, First2 const& first2, Last1 const& last1
, Last2 const& last2, F& f, mpl::false_)
{
typename result_of::attribute_value<First1, First2, Last2, Pred>::type
attribute = spirit::detail::attribute_value<Pred, First1, Last2>(first2);
return f(*first1, attribute) ||
detail::any_if<Pred>(
fusion::next(first1)
, attribute_next<Pred, First1, Last2>(first2)
, last1, last2
, f
, fusion::result_of::equal_to<
typename fusion::result_of::next<First1>::type, Last1>());
}
}
template <typename Pred, typename Sequence1, typename Sequence2, typename F>
inline bool
any_if(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
{
return detail::any_if<Pred>(
fusion::begin(seq1), fusion::begin(seq2)
, fusion::end(seq1), fusion::end(seq2)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence1>::type
, typename fusion::result_of::end<Sequence1>::type>());
}
template <typename Pred, typename Sequence, typename F>
inline bool
any_if(Sequence const& seq, unused_type const, F f, Pred)
{
return fusion::any(seq, f);
}
}}
#endif
@@ -0,0 +1,91 @@
/*=============================================================================
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_ANY_IF_NS_NOVEMBER_04_2008_0906PM)
#define BOOST_SPIRIT_ANY_IF_NS_NOVEMBER_04_2008_0906PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/algorithm/any_if.hpp>
#include <boost/spirit/home/support/algorithm/any_ns.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// This is a special version for a binary fusion::any. The predicate
// is used to decide whether to advance the second iterator or not.
// This is needed for sequences containing components with unused
// attributes. The second iterator is advanced only if the attribute
// of the corresponding component iterator is not unused.
//
// This is a non-short circuiting (ns) version of the any_if algorithm.
// see any_if.hpp (uses | instead of ||).
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <
typename Pred, typename First1, typename Last1, typename First2
, typename Last2, typename F
>
inline bool
any_if_ns(First1 const&, First2 const&, Last1 const&, Last2 const&
, F const&, mpl::true_)
{
return false;
}
template <
typename Pred, typename First1, typename Last1, typename First2
, typename Last2, typename F
>
inline bool
any_if_ns(First1 const& first1, First2 const& first2
, Last1 const& last1, Last2 const& last2, F& f, mpl::false_)
{
return (0 != (f(*first1, spirit::detail::attribute_value<Pred, First1, Last2>(first2)) |
detail::any_if_ns<Pred>(
fusion::next(first1)
, attribute_next<Pred, First1, Last2>(first2)
, last1, last2
, f
, fusion::result_of::equal_to<
typename fusion::result_of::next<First1>::type, Last1>())));
}
}
template <typename Pred, typename Sequence1, typename Sequence2, typename F>
inline bool
any_if_ns(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
{
return detail::any_if_ns<Pred>(
fusion::begin(seq1), fusion::begin(seq2)
, fusion::end(seq1), fusion::end(seq2)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence1>::type
, typename fusion::result_of::end<Sequence1>::type>());
}
template <typename Pred, typename Sequence, typename F>
inline bool
any_if_ns(Sequence const& seq, unused_type const, F f, Pred)
{
return detail::any_ns(
fusion::begin(seq)
, fusion::end(seq)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence>::type
, typename fusion::result_of::end<Sequence>::type>());
}
}}
#endif
@@ -0,0 +1,102 @@
/*=============================================================================
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_ANY_NS_MARCH_13_2007_0827AM)
#define BOOST_SPIRIT_ANY_NS_MARCH_13_2007_0827AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/fusion/include/equal_to.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/deref.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit
{
// A non-short circuiting (ns) version of the any algorithm (uses
// | instead of ||.
namespace detail
{
template <typename First1, typename Last, typename First2, typename F>
inline bool
any_ns(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
{
return false;
}
template <typename First1, typename Last, typename First2, typename F>
inline bool
any_ns(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
{
return (0 != (f(*first1, *first2) |
detail::any_ns(
fusion::next(first1)
, fusion::next(first2)
, last
, f
, fusion::result_of::equal_to<
typename fusion::result_of::next<First1>::type, Last>())));
}
template <typename First, typename Last, typename F>
inline bool
any_ns(First const&, Last const&, F const&, mpl::true_)
{
return false;
}
template <typename First, typename Last, typename F>
inline bool
any_ns(First const& first, Last const& last, F& f, mpl::false_)
{
return (0 != (f(*first) |
detail::any_ns(
fusion::next(first)
, last
, f
, fusion::result_of::equal_to<
typename fusion::result_of::next<First>::type, Last>())));
}
}
template <typename Sequence1, typename Sequence2, typename F>
inline bool
any_ns(Sequence1 const& seq1, Sequence2& seq2, F f)
{
return detail::any_ns(
fusion::begin(seq1)
, fusion::begin(seq2)
, fusion::end(seq1)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence1>::type
, typename fusion::result_of::end<Sequence1>::type>());
}
template <typename Sequence, typename F>
inline bool
any_ns(Sequence const& seq, unused_type, F f)
{
return detail::any_ns(
fusion::begin(seq)
, fusion::end(seq)
, f
, fusion::result_of::equal_to<
typename fusion::result_of::begin<Sequence>::type
, typename fusion::result_of::end<Sequence>::type>());
}
}}
#endif
@@ -0,0 +1,217 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Thomas Heller
Distributed under the 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_ARGUMENT_FEBRUARY_17_2007_0339PM)
#define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/limits.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define SPIRIT_DECLARE_ARG(z, n, data) \
typedef phoenix::actor<argument<n> > \
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
phoenix::actor<argument<n> > const \
BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \
/***/
#define SPIRIT_USING_ARGUMENT(z, n, data) \
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
using spirit::BOOST_PP_CAT(_, n); \
/***/
#else
#define SPIRIT_DECLARE_ARG(z, n, data) \
typedef phoenix::actor<argument<n> > \
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
/***/
#define SPIRIT_USING_ARGUMENT(z, n, data) \
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
/***/
#endif
namespace boost { namespace spirit
{
template <int N>
struct argument;
template <typename Dummy>
struct attribute_context;
}}
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
template <int N>
, boost::spirit::argument<N>
, mpl::false_ // is not nullary
, v2_eval(
proto::make<
boost::spirit::argument<N>()
>
, proto::call<
functional::env(proto::_state)
>
)
)
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
template <typename Dummy>
, boost::spirit::attribute_context<Dummy>
, mpl::false_ // is not nullary
, v2_eval(
proto::make<
boost::spirit::attribute_context<Dummy>()
>
, proto::call<
functional::env(proto::_state)
>
)
)
namespace boost { namespace spirit
{
namespace result_of
{
template <typename Sequence, int N>
struct get_arg
{
typedef typename
fusion::result_of::size<Sequence>::type
sequence_size;
// report invalid argument not found (N is out of bounds)
BOOST_SPIRIT_ASSERT_MSG(
(N < sequence_size::value),
index_is_out_of_bounds, ());
typedef typename
fusion::result_of::at_c<Sequence, N>::type
type;
static type call(Sequence& seq)
{
return fusion::at_c<N>(seq);
}
};
template <typename Sequence, int N>
struct get_arg<Sequence&, N> : get_arg<Sequence, N>
{
};
}
template <int N, typename T>
typename result_of::get_arg<T, N>::type
get_arg(T& val)
{
return result_of::get_arg<T, N>::call(val);
}
template <typename>
struct attribute_context
{
typedef mpl::true_ no_nullary;
template <typename Env>
struct result
{
// FIXME: is this remove_const really necessary?
typedef typename
remove_const<
typename mpl::at_c<typename Env::args_type, 0>::type
>::type
type;
};
template <typename Env>
typename result<Env>::type
eval(Env const& env) const
{
return fusion::at_c<0>(env.args());
}
};
template <int N>
struct argument
{
typedef mpl::true_ no_nullary;
template <typename Env>
struct result
{
typedef typename
mpl::at_c<typename Env::args_type, 0>::type
arg_type;
typedef typename result_of::get_arg<arg_type, N>::type type;
};
template <typename Env>
typename result<Env>::type
eval(Env const& env) const
{
return get_arg<N>(fusion::at_c<0>(env.args()));
}
};
// _0 refers to the whole attribute as generated by the lhs parser
typedef phoenix::actor<attribute_context<void> > _0_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
_0_type const _0 = _0_type();
#endif
// _1, _2, ... refer to the attributes of the single components the lhs
// parser is composed of
typedef phoenix::actor<argument<0> > _1_type;
typedef phoenix::actor<argument<1> > _2_type;
typedef phoenix::actor<argument<2> > _3_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
_1_type const _1 = _1_type();
_2_type const _2 = _2_type();
_3_type const _3 = _3_type();
#endif
// '_pass' may be used to make a match fail in retrospective
typedef phoenix::arg_names::_3_type _pass_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
_pass_type const _pass = _pass_type();
#endif
// Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
BOOST_PP_REPEAT_FROM_TO(
3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _)
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
// You can bring these in with the using directive
// without worrying about bringing in too much.
namespace labels
{
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
}
#endif
}}
#undef SPIRIT_DECLARE_ARG
#endif
@@ -0,0 +1,106 @@
/*=============================================================================
Copyright (c) 2011 Thomas Heller
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Thomas Heller
Distributed under the 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_ARGUMENT_MARCH_22_2011_0939PM)
#define BOOST_SPIRIT_ARGUMENT_MARCH_22_2011_0939PM
#include <boost/spirit/include/phoenix_core.hpp>
namespace boost { namespace spirit
{
template <int N>
struct argument;
template <typename Dummy>
struct attribute_context;
namespace expression
{
template <int N>
struct argument
: phoenix::expression::terminal<spirit::argument<N> >
{
typedef typename phoenix::expression::terminal<
spirit::argument<N>
>::type type;
static type make()
{
type const e = {{{}}};
return e;
}
};
template <typename Dummy>
struct attribute_context
: phoenix::expression::terminal<spirit::attribute_context<Dummy> >
{
typedef typename phoenix::expression::terminal<
spirit::attribute_context<Dummy>
>::type type;
static type make()
{
type const e = {{{}}};
return e;
}
};
}
}}
namespace boost { namespace phoenix
{
namespace result_of
{
template <typename Dummy>
struct is_nullary<custom_terminal<spirit::attribute_context<Dummy> > >
: mpl::false_
{};
template <int N>
struct is_nullary<custom_terminal<spirit::argument<N> > >
: mpl::false_
{};
}
template <typename Dummy>
struct is_custom_terminal<spirit::attribute_context<Dummy> >
: mpl::true_
{};
template <int N>
struct is_custom_terminal<spirit::argument<N> >
: mpl::true_
{};
template <typename Dummy>
struct custom_terminal<spirit::attribute_context<Dummy> >
: proto::call<
v2_eval(
proto::make<spirit::attribute_context<Dummy>()>
, proto::call<
functional::env(proto::_state)
>
)
>
{};
template <int N>
struct custom_terminal<spirit::argument<N> >
: proto::call<
v2_eval(
proto::make<spirit::argument<N>()>
, proto::call<
functional::env(proto::_state)
>
)
>
{};
}}
#endif
@@ -0,0 +1,54 @@
// Copyright (c) 2001-2013 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_ASSERT_MSG_JUN_23_2009_0836AM)
#define BOOST_SPIRIT_ASSERT_MSG_JUN_23_2009_0836AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
// Work around the MPL problem in BOOST_MPL_ASSERT_MSG generating
// multiple definition linker errors for certain compilers (VC++ 8).
// BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG can also be defined by user.
#if !defined(BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG)
# if defined(BOOST_MSVC) && BOOST_MSVC < 1500
# define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1
# endif
#endif
#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG != 0
#include <boost/static_assert.hpp>
#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types) \
BOOST_STATIC_ASSERT_MSG(Cond, # Msg)
#else
#include <boost/mpl/assert.hpp>
#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types) \
BOOST_MPL_ASSERT_MSG(Cond, Msg, Types)
#endif
#define BOOST_SPIRIT_ASSERT_MATCH(Domain, Expr) \
BOOST_SPIRIT_ASSERT_MSG(( \
boost::spirit::traits::matches< Domain, Expr >::value \
), error_invalid_expression, (Expr))
// GCC 4.7 will overeagerly instantiate static_asserts in template functions,
// if the assert condition does not depend on template parameters
// (see https://svn.boost.org/trac/boost/ticket/8381).
// There are places where we want to use constant false as the condition in
// template functions to indicate that these function overloads should never
// be called. This allows to generate better error messages. To solve this
// problem we make the condition dependent on the template argument and use
// the following macro in such places.
#include <boost/type_traits/is_same.hpp>
#define BOOST_SPIRIT_ASSERT_FAIL(TemplateParam, Msg, Types) \
BOOST_SPIRIT_ASSERT_MSG((!boost::is_same< \
TemplateParam, TemplateParam >::value), Msg, Types)
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,297 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
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_ATTRIBUTES_FWD_OCT_01_2009_0715AM)
#define BOOST_SPIRIT_ATTRIBUTES_FWD_OCT_01_2009_0715AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#if (defined(__GNUC__) && (__GNUC__ < 4)) || \
(defined(__APPLE__) && defined(__INTEL_COMPILER))
#include <boost/utility/enable_if.hpp>
#endif
#include <boost/spirit/home/support/unused.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace result_of
{
// forward declaration only
template <typename Exposed, typename Attribute>
struct extract_from;
template <typename T, typename Attribute>
struct attribute_as;
template <typename Exposed, typename Transformed, typename Domain>
struct pre_transform;
template <typename T>
struct optional_value;
template <typename Container>
struct begin;
template <typename Container>
struct end;
template <typename Iterator>
struct deref;
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Find out if T can be a strong substitute for Expected attribute
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Expected, typename Enable = void>
struct is_substitute;
///////////////////////////////////////////////////////////////////////////
// Find out if T can be a weak substitute for Expected attribute
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Expected, typename Enable = void>
struct is_weak_substitute;
///////////////////////////////////////////////////////////////////////////
// Determine if T is a proxy
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct is_proxy;
///////////////////////////////////////////////////////////////////////////
// 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;
///////////////////////////////////////////////////////////////////////////
// Retrieve the size of a fusion sequence (compile time)
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct sequence_size;
///////////////////////////////////////////////////////////////////////////
// Retrieve the size of an attribute (runtime)
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Enable = void>
struct attribute_size;
template <typename Attribute>
typename attribute_size<Attribute>::type
size(Attribute const& attr);
///////////////////////////////////////////////////////////////////////////
// Determines how we pass attributes to semantic actions. This
// may be specialized. By default, all attributes are wrapped in
// a fusion sequence, because the attribute has to be treated as being
// a single value in any case (even if it actually already is a fusion
// sequence in its own).
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Attribute, typename Enable = void>
struct pass_attribute;
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct optional_attribute;
///////////////////////////////////////////////////////////////////////////
// Sometimes the user needs to transform the attribute types for certain
// attributes. This template can be used as a customization point, where
// the user is able specify specific transformation rules for any attribute
// type.
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed, typename Domain
, typename Enable = void>
struct transform_attribute;
///////////////////////////////////////////////////////////////////////////
// Qi only
template <typename Attribute, typename Iterator, typename Enable = void>
struct assign_to_attribute_from_iterators;
template <typename Iterator, typename Attribute>
void assign_to(Iterator const& first, Iterator const& last, Attribute& attr);
template <typename Iterator>
void assign_to(Iterator const&, Iterator const&, unused_type);
template <typename Attribute, typename T, typename Enable = void>
struct assign_to_attribute_from_value;
template <typename Attribute, typename T, typename Enable = void>
struct assign_to_container_from_value;
template <typename T, typename Attribute>
void assign_to(T const& val, Attribute& attr);
template <typename T>
void assign_to(T const&, unused_type);
///////////////////////////////////////////////////////////////////////////
// Karma only
template <typename Attribute, typename Exposed, typename Enable = void>
struct extract_from_attribute;
template <typename Attribute, typename Exposed, typename Enable = void>
struct extract_from_container;
template <typename Exposed, typename Attribute, typename Context>
typename spirit::result_of::extract_from<Exposed, Attribute>::type
extract_from(Attribute const& attr, Context& ctx
#if (defined(__GNUC__) && (__GNUC__ < 4)) || \
(defined(__APPLE__) && defined(__INTEL_COMPILER))
, typename enable_if<traits::not_is_unused<Attribute> >::type* = NULL
#endif
);
///////////////////////////////////////////////////////////////////////////
// Karma only
template <typename T, typename Attribute, typename Enable = void>
struct attribute_as;
template <typename T, typename Attribute>
typename spirit::result_of::attribute_as<T, Attribute>::type
as(Attribute const& attr);
template <typename T, typename Attribute>
bool valid_as(Attribute const& attr);
///////////////////////////////////////////////////////////////////////////
// return the type currently stored in the given variant
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct variant_which;
template <typename T>
int which(T const& v);
///////////////////////////////////////////////////////////////////////////
// Determine, whether T is a variant like type
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Domain = unused_type, typename Enable = void>
struct not_is_variant;
///////////////////////////////////////////////////////////////////////////
// Determine, whether T is a variant like type
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Domain = unused_type, typename Enable = void>
struct not_is_optional;
///////////////////////////////////////////////////////////////////////////
// Clear data efficiently
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct clear_value;
///////////////////////////////////////////////////////////////////////
// Determine the value type of the given container type
///////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct container_value;
template <typename Container, typename Enable = void>
struct container_iterator;
template <typename T, typename Enable = void>
struct is_container;
template <typename T, typename Enable = void>
struct is_iterator_range;
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute, typename Context = unused_type
, typename Iterator = unused_type, typename Enable = void>
struct handles_container;
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename Domain, typename Enable = void>
struct pass_through_container;
///////////////////////////////////////////////////////////////////////////
// Qi only
template <typename Container, typename T, typename Enable = void>
struct push_back_container;
template <typename Container, typename Enable = void>
struct is_empty_container;
template <typename Container, typename Enable = void>
struct make_container_attribute;
///////////////////////////////////////////////////////////////////////
// Determine the iterator type of the given container type
// Karma only
///////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct begin_container;
template <typename Container, typename Enable = void>
struct end_container;
template <typename Iterator, typename Enable = void>
struct deref_iterator;
template <typename Iterator, typename Enable = void>
struct next_iterator;
template <typename Iterator, typename Enable = void>
struct compare_iterators;
///////////////////////////////////////////////////////////////////////////
// Print the given attribute of type T to the stream given as Out
///////////////////////////////////////////////////////////////////////////
template <typename Out, typename T, typename Enable = void>
struct print_attribute_debug;
template <typename Out, typename T>
void print_attribute(Out&, T const&);
template <typename Out>
void print_attribute(Out&, unused_type);
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename Enable = void>
struct token_printer_debug;
template<typename Out, typename T>
void print_token(Out&, T const&);
///////////////////////////////////////////////////////////////////////////
// Access attributes from a karma symbol table
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute, typename Enable = void>
struct symbols_lookup;
template <typename Attribute, typename T, typename Enable = void>
struct symbols_value;
///////////////////////////////////////////////////////////////////////////
// transform attribute types exposed from compound operator components
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Domain>
struct alternative_attribute_transform;
template <typename Attribute, typename Domain>
struct sequence_attribute_transform;
template <typename Attribute, typename Domain>
struct permutation_attribute_transform;
template <typename Attribute, typename Domain>
struct sequential_or_attribute_transform;
}}}
#endif
@@ -0,0 +1,35 @@
/*=============================================================================
Copyright (c) 2001-2012 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_AUTO_FEBRUARY_7_2012_0159PM)
#define BOOST_SPIRIT_AUTO_FEBRUARY_7_2012_0159PM
#include <boost/config.hpp>
#include <boost/typeof/typeof.hpp>
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
// Support for c++11 auto. See:
// http://boost-spirit.com/home/articles/qi-example/zero-to-60-mph-in-2-seconds/
// for more info
#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
typedef boost::proto::result_of:: \
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
BOOST_SPIRIT_ASSERT_MATCH( \
boost::spirit::domain_::domain, name##_expr_type); \
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
/****/
#endif
#endif
@@ -0,0 +1,212 @@
// 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_SUPPORT_META_CREATE_NOV_21_2009_0327PM)
#define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/version.hpp>
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
#include <boost/proto/proto.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/include/fold.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
// needed for workaround below
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
#include <boost/type_traits/is_same.hpp>
#endif
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This is the main dispatch point for meta_create to the correct domain
template <typename Domain, typename T, typename Enable = void>
struct meta_create;
///////////////////////////////////////////////////////////////////////////
// This allows to query whether a valid mapping exists for the given data
// type to a component in the given domain
template <typename Domain, typename T, typename Enable = void>
struct meta_create_exists : mpl::false_ {};
}}}
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct add_const_ref
: add_reference<typename add_const<T>::type> {};
template <typename T>
struct remove_const_ref
: remove_const<typename remove_reference<T>::type> {};
// starting with Boost V1.42 fusion::fold has been changed to be compatible
// with mpl::fold (the sequence of template parameters for the meta-function
// object has been changed)
#if BOOST_VERSION < 104200
///////////////////////////////////////////////////////////////////////
template <typename OpTag, typename Domain>
struct nary_proto_expr_function
{
template <typename T>
struct result;
// this is a workaround for older versions of g++ (< V4.3) which apparently have
// problems with the following template specialization
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
template <typename F, typename T1, typename T2>
struct result<F(T1, T2)>
{
BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
#else
template <typename T1, typename T2>
struct result<nary_proto_expr_function(T1, T2)>
{
#endif
typedef typename remove_const_ref<T2>::type left_type;
typedef typename
spirit::traits::meta_create<Domain, T1>::type
right_type;
typedef typename mpl::eval_if<
traits::not_is_unused<left_type>
, proto::result_of::make_expr<OpTag, left_type, right_type>
, mpl::identity<right_type>
>::type type;
};
template <typename T>
typename result<nary_proto_expr_function(T, unused_type const&)>::type
operator()(T, unused_type const&) const
{
typedef spirit::traits::meta_create<Domain, T> right_type;
return right_type::call();
}
template <typename T1, typename T2>
typename result<nary_proto_expr_function(T1, T2)>::type
operator()(T1, T2 const& t2) const
{
// we variants to the alternative operator
typedef spirit::traits::meta_create<Domain, T1> right_type;
return proto::make_expr<OpTag>(t2, right_type::call());
}
};
#else
///////////////////////////////////////////////////////////////////////
template <typename OpTag, typename Domain>
struct nary_proto_expr_function
{
template <typename T>
struct result;
// this is a workaround for older versions of g++ (< V4.3) which apparently have
// problems with the following template specialization
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
template <typename F, typename T1, typename T2>
struct result<F(T1, T2)>
{
BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
#else
template <typename T1, typename T2>
struct result<nary_proto_expr_function(T1, T2)>
{
#endif
typedef typename remove_const_ref<T1>::type left_type;
typedef typename
spirit::traits::meta_create<Domain, T2>::type
right_type;
typedef typename mpl::eval_if<
traits::not_is_unused<left_type>
, proto::result_of::make_expr<OpTag, left_type, right_type>
, mpl::identity<right_type>
>::type type;
};
template <typename T>
typename result<nary_proto_expr_function(unused_type const&, T)>::type
operator()(unused_type const&, T) const
{
typedef spirit::traits::meta_create<Domain, T> right_type;
return right_type::call();
}
template <typename T1, typename T2>
typename result<nary_proto_expr_function(T1, T2)>::type
operator()(T1 const& t1, T2) const
{
// we variants to the alternative operator
typedef spirit::traits::meta_create<Domain, T2> right_type;
return proto::make_expr<OpTag>(t1, right_type::call());
}
};
#endif
}
///////////////////////////////////////////////////////////////////////
template <typename T, typename OpTag, typename Domain>
struct make_unary_proto_expr
{
typedef spirit::traits::meta_create<Domain, T> subject_type;
typedef typename proto::result_of::make_expr<
OpTag, typename subject_type::type
>::type type;
static type call()
{
return proto::make_expr<OpTag>(subject_type::call());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Sequence, typename OpTag, typename Domain>
struct make_nary_proto_expr
{
typedef detail::nary_proto_expr_function<OpTag, Domain>
make_proto_expr;
typedef typename fusion::result_of::fold<
Sequence, unused_type, make_proto_expr
>::type type;
static type call()
{
return fusion::fold(Sequence(), unused, make_proto_expr());
}
};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
// Starting with newer versions of Proto, all Proto expressions are at
// the same time Fusion sequences. This is the correct behavior, but
// we need to distinguish between Fusion sequences and Proto
// expressions. This meta-function does exactly that.
template <typename T>
struct is_fusion_sequence_but_not_proto_expr
: mpl::and_<
fusion::traits::is_sequence<T>
, mpl::not_<proto::is_expr<T> > >
{};
}
}}
#endif
@@ -0,0 +1,47 @@
// 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_SUPPORT_ATTR_CAST_OCT_06_2009_00535PM)
#define SPIRIT_SUPPORT_ATTR_CAST_OCT_06_2009_00535PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// This one is the function that the user can call directly in order
// to create a customized attr_cast component
template <typename Expr>
typename enable_if<proto::is_expr<Expr>
, stateful_tag_type<Expr, tag::attr_cast> >::type
attr_cast(Expr const& expr)
{
return stateful_tag_type<Expr, tag::attr_cast>(expr);
}
template <typename Exposed, typename Expr>
typename enable_if<proto::is_expr<Expr>
, stateful_tag_type<Expr, tag::attr_cast, Exposed> >::type
attr_cast(Expr const& expr)
{
return stateful_tag_type<Expr, tag::attr_cast, Exposed>(expr);
}
template <typename Exposed, typename Transformed, typename Expr>
typename enable_if<proto::is_expr<Expr>
, stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed> >::type
attr_cast(Expr const& expr)
{
return stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed>(expr);
}
}}
#endif
@@ -0,0 +1,798 @@
/*=============================================================================
Copyright (c) 2001-2011 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_CHAR_CLASS_NOVEMBER_10_2006_0907AM)
#define BOOST_SPIRIT_CHAR_CLASS_NOVEMBER_10_2006_0907AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <string>
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
#include <boost/proto/proto.hpp>
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/make_signed.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' warning
#endif
namespace boost { namespace spirit { 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
}
}
}}}
namespace boost { namespace spirit { namespace tag
{
struct char_ { BOOST_SPIRIT_IS_TAG() };
struct string { BOOST_SPIRIT_IS_TAG() };
///////////////////////////////////////////////////////////////////////////
// classification tags
struct alnum { BOOST_SPIRIT_IS_TAG() };
struct alpha { BOOST_SPIRIT_IS_TAG() };
struct digit { BOOST_SPIRIT_IS_TAG() };
struct xdigit { BOOST_SPIRIT_IS_TAG() };
struct cntrl { BOOST_SPIRIT_IS_TAG() };
struct graph { BOOST_SPIRIT_IS_TAG() };
struct print { BOOST_SPIRIT_IS_TAG() };
struct punct { BOOST_SPIRIT_IS_TAG() };
struct space { BOOST_SPIRIT_IS_TAG() };
struct blank { BOOST_SPIRIT_IS_TAG() };
///////////////////////////////////////////////////////////////////////////
// classification/conversion tags
struct no_case { BOOST_SPIRIT_IS_TAG() };
struct lower { BOOST_SPIRIT_IS_TAG() };
struct upper { BOOST_SPIRIT_IS_TAG() };
struct lowernum { BOOST_SPIRIT_IS_TAG() };
struct uppernum { BOOST_SPIRIT_IS_TAG() };
struct ucs4 { BOOST_SPIRIT_IS_TAG() };
struct encoding { BOOST_SPIRIT_IS_TAG() };
#if defined(BOOST_SPIRIT_UNICODE)
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct letter { BOOST_SPIRIT_IS_TAG() };
struct mark { BOOST_SPIRIT_IS_TAG() };
struct number { BOOST_SPIRIT_IS_TAG() };
struct separator { BOOST_SPIRIT_IS_TAG() };
struct other { BOOST_SPIRIT_IS_TAG() };
struct punctuation { BOOST_SPIRIT_IS_TAG() };
struct symbol { BOOST_SPIRIT_IS_TAG() };
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
struct uppercase_letter { BOOST_SPIRIT_IS_TAG() };
struct lowercase_letter { BOOST_SPIRIT_IS_TAG() };
struct titlecase_letter { BOOST_SPIRIT_IS_TAG() };
struct modifier_letter { BOOST_SPIRIT_IS_TAG() };
struct other_letter { BOOST_SPIRIT_IS_TAG() };
struct nonspacing_mark { BOOST_SPIRIT_IS_TAG() };
struct enclosing_mark { BOOST_SPIRIT_IS_TAG() };
struct spacing_mark { BOOST_SPIRIT_IS_TAG() };
struct decimal_number { BOOST_SPIRIT_IS_TAG() };
struct letter_number { BOOST_SPIRIT_IS_TAG() };
struct other_number { BOOST_SPIRIT_IS_TAG() };
struct space_separator { BOOST_SPIRIT_IS_TAG() };
struct line_separator { BOOST_SPIRIT_IS_TAG() };
struct paragraph_separator { BOOST_SPIRIT_IS_TAG() };
struct control { BOOST_SPIRIT_IS_TAG() };
struct format { BOOST_SPIRIT_IS_TAG() };
struct private_use { BOOST_SPIRIT_IS_TAG() };
struct surrogate { BOOST_SPIRIT_IS_TAG() };
struct unassigned { BOOST_SPIRIT_IS_TAG() };
struct dash_punctuation { BOOST_SPIRIT_IS_TAG() };
struct open_punctuation { BOOST_SPIRIT_IS_TAG() };
struct close_punctuation { BOOST_SPIRIT_IS_TAG() };
struct connector_punctuation { BOOST_SPIRIT_IS_TAG() };
struct other_punctuation { BOOST_SPIRIT_IS_TAG() };
struct initial_punctuation { BOOST_SPIRIT_IS_TAG() };
struct final_punctuation { BOOST_SPIRIT_IS_TAG() };
struct math_symbol { BOOST_SPIRIT_IS_TAG() };
struct currency_symbol { BOOST_SPIRIT_IS_TAG() };
struct modifier_symbol { BOOST_SPIRIT_IS_TAG() };
struct other_symbol { BOOST_SPIRIT_IS_TAG() };
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
struct alphabetic { BOOST_SPIRIT_IS_TAG() };
struct uppercase { BOOST_SPIRIT_IS_TAG() };
struct lowercase { BOOST_SPIRIT_IS_TAG() };
struct white_space { BOOST_SPIRIT_IS_TAG() };
struct hex_digit { BOOST_SPIRIT_IS_TAG() };
struct noncharacter_code_point { BOOST_SPIRIT_IS_TAG() };
struct default_ignorable_code_point { BOOST_SPIRIT_IS_TAG() };
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
struct arabic { BOOST_SPIRIT_IS_TAG() };
struct imperial_aramaic { BOOST_SPIRIT_IS_TAG() };
struct armenian { BOOST_SPIRIT_IS_TAG() };
struct avestan { BOOST_SPIRIT_IS_TAG() };
struct balinese { BOOST_SPIRIT_IS_TAG() };
struct bamum { BOOST_SPIRIT_IS_TAG() };
struct bengali { BOOST_SPIRIT_IS_TAG() };
struct bopomofo { BOOST_SPIRIT_IS_TAG() };
struct braille { BOOST_SPIRIT_IS_TAG() };
struct buginese { BOOST_SPIRIT_IS_TAG() };
struct buhid { BOOST_SPIRIT_IS_TAG() };
struct canadian_aboriginal { BOOST_SPIRIT_IS_TAG() };
struct carian { BOOST_SPIRIT_IS_TAG() };
struct cham { BOOST_SPIRIT_IS_TAG() };
struct cherokee { BOOST_SPIRIT_IS_TAG() };
struct coptic { BOOST_SPIRIT_IS_TAG() };
struct cypriot { BOOST_SPIRIT_IS_TAG() };
struct cyrillic { BOOST_SPIRIT_IS_TAG() };
struct devanagari { BOOST_SPIRIT_IS_TAG() };
struct deseret { BOOST_SPIRIT_IS_TAG() };
struct egyptian_hieroglyphs { BOOST_SPIRIT_IS_TAG() };
struct ethiopic { BOOST_SPIRIT_IS_TAG() };
struct georgian { BOOST_SPIRIT_IS_TAG() };
struct glagolitic { BOOST_SPIRIT_IS_TAG() };
struct gothic { BOOST_SPIRIT_IS_TAG() };
struct greek { BOOST_SPIRIT_IS_TAG() };
struct gujarati { BOOST_SPIRIT_IS_TAG() };
struct gurmukhi { BOOST_SPIRIT_IS_TAG() };
struct hangul { BOOST_SPIRIT_IS_TAG() };
struct han { BOOST_SPIRIT_IS_TAG() };
struct hanunoo { BOOST_SPIRIT_IS_TAG() };
struct hebrew { BOOST_SPIRIT_IS_TAG() };
struct hiragana { BOOST_SPIRIT_IS_TAG() };
struct katakana_or_hiragana { BOOST_SPIRIT_IS_TAG() };
struct old_italic { BOOST_SPIRIT_IS_TAG() };
struct javanese { BOOST_SPIRIT_IS_TAG() };
struct kayah_li { BOOST_SPIRIT_IS_TAG() };
struct katakana { BOOST_SPIRIT_IS_TAG() };
struct kharoshthi { BOOST_SPIRIT_IS_TAG() };
struct khmer { BOOST_SPIRIT_IS_TAG() };
struct kannada { BOOST_SPIRIT_IS_TAG() };
struct kaithi { BOOST_SPIRIT_IS_TAG() };
struct tai_tham { BOOST_SPIRIT_IS_TAG() };
struct lao { BOOST_SPIRIT_IS_TAG() };
struct latin { BOOST_SPIRIT_IS_TAG() };
struct lepcha { BOOST_SPIRIT_IS_TAG() };
struct limbu { BOOST_SPIRIT_IS_TAG() };
struct linear_b { BOOST_SPIRIT_IS_TAG() };
struct lisu { BOOST_SPIRIT_IS_TAG() };
struct lycian { BOOST_SPIRIT_IS_TAG() };
struct lydian { BOOST_SPIRIT_IS_TAG() };
struct malayalam { BOOST_SPIRIT_IS_TAG() };
struct mongolian { BOOST_SPIRIT_IS_TAG() };
struct meetei_mayek { BOOST_SPIRIT_IS_TAG() };
struct myanmar { BOOST_SPIRIT_IS_TAG() };
struct nko { BOOST_SPIRIT_IS_TAG() };
struct ogham { BOOST_SPIRIT_IS_TAG() };
struct ol_chiki { BOOST_SPIRIT_IS_TAG() };
struct old_turkic { BOOST_SPIRIT_IS_TAG() };
struct oriya { BOOST_SPIRIT_IS_TAG() };
struct osmanya { BOOST_SPIRIT_IS_TAG() };
struct phags_pa { BOOST_SPIRIT_IS_TAG() };
struct inscriptional_pahlavi { BOOST_SPIRIT_IS_TAG() };
struct phoenician { BOOST_SPIRIT_IS_TAG() };
struct inscriptional_parthian { BOOST_SPIRIT_IS_TAG() };
struct rejang { BOOST_SPIRIT_IS_TAG() };
struct runic { BOOST_SPIRIT_IS_TAG() };
struct samaritan { BOOST_SPIRIT_IS_TAG() };
struct old_south_arabian { BOOST_SPIRIT_IS_TAG() };
struct saurashtra { BOOST_SPIRIT_IS_TAG() };
struct shavian { BOOST_SPIRIT_IS_TAG() };
struct sinhala { BOOST_SPIRIT_IS_TAG() };
struct sundanese { BOOST_SPIRIT_IS_TAG() };
struct syloti_nagri { BOOST_SPIRIT_IS_TAG() };
struct syriac { BOOST_SPIRIT_IS_TAG() };
struct tagbanwa { BOOST_SPIRIT_IS_TAG() };
struct tai_le { BOOST_SPIRIT_IS_TAG() };
struct new_tai_lue { BOOST_SPIRIT_IS_TAG() };
struct tamil { BOOST_SPIRIT_IS_TAG() };
struct tai_viet { BOOST_SPIRIT_IS_TAG() };
struct telugu { BOOST_SPIRIT_IS_TAG() };
struct tifinagh { BOOST_SPIRIT_IS_TAG() };
struct tagalog { BOOST_SPIRIT_IS_TAG() };
struct thaana { BOOST_SPIRIT_IS_TAG() };
struct thai { BOOST_SPIRIT_IS_TAG() };
struct tibetan { BOOST_SPIRIT_IS_TAG() };
struct ugaritic { BOOST_SPIRIT_IS_TAG() };
struct vai { BOOST_SPIRIT_IS_TAG() };
struct old_persian { BOOST_SPIRIT_IS_TAG() };
struct cuneiform { BOOST_SPIRIT_IS_TAG() };
struct yi { BOOST_SPIRIT_IS_TAG() };
struct inherited { BOOST_SPIRIT_IS_TAG() };
struct common { BOOST_SPIRIT_IS_TAG() };
struct unknown { BOOST_SPIRIT_IS_TAG() };
#endif
///////////////////////////////////////////////////////////////////////////
// This composite tag type encodes both the character
// set and the specific char tag (used for classification
// or conversion). char_code_base and char_encoding_base
// can be used to test for modifier membership (see modifier.hpp)
template <typename CharClass>
struct char_code_base {};
template <typename CharEncoding>
struct char_encoding_base {};
template <typename CharClass, typename CharEncoding>
struct char_code
: char_code_base<CharClass>, char_encoding_base<CharEncoding>
{
BOOST_SPIRIT_IS_TAG()
typedef CharEncoding char_encoding; // e.g. ascii
typedef CharClass char_class; // e.g. tag::alnum
};
}}}
namespace boost { namespace spirit { namespace char_class
{
///////////////////////////////////////////////////////////////////////////
// Test characters for classification
template <typename CharEncoding>
struct classify
{
typedef typename CharEncoding::char_type char_type;
#define BOOST_SPIRIT_CLASSIFY(name, isname) \
template <typename Char> \
static bool \
is(tag::name, Char ch) \
{ \
return CharEncoding::isname \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
BOOST_SPIRIT_CLASSIFY(char_, ischar)
BOOST_SPIRIT_CLASSIFY(alnum, isalnum)
BOOST_SPIRIT_CLASSIFY(alpha, isalpha)
BOOST_SPIRIT_CLASSIFY(digit, isdigit)
BOOST_SPIRIT_CLASSIFY(xdigit, isxdigit)
BOOST_SPIRIT_CLASSIFY(cntrl, iscntrl)
BOOST_SPIRIT_CLASSIFY(graph, isgraph)
BOOST_SPIRIT_CLASSIFY(lower, islower)
BOOST_SPIRIT_CLASSIFY(print, isprint)
BOOST_SPIRIT_CLASSIFY(punct, ispunct)
BOOST_SPIRIT_CLASSIFY(space, isspace)
BOOST_SPIRIT_CLASSIFY(blank, isblank)
BOOST_SPIRIT_CLASSIFY(upper, isupper)
#undef BOOST_SPIRIT_CLASSIFY
template <typename Char>
static bool
is(tag::lowernum, Char ch)
{
return CharEncoding::islower(detail::cast_char<char_type>(ch)) ||
CharEncoding::isdigit(detail::cast_char<char_type>(ch));
}
template <typename Char>
static bool
is(tag::uppernum, Char ch)
{
return CharEncoding::isupper(detail::cast_char<char_type>(ch)) ||
CharEncoding::isdigit(detail::cast_char<char_type>(ch));
}
#if defined(BOOST_SPIRIT_UNICODE)
#define BOOST_SPIRIT_UNICODE_CLASSIFY(name) \
template <typename Char> \
static bool \
is(tag::name, Char ch) \
{ \
return CharEncoding::is_##name(detail::cast_char<char_type>(ch)); \
} \
/***/
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY(letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(mark)
BOOST_SPIRIT_UNICODE_CLASSIFY(number)
BOOST_SPIRIT_UNICODE_CLASSIFY(separator)
BOOST_SPIRIT_UNICODE_CLASSIFY(other)
BOOST_SPIRIT_UNICODE_CLASSIFY(punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY(uppercase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(lowercase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(titlecase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(modifier_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(other_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY(nonspacing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY(enclosing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY(spacing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY(decimal_number)
BOOST_SPIRIT_UNICODE_CLASSIFY(letter_number)
BOOST_SPIRIT_UNICODE_CLASSIFY(other_number)
BOOST_SPIRIT_UNICODE_CLASSIFY(space_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY(line_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY(paragraph_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY(control)
BOOST_SPIRIT_UNICODE_CLASSIFY(format)
BOOST_SPIRIT_UNICODE_CLASSIFY(private_use)
BOOST_SPIRIT_UNICODE_CLASSIFY(surrogate)
BOOST_SPIRIT_UNICODE_CLASSIFY(unassigned)
BOOST_SPIRIT_UNICODE_CLASSIFY(dash_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(open_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(close_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(connector_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(other_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(initial_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(final_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY(math_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY(currency_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY(modifier_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY(alphabetic)
BOOST_SPIRIT_UNICODE_CLASSIFY(uppercase)
BOOST_SPIRIT_UNICODE_CLASSIFY(lowercase)
BOOST_SPIRIT_UNICODE_CLASSIFY(white_space)
BOOST_SPIRIT_UNICODE_CLASSIFY(hex_digit)
BOOST_SPIRIT_UNICODE_CLASSIFY(noncharacter_code_point)
BOOST_SPIRIT_UNICODE_CLASSIFY(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY(arabic)
BOOST_SPIRIT_UNICODE_CLASSIFY(imperial_aramaic)
BOOST_SPIRIT_UNICODE_CLASSIFY(armenian)
BOOST_SPIRIT_UNICODE_CLASSIFY(avestan)
BOOST_SPIRIT_UNICODE_CLASSIFY(balinese)
BOOST_SPIRIT_UNICODE_CLASSIFY(bamum)
BOOST_SPIRIT_UNICODE_CLASSIFY(bengali)
BOOST_SPIRIT_UNICODE_CLASSIFY(bopomofo)
BOOST_SPIRIT_UNICODE_CLASSIFY(braille)
BOOST_SPIRIT_UNICODE_CLASSIFY(buginese)
BOOST_SPIRIT_UNICODE_CLASSIFY(buhid)
BOOST_SPIRIT_UNICODE_CLASSIFY(canadian_aboriginal)
BOOST_SPIRIT_UNICODE_CLASSIFY(carian)
BOOST_SPIRIT_UNICODE_CLASSIFY(cham)
BOOST_SPIRIT_UNICODE_CLASSIFY(cherokee)
BOOST_SPIRIT_UNICODE_CLASSIFY(coptic)
BOOST_SPIRIT_UNICODE_CLASSIFY(cypriot)
BOOST_SPIRIT_UNICODE_CLASSIFY(cyrillic)
BOOST_SPIRIT_UNICODE_CLASSIFY(devanagari)
BOOST_SPIRIT_UNICODE_CLASSIFY(deseret)
BOOST_SPIRIT_UNICODE_CLASSIFY(egyptian_hieroglyphs)
BOOST_SPIRIT_UNICODE_CLASSIFY(ethiopic)
BOOST_SPIRIT_UNICODE_CLASSIFY(georgian)
BOOST_SPIRIT_UNICODE_CLASSIFY(glagolitic)
BOOST_SPIRIT_UNICODE_CLASSIFY(gothic)
BOOST_SPIRIT_UNICODE_CLASSIFY(greek)
BOOST_SPIRIT_UNICODE_CLASSIFY(gujarati)
BOOST_SPIRIT_UNICODE_CLASSIFY(gurmukhi)
BOOST_SPIRIT_UNICODE_CLASSIFY(hangul)
BOOST_SPIRIT_UNICODE_CLASSIFY(han)
BOOST_SPIRIT_UNICODE_CLASSIFY(hanunoo)
BOOST_SPIRIT_UNICODE_CLASSIFY(hebrew)
BOOST_SPIRIT_UNICODE_CLASSIFY(hiragana)
BOOST_SPIRIT_UNICODE_CLASSIFY(katakana_or_hiragana)
BOOST_SPIRIT_UNICODE_CLASSIFY(old_italic)
BOOST_SPIRIT_UNICODE_CLASSIFY(javanese)
BOOST_SPIRIT_UNICODE_CLASSIFY(kayah_li)
BOOST_SPIRIT_UNICODE_CLASSIFY(katakana)
BOOST_SPIRIT_UNICODE_CLASSIFY(kharoshthi)
BOOST_SPIRIT_UNICODE_CLASSIFY(khmer)
BOOST_SPIRIT_UNICODE_CLASSIFY(kannada)
BOOST_SPIRIT_UNICODE_CLASSIFY(kaithi)
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_tham)
BOOST_SPIRIT_UNICODE_CLASSIFY(lao)
BOOST_SPIRIT_UNICODE_CLASSIFY(latin)
BOOST_SPIRIT_UNICODE_CLASSIFY(lepcha)
BOOST_SPIRIT_UNICODE_CLASSIFY(limbu)
BOOST_SPIRIT_UNICODE_CLASSIFY(linear_b)
BOOST_SPIRIT_UNICODE_CLASSIFY(lisu)
BOOST_SPIRIT_UNICODE_CLASSIFY(lycian)
BOOST_SPIRIT_UNICODE_CLASSIFY(lydian)
BOOST_SPIRIT_UNICODE_CLASSIFY(malayalam)
BOOST_SPIRIT_UNICODE_CLASSIFY(mongolian)
BOOST_SPIRIT_UNICODE_CLASSIFY(meetei_mayek)
BOOST_SPIRIT_UNICODE_CLASSIFY(myanmar)
BOOST_SPIRIT_UNICODE_CLASSIFY(nko)
BOOST_SPIRIT_UNICODE_CLASSIFY(ogham)
BOOST_SPIRIT_UNICODE_CLASSIFY(ol_chiki)
BOOST_SPIRIT_UNICODE_CLASSIFY(old_turkic)
BOOST_SPIRIT_UNICODE_CLASSIFY(oriya)
BOOST_SPIRIT_UNICODE_CLASSIFY(osmanya)
BOOST_SPIRIT_UNICODE_CLASSIFY(phags_pa)
BOOST_SPIRIT_UNICODE_CLASSIFY(inscriptional_pahlavi)
BOOST_SPIRIT_UNICODE_CLASSIFY(phoenician)
BOOST_SPIRIT_UNICODE_CLASSIFY(inscriptional_parthian)
BOOST_SPIRIT_UNICODE_CLASSIFY(rejang)
BOOST_SPIRIT_UNICODE_CLASSIFY(runic)
BOOST_SPIRIT_UNICODE_CLASSIFY(samaritan)
BOOST_SPIRIT_UNICODE_CLASSIFY(old_south_arabian)
BOOST_SPIRIT_UNICODE_CLASSIFY(saurashtra)
BOOST_SPIRIT_UNICODE_CLASSIFY(shavian)
BOOST_SPIRIT_UNICODE_CLASSIFY(sinhala)
BOOST_SPIRIT_UNICODE_CLASSIFY(sundanese)
BOOST_SPIRIT_UNICODE_CLASSIFY(syloti_nagri)
BOOST_SPIRIT_UNICODE_CLASSIFY(syriac)
BOOST_SPIRIT_UNICODE_CLASSIFY(tagbanwa)
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_le)
BOOST_SPIRIT_UNICODE_CLASSIFY(new_tai_lue)
BOOST_SPIRIT_UNICODE_CLASSIFY(tamil)
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_viet)
BOOST_SPIRIT_UNICODE_CLASSIFY(telugu)
BOOST_SPIRIT_UNICODE_CLASSIFY(tifinagh)
BOOST_SPIRIT_UNICODE_CLASSIFY(tagalog)
BOOST_SPIRIT_UNICODE_CLASSIFY(thaana)
BOOST_SPIRIT_UNICODE_CLASSIFY(thai)
BOOST_SPIRIT_UNICODE_CLASSIFY(tibetan)
BOOST_SPIRIT_UNICODE_CLASSIFY(ugaritic)
BOOST_SPIRIT_UNICODE_CLASSIFY(vai)
BOOST_SPIRIT_UNICODE_CLASSIFY(old_persian)
BOOST_SPIRIT_UNICODE_CLASSIFY(cuneiform)
BOOST_SPIRIT_UNICODE_CLASSIFY(yi)
BOOST_SPIRIT_UNICODE_CLASSIFY(inherited)
BOOST_SPIRIT_UNICODE_CLASSIFY(common)
BOOST_SPIRIT_UNICODE_CLASSIFY(unknown)
#undef BOOST_SPIRIT_UNICODE_CLASSIFY
#endif
};
///////////////////////////////////////////////////////////////////////////
// Convert characters
template <typename CharEncoding>
struct convert
{
typedef typename CharEncoding::char_type char_type;
template <typename Char>
static Char
to(tag::lower, Char ch)
{
return static_cast<Char>(
CharEncoding::tolower(detail::cast_char<char_type>(ch)));
}
template <typename Char>
static Char
to(tag::upper, Char ch)
{
return static_cast<Char>(
CharEncoding::toupper(detail::cast_char<char_type>(ch)));
}
template <typename Char>
static Char
to(tag::ucs4, Char ch)
{
return static_cast<Char>(
CharEncoding::toucs4(detail::cast_char<char_type>(ch)));
}
template <typename Char>
static Char
to(unused_type, Char ch)
{
return ch;
}
};
///////////////////////////////////////////////////////////////////////////
// Info on character classification
template <typename CharEncoding>
struct what
{
#define BOOST_SPIRIT_CLASSIFY_WHAT(name, isname) \
static char const* is(tag::name) \
{ \
return isname; \
} \
/***/
BOOST_SPIRIT_CLASSIFY_WHAT(char_, "char")
BOOST_SPIRIT_CLASSIFY_WHAT(alnum, "alnum")
BOOST_SPIRIT_CLASSIFY_WHAT(alpha, "alpha")
BOOST_SPIRIT_CLASSIFY_WHAT(digit, "digit")
BOOST_SPIRIT_CLASSIFY_WHAT(xdigit, "xdigit")
BOOST_SPIRIT_CLASSIFY_WHAT(cntrl, "cntrl")
BOOST_SPIRIT_CLASSIFY_WHAT(graph, "graph")
BOOST_SPIRIT_CLASSIFY_WHAT(lower, "lower")
BOOST_SPIRIT_CLASSIFY_WHAT(lowernum, "lowernum")
BOOST_SPIRIT_CLASSIFY_WHAT(print, "print")
BOOST_SPIRIT_CLASSIFY_WHAT(punct, "punct")
BOOST_SPIRIT_CLASSIFY_WHAT(space, "space")
BOOST_SPIRIT_CLASSIFY_WHAT(blank, "blank")
BOOST_SPIRIT_CLASSIFY_WHAT(upper, "upper")
BOOST_SPIRIT_CLASSIFY_WHAT(uppernum, "uppernum")
BOOST_SPIRIT_CLASSIFY_WHAT(ucs4, "ucs4")
#undef BOOST_SPIRIT_CLASSIFY_WHAT
#if defined(BOOST_SPIRIT_UNICODE)
#define BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(name) \
static char const* is(tag::name) \
{ \
return BOOST_PP_STRINGIZE(name); \
} \
/***/
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(mark)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(number)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(separator)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(uppercase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lowercase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(titlecase_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(modifier_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_letter)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(nonspacing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(enclosing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(spacing_mark)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(decimal_number)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(letter_number)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_number)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(space_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(line_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(paragraph_separator)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(control)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(format)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(private_use)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(surrogate)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(unassigned)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(dash_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(open_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(close_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(connector_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(initial_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(final_punctuation)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(math_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(currency_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(modifier_symbol)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(alphabetic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(uppercase)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lowercase)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(white_space)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hex_digit)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(noncharacter_code_point)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(arabic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(imperial_aramaic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(armenian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(avestan)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(balinese)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bamum)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bengali)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bopomofo)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(braille)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(buginese)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(buhid)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(canadian_aboriginal)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(carian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cham)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cherokee)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(coptic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cypriot)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cyrillic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(devanagari)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(deseret)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(egyptian_hieroglyphs)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ethiopic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(georgian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(glagolitic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gothic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(greek)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gujarati)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gurmukhi)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hangul)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(han)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hanunoo)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hebrew)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hiragana)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(katakana_or_hiragana)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_italic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(javanese)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kayah_li)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(katakana)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kharoshthi)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(khmer)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kannada)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kaithi)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_tham)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lao)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(latin)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lepcha)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(limbu)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(linear_b)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lisu)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lycian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lydian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(malayalam)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(mongolian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(meetei_mayek)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(myanmar)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(nko)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ogham)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ol_chiki)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_turkic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(oriya)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(osmanya)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(phags_pa)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inscriptional_pahlavi)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(phoenician)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inscriptional_parthian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(rejang)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(runic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(samaritan)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_south_arabian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(saurashtra)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(shavian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(sinhala)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(sundanese)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(syloti_nagri)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(syriac)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tagbanwa)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_le)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(new_tai_lue)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tamil)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_viet)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(telugu)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tifinagh)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tagalog)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(thaana)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(thai)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tibetan)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ugaritic)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(vai)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_persian)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cuneiform)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(yi)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inherited)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(common)
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(unknown)
#undef BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT
#endif
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This meta-function evaluates to mpl::true_ if the function
// char_encoding::ischar() needs to be called to ensure correct matching.
// This happens mainly if the character type returned from the underlying
// iterator is larger than the character type of the used character
// encoding. Additionally, this meta-function provides a customization
// point for the lexer library to enforce this behavior while parsing
// a token stream.
template <typename Char, typename BaseChar>
struct mustcheck_ischar
: mpl::bool_<(sizeof(Char) > sizeof(BaseChar)) ? true : false> {};
///////////////////////////////////////////////////////////////////////////
// The following template calls char_encoding::ischar, if necessary
template <typename CharParam, typename CharEncoding
, bool MustCheck = mustcheck_ischar<
CharParam, typename CharEncoding::char_type>::value>
struct ischar
{
static bool call(CharParam)
{
return true;
}
};
template <typename CharParam, typename CharEncoding>
struct ischar<CharParam, CharEncoding, true>
{
static bool call(CharParam const& ch)
{
return CharEncoding::ischar(int(ch));
}
};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,318 @@
/*=============================================================================
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_ASCII_APRIL_26_2006_1106PM)
#define BOOST_SPIRIT_ASCII_APRIL_26_2006_1106PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <climits>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
///////////////////////////////////////////////////////////////////////////////
// constants used to classify the single characters
///////////////////////////////////////////////////////////////////////////////
#define BOOST_CC_DIGIT 0x0001
#define BOOST_CC_XDIGIT 0x0002
#define BOOST_CC_ALPHA 0x0004
#define BOOST_CC_CTRL 0x0008
#define BOOST_CC_LOWER 0x0010
#define BOOST_CC_UPPER 0x0020
#define BOOST_CC_SPACE 0x0040
#define BOOST_CC_PUNCT 0x0080
namespace boost { namespace spirit { namespace char_encoding
{
// The detection of isgraph(), isprint() and isblank() is done programmatically
// to keep the character type table small. Additionally, these functions are
// rather seldom used and the programmatic detection is very simple.
///////////////////////////////////////////////////////////////////////////
// ASCII character classification table
///////////////////////////////////////////////////////////////////////////
const unsigned char ascii_char_types[] =
{
/* NUL 0 0 */ BOOST_CC_CTRL,
/* SOH 1 1 */ BOOST_CC_CTRL,
/* STX 2 2 */ BOOST_CC_CTRL,
/* ETX 3 3 */ BOOST_CC_CTRL,
/* EOT 4 4 */ BOOST_CC_CTRL,
/* ENQ 5 5 */ BOOST_CC_CTRL,
/* ACK 6 6 */ BOOST_CC_CTRL,
/* BEL 7 7 */ BOOST_CC_CTRL,
/* BS 8 8 */ BOOST_CC_CTRL,
/* HT 9 9 */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* NL 10 a */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* VT 11 b */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* NP 12 c */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* CR 13 d */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* SO 14 e */ BOOST_CC_CTRL,
/* SI 15 f */ BOOST_CC_CTRL,
/* DLE 16 10 */ BOOST_CC_CTRL,
/* DC1 17 11 */ BOOST_CC_CTRL,
/* DC2 18 12 */ BOOST_CC_CTRL,
/* DC3 19 13 */ BOOST_CC_CTRL,
/* DC4 20 14 */ BOOST_CC_CTRL,
/* NAK 21 15 */ BOOST_CC_CTRL,
/* SYN 22 16 */ BOOST_CC_CTRL,
/* ETB 23 17 */ BOOST_CC_CTRL,
/* CAN 24 18 */ BOOST_CC_CTRL,
/* EM 25 19 */ BOOST_CC_CTRL,
/* SUB 26 1a */ BOOST_CC_CTRL,
/* ESC 27 1b */ BOOST_CC_CTRL,
/* FS 28 1c */ BOOST_CC_CTRL,
/* GS 29 1d */ BOOST_CC_CTRL,
/* RS 30 1e */ BOOST_CC_CTRL,
/* US 31 1f */ BOOST_CC_CTRL,
/* SP 32 20 */ BOOST_CC_SPACE,
/* ! 33 21 */ BOOST_CC_PUNCT,
/* " 34 22 */ BOOST_CC_PUNCT,
/* # 35 23 */ BOOST_CC_PUNCT,
/* $ 36 24 */ BOOST_CC_PUNCT,
/* % 37 25 */ BOOST_CC_PUNCT,
/* & 38 26 */ BOOST_CC_PUNCT,
/* ' 39 27 */ BOOST_CC_PUNCT,
/* ( 40 28 */ BOOST_CC_PUNCT,
/* ) 41 29 */ BOOST_CC_PUNCT,
/* * 42 2a */ BOOST_CC_PUNCT,
/* + 43 2b */ BOOST_CC_PUNCT,
/* , 44 2c */ BOOST_CC_PUNCT,
/* - 45 2d */ BOOST_CC_PUNCT,
/* . 46 2e */ BOOST_CC_PUNCT,
/* / 47 2f */ BOOST_CC_PUNCT,
/* 0 48 30 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 1 49 31 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 2 50 32 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 3 51 33 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 4 52 34 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 5 53 35 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 6 54 36 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 7 55 37 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 8 56 38 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 9 57 39 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* : 58 3a */ BOOST_CC_PUNCT,
/* ; 59 3b */ BOOST_CC_PUNCT,
/* < 60 3c */ BOOST_CC_PUNCT,
/* = 61 3d */ BOOST_CC_PUNCT,
/* > 62 3e */ BOOST_CC_PUNCT,
/* ? 63 3f */ BOOST_CC_PUNCT,
/* @ 64 40 */ BOOST_CC_PUNCT,
/* A 65 41 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* B 66 42 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* C 67 43 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* D 68 44 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* E 69 45 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* F 70 46 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* G 71 47 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* H 72 48 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* I 73 49 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* J 74 4a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* K 75 4b */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* L 76 4c */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* M 77 4d */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* N 78 4e */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* O 79 4f */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* P 80 50 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Q 81 51 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* R 82 52 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* S 83 53 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* T 84 54 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* U 85 55 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* V 86 56 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* W 87 57 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* X 88 58 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Y 89 59 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Z 90 5a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* [ 91 5b */ BOOST_CC_PUNCT,
/* \ 92 5c */ BOOST_CC_PUNCT,
/* ] 93 5d */ BOOST_CC_PUNCT,
/* ^ 94 5e */ BOOST_CC_PUNCT,
/* _ 95 5f */ BOOST_CC_PUNCT,
/* ` 96 60 */ BOOST_CC_PUNCT,
/* a 97 61 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* b 98 62 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* c 99 63 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* d 100 64 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* e 101 65 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* f 102 66 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* g 103 67 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* h 104 68 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* i 105 69 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* j 106 6a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* k 107 6b */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* l 108 6c */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* m 109 6d */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* n 110 6e */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* o 111 6f */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* p 112 70 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* q 113 71 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* r 114 72 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* s 115 73 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* t 116 74 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* u 117 75 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* v 118 76 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* w 119 77 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* x 120 78 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* y 121 79 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* z 122 7a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* { 123 7b */ BOOST_CC_PUNCT,
/* | 124 7c */ BOOST_CC_PUNCT,
/* } 125 7d */ BOOST_CC_PUNCT,
/* ~ 126 7e */ BOOST_CC_PUNCT,
/* DEL 127 7f */ BOOST_CC_CTRL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
///////////////////////////////////////////////////////////////////////////
// Test characters for specified conditions (using ASCII)
///////////////////////////////////////////////////////////////////////////
struct ascii
{
typedef char char_type;
static bool
isascii_(int ch)
{
return 0 == (ch & ~0x7f);
}
static bool
ischar(int ch)
{
return isascii_(ch);
}
static bool
isalnum(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_ALPHA)
|| (ascii_char_types[ch] & BOOST_CC_DIGIT);
}
static bool
isalpha(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_ALPHA) ? true : false;
}
static bool
isdigit(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_DIGIT) ? true : false;
}
static bool
isxdigit(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_XDIGIT) ? true : false;
}
static bool
iscntrl(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_CTRL) ? true : false;
}
static bool
isgraph(int ch)
{
return ('\x21' <= ch && ch <= '\x7e');
}
static bool
islower(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_LOWER) ? true : false;
}
static bool
isprint(int ch)
{
return ('\x20' <= ch && ch <= '\x7e');
}
static bool
ispunct(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_PUNCT) ? true : false;
}
static bool
isspace(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_SPACE) ? true : false;
}
static bool
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
{
return ('\x09' == ch || '\x20' == ch);
}
static bool
isupper(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (ascii_char_types[ch] & BOOST_CC_UPPER) ? true : false;
}
///////////////////////////////////////////////////////////////////////
// Simple character conversions
///////////////////////////////////////////////////////////////////////
static int
tolower(int ch)
{
return isupper(ch) ? (ch - 'A' + 'a') : ch;
}
static int
toupper(int ch)
{
return islower(ch) ? (ch - 'a' + 'A') : ch;
}
static ::boost::uint32_t
toucs4(int ch)
{
return ch;
}
};
}}}
///////////////////////////////////////////////////////////////////////////////
// undefine macros
///////////////////////////////////////////////////////////////////////////////
#undef BOOST_CC_DIGIT
#undef BOOST_CC_XDIGIT
#undef BOOST_CC_ALPHA
#undef BOOST_CC_CTRL
#undef BOOST_CC_LOWER
#undef BOOST_CC_UPPER
#undef BOOST_CC_PUNCT
#undef BOOST_CC_SPACE
#endif
@@ -0,0 +1,711 @@
/*=============================================================================
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_ISO8859_1_APRIL_26_2006_1106PM)
#define BOOST_SPIRIT_ISO8859_1_APRIL_26_2006_1106PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <climits>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
///////////////////////////////////////////////////////////////////////////////
// constants used to classify the single characters
///////////////////////////////////////////////////////////////////////////////
#define BOOST_CC_DIGIT 0x0001
#define BOOST_CC_XDIGIT 0x0002
#define BOOST_CC_ALPHA 0x0004
#define BOOST_CC_CTRL 0x0008
#define BOOST_CC_LOWER 0x0010
#define BOOST_CC_UPPER 0x0020
#define BOOST_CC_SPACE 0x0040
#define BOOST_CC_PUNCT 0x0080
namespace boost { namespace spirit { namespace char_encoding
{
// The detection of isgraph(), isprint() and isblank() is done programmatically
// to keep the character type table small. Additionally, these functions are
// rather seldom used and the programmatic detection is very simple.
///////////////////////////////////////////////////////////////////////////
// ISO 8859-1 character classification table
//
// the comments intentionally contain non-ascii characters
// boostinspect:noascii
///////////////////////////////////////////////////////////////////////////
const unsigned char iso8859_1_char_types[] =
{
/* NUL 0 0 */ BOOST_CC_CTRL,
/* SOH 1 1 */ BOOST_CC_CTRL,
/* STX 2 2 */ BOOST_CC_CTRL,
/* ETX 3 3 */ BOOST_CC_CTRL,
/* EOT 4 4 */ BOOST_CC_CTRL,
/* ENQ 5 5 */ BOOST_CC_CTRL,
/* ACK 6 6 */ BOOST_CC_CTRL,
/* BEL 7 7 */ BOOST_CC_CTRL,
/* BS 8 8 */ BOOST_CC_CTRL,
/* HT 9 9 */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* NL 10 a */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* VT 11 b */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* NP 12 c */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* CR 13 d */ BOOST_CC_CTRL|BOOST_CC_SPACE,
/* SO 14 e */ BOOST_CC_CTRL,
/* SI 15 f */ BOOST_CC_CTRL,
/* DLE 16 10 */ BOOST_CC_CTRL,
/* DC1 17 11 */ BOOST_CC_CTRL,
/* DC2 18 12 */ BOOST_CC_CTRL,
/* DC3 19 13 */ BOOST_CC_CTRL,
/* DC4 20 14 */ BOOST_CC_CTRL,
/* NAK 21 15 */ BOOST_CC_CTRL,
/* SYN 22 16 */ BOOST_CC_CTRL,
/* ETB 23 17 */ BOOST_CC_CTRL,
/* CAN 24 18 */ BOOST_CC_CTRL,
/* EM 25 19 */ BOOST_CC_CTRL,
/* SUB 26 1a */ BOOST_CC_CTRL,
/* ESC 27 1b */ BOOST_CC_CTRL,
/* FS 28 1c */ BOOST_CC_CTRL,
/* GS 29 1d */ BOOST_CC_CTRL,
/* RS 30 1e */ BOOST_CC_CTRL,
/* US 31 1f */ BOOST_CC_CTRL,
/* SP 32 20 */ BOOST_CC_SPACE,
/* ! 33 21 */ BOOST_CC_PUNCT,
/* " 34 22 */ BOOST_CC_PUNCT,
/* # 35 23 */ BOOST_CC_PUNCT,
/* $ 36 24 */ BOOST_CC_PUNCT,
/* % 37 25 */ BOOST_CC_PUNCT,
/* & 38 26 */ BOOST_CC_PUNCT,
/* ' 39 27 */ BOOST_CC_PUNCT,
/* ( 40 28 */ BOOST_CC_PUNCT,
/* ) 41 29 */ BOOST_CC_PUNCT,
/* * 42 2a */ BOOST_CC_PUNCT,
/* + 43 2b */ BOOST_CC_PUNCT,
/* , 44 2c */ BOOST_CC_PUNCT,
/* - 45 2d */ BOOST_CC_PUNCT,
/* . 46 2e */ BOOST_CC_PUNCT,
/* / 47 2f */ BOOST_CC_PUNCT,
/* 0 48 30 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 1 49 31 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 2 50 32 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 3 51 33 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 4 52 34 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 5 53 35 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 6 54 36 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 7 55 37 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 8 56 38 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* 9 57 39 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
/* : 58 3a */ BOOST_CC_PUNCT,
/* ; 59 3b */ BOOST_CC_PUNCT,
/* < 60 3c */ BOOST_CC_PUNCT,
/* = 61 3d */ BOOST_CC_PUNCT,
/* > 62 3e */ BOOST_CC_PUNCT,
/* ? 63 3f */ BOOST_CC_PUNCT,
/* @ 64 40 */ BOOST_CC_PUNCT,
/* A 65 41 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* B 66 42 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* C 67 43 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* D 68 44 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* E 69 45 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* F 70 46 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
/* G 71 47 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* H 72 48 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* I 73 49 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* J 74 4a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* K 75 4b */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* L 76 4c */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* M 77 4d */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* N 78 4e */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* O 79 4f */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* P 80 50 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Q 81 51 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* R 82 52 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* S 83 53 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* T 84 54 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* U 85 55 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* V 86 56 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* W 87 57 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* X 88 58 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Y 89 59 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Z 90 5a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* [ 91 5b */ BOOST_CC_PUNCT,
/* \ 92 5c */ BOOST_CC_PUNCT,
/* ] 93 5d */ BOOST_CC_PUNCT,
/* ^ 94 5e */ BOOST_CC_PUNCT,
/* _ 95 5f */ BOOST_CC_PUNCT,
/* ` 96 60 */ BOOST_CC_PUNCT,
/* a 97 61 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* b 98 62 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* c 99 63 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* d 100 64 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* e 101 65 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* f 102 66 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
/* g 103 67 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* h 104 68 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* i 105 69 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* j 106 6a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* k 107 6b */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* l 108 6c */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* m 109 6d */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* n 110 6e */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* o 111 6f */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* p 112 70 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* q 113 71 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* r 114 72 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* s 115 73 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* t 116 74 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* u 117 75 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* v 118 76 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* w 119 77 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* x 120 78 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* y 121 79 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* z 122 7a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* { 123 7b */ BOOST_CC_PUNCT,
/* | 124 7c */ BOOST_CC_PUNCT,
/* } 125 7d */ BOOST_CC_PUNCT,
/* ~ 126 7e */ BOOST_CC_PUNCT,
/* DEL 127 7f */ BOOST_CC_CTRL,
/* -- 128 80 */ BOOST_CC_CTRL,
/* -- 129 81 */ BOOST_CC_CTRL,
/* -- 130 82 */ BOOST_CC_CTRL,
/* -- 131 83 */ BOOST_CC_CTRL,
/* -- 132 84 */ BOOST_CC_CTRL,
/* -- 133 85 */ BOOST_CC_CTRL,
/* -- 134 86 */ BOOST_CC_CTRL,
/* -- 135 87 */ BOOST_CC_CTRL,
/* -- 136 88 */ BOOST_CC_CTRL,
/* -- 137 89 */ BOOST_CC_CTRL,
/* -- 138 8a */ BOOST_CC_CTRL,
/* -- 139 8b */ BOOST_CC_CTRL,
/* -- 140 8c */ BOOST_CC_CTRL,
/* -- 141 8d */ BOOST_CC_CTRL,
/* -- 142 8e */ BOOST_CC_CTRL,
/* -- 143 8f */ BOOST_CC_CTRL,
/* -- 144 90 */ BOOST_CC_CTRL,
/* -- 145 91 */ BOOST_CC_CTRL,
/* -- 146 92 */ BOOST_CC_CTRL,
/* -- 147 93 */ BOOST_CC_CTRL,
/* -- 148 94 */ BOOST_CC_CTRL,
/* -- 149 95 */ BOOST_CC_CTRL,
/* -- 150 96 */ BOOST_CC_CTRL,
/* -- 151 97 */ BOOST_CC_CTRL,
/* -- 152 98 */ BOOST_CC_CTRL,
/* -- 153 99 */ BOOST_CC_CTRL,
/* -- 154 9a */ BOOST_CC_CTRL,
/* -- 155 9b */ BOOST_CC_CTRL,
/* -- 156 9c */ BOOST_CC_CTRL,
/* -- 157 9d */ BOOST_CC_CTRL,
/* -- 158 9e */ BOOST_CC_CTRL,
/* -- 159 9f */ BOOST_CC_CTRL,
/* 160 a0 */ BOOST_CC_SPACE,
/* ¡ 161 a1 */ BOOST_CC_PUNCT,
/* ¢ 162 a2 */ BOOST_CC_PUNCT,
/* £ 163 a3 */ BOOST_CC_PUNCT,
/* ¤ 164 a4 */ BOOST_CC_PUNCT,
/* ¥ 165 a5 */ BOOST_CC_PUNCT,
/* ¦ 166 a6 */ BOOST_CC_PUNCT,
/* § 167 a7 */ BOOST_CC_PUNCT,
/* ¨ 168 a8 */ BOOST_CC_PUNCT,
/* © 169 a9 */ BOOST_CC_PUNCT,
/* ª 170 aa */ BOOST_CC_PUNCT,
/* « 171 ab */ BOOST_CC_PUNCT,
/* ¬ 172 ac */ BOOST_CC_PUNCT,
/* ­ 173 ad */ BOOST_CC_PUNCT,
/* ® 174 ae */ BOOST_CC_PUNCT,
/* ¯ 175 af */ BOOST_CC_PUNCT,
/* ° 176 b0 */ BOOST_CC_PUNCT,
/* ± 177 b1 */ BOOST_CC_PUNCT,
/* ² 178 b2 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
/* ³ 179 b3 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
/* ´ 180 b4 */ BOOST_CC_PUNCT,
/* µ 181 b5 */ BOOST_CC_PUNCT,
/* ¶ 182 b6 */ BOOST_CC_PUNCT,
/* · 183 b7 */ BOOST_CC_PUNCT,
/* ¸ 184 b8 */ BOOST_CC_PUNCT,
/* ¹ 185 b9 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
/* º 186 ba */ BOOST_CC_PUNCT,
/* » 187 bb */ BOOST_CC_PUNCT,
/* ¼ 188 bc */ BOOST_CC_PUNCT,
/* ½ 189 bd */ BOOST_CC_PUNCT,
/* ¾ 190 be */ BOOST_CC_PUNCT,
/* ¿ 191 bf */ BOOST_CC_PUNCT,
/* À 192 c0 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Á 193 c1 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Â 194 c2 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ã 195 c3 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ä 196 c4 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Å 197 c5 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Æ 198 c6 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ç 199 c7 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* È 200 c8 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* É 201 c9 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ê 202 ca */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ë 203 cb */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ì 204 cc */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Í 205 cd */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Î 206 ce */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ï 207 cf */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ð 208 d0 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ñ 209 d1 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ò 210 d2 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ó 211 d3 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ô 212 d4 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Õ 213 d5 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ö 214 d6 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* × 215 d7 */ BOOST_CC_PUNCT,
/* Ø 216 d8 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ù 217 d9 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ú 218 da */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Û 219 db */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ü 220 dc */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Ý 221 dd */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* Þ 222 de */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
/* ß 223 df */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* à 224 e0 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* á 225 e1 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* â 226 e2 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ã 227 e3 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ä 228 e4 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* å 229 e5 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* æ 230 e6 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ç 231 e7 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* è 232 e8 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* é 233 e9 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ê 234 ea */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ë 235 eb */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ì 236 ec */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* í 237 ed */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* î 238 ee */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ï 239 ef */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ð 240 f0 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ñ 241 f1 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ò 242 f2 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ó 243 f3 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ô 244 f4 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* õ 245 f5 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ö 246 f6 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ÷ 247 f7 */ BOOST_CC_PUNCT,
/* ø 248 f8 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ù 249 f9 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ú 250 fa */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* û 251 fb */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ü 252 fc */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ý 253 fd */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* þ 254 fe */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
/* ÿ 255 ff */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
};
///////////////////////////////////////////////////////////////////////////
// ISO 8859-1 character conversion table
///////////////////////////////////////////////////////////////////////////
const unsigned char iso8859_1_char_conversion[] =
{
/* NUL 0 0 */ '\0',
/* SOH 1 1 */ '\0',
/* STX 2 2 */ '\0',
/* ETX 3 3 */ '\0',
/* EOT 4 4 */ '\0',
/* ENQ 5 5 */ '\0',
/* ACK 6 6 */ '\0',
/* BEL 7 7 */ '\0',
/* BS 8 8 */ '\0',
/* HT 9 9 */ '\0',
/* NL 10 a */ '\0',
/* VT 11 b */ '\0',
/* NP 12 c */ '\0',
/* CR 13 d */ '\0',
/* SO 14 e */ '\0',
/* SI 15 f */ '\0',
/* DLE 16 10 */ '\0',
/* DC1 17 11 */ '\0',
/* DC2 18 12 */ '\0',
/* DC3 19 13 */ '\0',
/* DC4 20 14 */ '\0',
/* NAK 21 15 */ '\0',
/* SYN 22 16 */ '\0',
/* ETB 23 17 */ '\0',
/* CAN 24 18 */ '\0',
/* EM 25 19 */ '\0',
/* SUB 26 1a */ '\0',
/* ESC 27 1b */ '\0',
/* FS 28 1c */ '\0',
/* GS 29 1d */ '\0',
/* RS 30 1e */ '\0',
/* US 31 1f */ '\0',
/* SP 32 20 */ '\0',
/* ! 33 21 */ '\0',
/* " 34 22 */ '\0',
/* # 35 23 */ '\0',
/* $ 36 24 */ '\0',
/* % 37 25 */ '\0',
/* & 38 26 */ '\0',
/* ' 39 27 */ '\0',
/* ( 40 28 */ '\0',
/* ) 41 29 */ '\0',
/* * 42 2a */ '\0',
/* + 43 2b */ '\0',
/* , 44 2c */ '\0',
/* - 45 2d */ '\0',
/* . 46 2e */ '\0',
/* / 47 2f */ '\0',
/* 0 48 30 */ '\0',
/* 1 49 31 */ '\0',
/* 2 50 32 */ '\0',
/* 3 51 33 */ '\0',
/* 4 52 34 */ '\0',
/* 5 53 35 */ '\0',
/* 6 54 36 */ '\0',
/* 7 55 37 */ '\0',
/* 8 56 38 */ '\0',
/* 9 57 39 */ '\0',
/* : 58 3a */ '\0',
/* ; 59 3b */ '\0',
/* < 60 3c */ '\0',
/* = 61 3d */ '\0',
/* > 62 3e */ '\0',
/* ? 63 3f */ '\0',
/* @ 64 40 */ '\0',
/* A 65 41 */ 'a',
/* B 66 42 */ 'b',
/* C 67 43 */ 'c',
/* D 68 44 */ 'd',
/* E 69 45 */ 'e',
/* F 70 46 */ 'f',
/* G 71 47 */ 'g',
/* H 72 48 */ 'h',
/* I 73 49 */ 'i',
/* J 74 4a */ 'j',
/* K 75 4b */ 'k',
/* L 76 4c */ 'l',
/* M 77 4d */ 'm',
/* N 78 4e */ 'n',
/* O 79 4f */ 'o',
/* P 80 50 */ 'p',
/* Q 81 51 */ 'q',
/* R 82 52 */ 'r',
/* S 83 53 */ 's',
/* T 84 54 */ 't',
/* U 85 55 */ 'u',
/* V 86 56 */ 'v',
/* W 87 57 */ 'w',
/* X 88 58 */ 'x',
/* Y 89 59 */ 'y',
/* Z 90 5a */ 'z',
/* [ 91 5b */ '\0',
/* \ 92 5c */ '\0',
/* ] 93 5d */ '\0',
/* ^ 94 5e */ '\0',
/* _ 95 5f */ '\0',
/* ` 96 60 */ '\0',
/* a 97 61 */ 'A',
/* b 98 62 */ 'B',
/* c 99 63 */ 'C',
/* d 100 64 */ 'D',
/* e 101 65 */ 'E',
/* f 102 66 */ 'F',
/* g 103 67 */ 'G',
/* h 104 68 */ 'H',
/* i 105 69 */ 'I',
/* j 106 6a */ 'J',
/* k 107 6b */ 'K',
/* l 108 6c */ 'L',
/* m 109 6d */ 'M',
/* n 110 6e */ 'N',
/* o 111 6f */ 'O',
/* p 112 70 */ 'P',
/* q 113 71 */ 'Q',
/* r 114 72 */ 'R',
/* s 115 73 */ 'S',
/* t 116 74 */ 'T',
/* u 117 75 */ 'U',
/* v 118 76 */ 'V',
/* w 119 77 */ 'W',
/* x 120 78 */ 'X',
/* y 121 79 */ 'Y',
/* z 122 7a */ 'Z',
/* { 123 7b */ '\0',
/* | 124 7c */ '\0',
/* } 125 7d */ '\0',
/* ~ 126 7e */ '\0',
/* DEL 127 7f */ '\0',
/* -- 128 80 */ '\0',
/* -- 129 81 */ '\0',
/* -- 130 82 */ '\0',
/* -- 131 83 */ '\0',
/* -- 132 84 */ '\0',
/* -- 133 85 */ '\0',
/* -- 134 86 */ '\0',
/* -- 135 87 */ '\0',
/* -- 136 88 */ '\0',
/* -- 137 89 */ '\0',
/* -- 138 8a */ '\0',
/* -- 139 8b */ '\0',
/* -- 140 8c */ '\0',
/* -- 141 8d */ '\0',
/* -- 142 8e */ '\0',
/* -- 143 8f */ '\0',
/* -- 144 90 */ '\0',
/* -- 145 91 */ '\0',
/* -- 146 92 */ '\0',
/* -- 147 93 */ '\0',
/* -- 148 94 */ '\0',
/* -- 149 95 */ '\0',
/* -- 150 96 */ '\0',
/* -- 151 97 */ '\0',
/* -- 152 98 */ '\0',
/* -- 153 99 */ '\0',
/* -- 154 9a */ '\0',
/* -- 155 9b */ '\0',
/* -- 156 9c */ '\0',
/* -- 157 9d */ '\0',
/* -- 158 9e */ '\0',
/* -- 159 9f */ '\0',
/* 160 a0 */ '\0',
/* ¡ 161 a1 */ '\0',
/* ¢ 162 a2 */ '\0',
/* £ 163 a3 */ '\0',
/* ¤ 164 a4 */ '\0',
/* ¥ 165 a5 */ '\0',
/* ¦ 166 a6 */ '\0',
/* § 167 a7 */ '\0',
/* ¨ 168 a8 */ '\0',
/* © 169 a9 */ '\0',
/* ª 170 aa */ '\0',
/* « 171 ab */ '\0',
/* ¬ 172 ac */ '\0',
/* ­ 173 ad */ '\0',
/* ® 174 ae */ '\0',
/* ¯ 175 af */ '\0',
/* ° 176 b0 */ '\0',
/* ± 177 b1 */ '\0',
/* ² 178 b2 */ '\0',
/* ³ 179 b3 */ '\0',
/* ´ 180 b4 */ '\0',
/* µ 181 b5 */ '\0',
/* ¶ 182 b6 */ '\0',
/* · 183 b7 */ '\0',
/* ¸ 184 b8 */ '\0',
/* ¹ 185 b9 */ '\0',
/* º 186 ba */ '\0',
/* » 187 bb */ '\0',
/* ¼ 188 bc */ '\0',
/* ½ 189 bd */ '\0',
/* ¾ 190 be */ '\0',
/* ¿ 191 bf */ '\0',
/* à 192 c0 */ 0xe0,
/* á 193 c1 */ 0xe1,
/* â 194 c2 */ 0xe2,
/* ã 195 c3 */ 0xe3,
/* ä 196 c4 */ 0xe4,
/* å 197 c5 */ 0xe5,
/* æ 198 c6 */ 0xe6,
/* ç 199 c7 */ 0xe7,
/* è 200 c8 */ 0xe8,
/* é 201 c9 */ 0xe9,
/* ê 202 ca */ 0xea,
/* ë 203 cb */ 0xeb,
/* ì 204 cc */ 0xec,
/* í 205 cd */ 0xed,
/* î 206 ce */ 0xee,
/* ï 207 cf */ 0xef,
/* ð 208 d0 */ 0xf0,
/* ñ 209 d1 */ 0xf1,
/* ò 210 d2 */ 0xf2,
/* ó 211 d3 */ 0xf3,
/* ô 212 d4 */ 0xf4,
/* õ 213 d5 */ 0xf5,
/* ö 214 d6 */ 0xf6,
/* × 215 d7 */ '\0',
/* ø 216 d8 */ 0xf8,
/* ù 217 d9 */ 0xf9,
/* ú 218 da */ 0xfa,
/* û 219 db */ 0xfb,
/* ü 220 dc */ 0xfc,
/* ý 221 dd */ 0xfd,
/* þ 222 de */ 0xfe,
/* ß 223 df */ '\0',
/* À 224 e0 */ 0xc0,
/* Á 225 e1 */ 0xc1,
/* Â 226 e2 */ 0xc2,
/* Ã 227 e3 */ 0xc3,
/* Ä 228 e4 */ 0xc4,
/* Å 229 e5 */ 0xc5,
/* Æ 230 e6 */ 0xc6,
/* Ç 231 e7 */ 0xc7,
/* È 232 e8 */ 0xc8,
/* É 233 e9 */ 0xc9,
/* Ê 234 ea */ 0xca,
/* Ë 235 eb */ 0xcb,
/* Ì 236 ec */ 0xcc,
/* Í 237 ed */ 0xcd,
/* Î 238 ee */ 0xce,
/* Ï 239 ef */ 0xcf,
/* Ð 240 f0 */ 0xd0,
/* Ñ 241 f1 */ 0xd1,
/* Ò 242 f2 */ 0xd2,
/* Ó 243 f3 */ 0xd3,
/* Ô 244 f4 */ 0xd4,
/* Õ 245 f5 */ 0xd5,
/* Ö 246 f6 */ 0xd6,
/* ÷ 247 f7 */ '\0',
/* Ø 248 f8 */ 0xd8,
/* Ù 249 f9 */ 0xd9,
/* Ú 250 fa */ 0xda,
/* Û 251 fb */ 0xdb,
/* Ü 252 fc */ 0xdc,
/* Ý 253 fd */ 0xdd,
/* Þ 254 fe */ 0xde,
/* ÿ 255 ff */ '\0',
};
///////////////////////////////////////////////////////////////////////////
// Test characters for specified conditions (using iso8859-1)
///////////////////////////////////////////////////////////////////////////
struct iso8859_1
{
typedef unsigned char char_type;
static bool
isascii_(int ch)
{
return 0 == (ch & ~0x7f);
}
static bool
ischar(int ch)
{
// iso8859.1 uses all 8 bits
// we have to watch out for sign extensions
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) ? true : false;
}
static bool
isalnum(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA)
|| (iso8859_1_char_types[ch] & BOOST_CC_DIGIT);
}
static bool
isalpha(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA) ? true : false;
}
static bool
isdigit(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_DIGIT) ? true : false;
}
static bool
isxdigit(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_XDIGIT) ? true : false;
}
static bool
iscntrl(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_CTRL) ? true : false;
}
static bool
isgraph(int ch)
{
return ('\x21' <= ch && ch <= '\x7e') || ('\xa1' <= ch && ch <= '\xff');
}
static bool
islower(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_LOWER) ? true : false;
}
static bool
isprint(int ch)
{
return ('\x20' <= ch && ch <= '\x7e') || ('\xa0' <= ch && ch <= '\xff');
}
static bool
ispunct(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_PUNCT) ? true : false;
}
static bool
isspace(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_SPACE) ? true : false;
}
static bool
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
{
return ('\x09' == ch || '\x20' == ch || '\xa0' == ch);
}
static bool
isupper(int ch)
{
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
return (iso8859_1_char_types[ch] & BOOST_CC_UPPER) ? true : false;
}
///////////////////////////////////////////////////////////////////////////
// Simple character conversions
///////////////////////////////////////////////////////////////////////////
static int
tolower(int ch)
{
return isupper(ch) && '\0' != iso8859_1_char_conversion[ch] ?
iso8859_1_char_conversion[ch] : ch;
}
static int
toupper(int ch)
{
return islower(ch) && '\0' != iso8859_1_char_conversion[ch] ?
iso8859_1_char_conversion[ch] : ch;
}
static ::boost::uint32_t
toucs4(int ch)
{
// The first 256 characters in Unicode and the UCS are
// identical to those in ISO/IEC-8859-1.
return ch;
}
};
}}}
///////////////////////////////////////////////////////////////////////////////
// undefine macros
///////////////////////////////////////////////////////////////////////////////
#undef BOOST_CC_DIGIT
#undef BOOST_CC_XDIGIT
#undef BOOST_CC_ALPHA
#undef BOOST_CC_CTRL
#undef BOOST_CC_LOWER
#undef BOOST_CC_UPPER
#undef BOOST_CC_PUNCT
#undef BOOST_CC_SPACE
#endif
@@ -0,0 +1,138 @@
/*=============================================================================
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_STANDARD_APRIL_26_2006_1106PM)
#define BOOST_SPIRIT_STANDARD_APRIL_26_2006_1106PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <cctype>
#include <boost/cstdint.hpp>
namespace boost { namespace spirit { namespace char_encoding
{
///////////////////////////////////////////////////////////////////////////
// Test characters for specified conditions (using std functions)
///////////////////////////////////////////////////////////////////////////
struct standard
{
typedef char char_type;
static bool
isascii_(int ch)
{
return 0 == (ch & ~0x7f);
}
static bool
ischar(int ch)
{
// uses all 8 bits
// we have to watch out for sign extensions
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) ? true : false;
}
static bool
isalnum(int ch)
{
return std::isalnum(ch) ? true : false;
}
static bool
isalpha(int ch)
{
return std::isalpha(ch) ? true : false;
}
static bool
isdigit(int ch)
{
return std::isdigit(ch) ? true : false;
}
static bool
isxdigit(int ch)
{
return std::isxdigit(ch) ? true : false;
}
static bool
iscntrl(int ch)
{
return std::iscntrl(ch) ? true : false;
}
static bool
isgraph(int ch)
{
return std::isgraph(ch) ? true : false;
}
static bool
islower(int ch)
{
return std::islower(ch) ? true : false;
}
static bool
isprint(int ch)
{
return std::isprint(ch) ? true : false;
}
static bool
ispunct(int ch)
{
return std::ispunct(ch) ? true : false;
}
static bool
isspace(int ch)
{
return std::isspace(ch) ? true : false;
}
static bool
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
{
return (ch == ' ' || ch == '\t');
}
static bool
isupper(int ch)
{
return std::isupper(ch) ? true : false;
}
///////////////////////////////////////////////////////////////////////////////
// Simple character conversions
///////////////////////////////////////////////////////////////////////////////
static int
tolower(int ch)
{
return std::tolower(ch);
}
static int
toupper(int ch)
{
return std::toupper(ch);
}
static ::boost::uint32_t
toucs4(int ch)
{
return ch;
}
};
}}}
#endif
@@ -0,0 +1,186 @@
/*=============================================================================
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_STANDARD_WIDE_NOVEMBER_10_2006_0913AM)
#define BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <cwctype>
#include <string>
#include <boost/cstdint.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
namespace boost { namespace spirit { namespace traits
{
template <std::size_t N>
struct wchar_t_size
{
BOOST_SPIRIT_ASSERT_MSG(N == 1 || N == 2 || N == 4,
not_supported_size_of_wchar_t, ());
};
template <> struct wchar_t_size<1> { enum { mask = 0xff }; };
template <> struct wchar_t_size<2> { enum { mask = 0xffff }; };
template <> struct wchar_t_size<4> { enum { mask = 0xffffffff }; };
}}}
namespace boost { namespace spirit { namespace char_encoding
{
///////////////////////////////////////////////////////////////////////////
// Test characters for specified conditions (using std wchar_t functions)
///////////////////////////////////////////////////////////////////////////
struct standard_wide
{
typedef wchar_t char_type;
template <typename Char>
static typename std::char_traits<Char>::int_type
to_int_type(Char ch)
{
return std::char_traits<Char>::to_int_type(ch);
}
template <typename Char>
static Char
to_char_type(typename std::char_traits<Char>::int_type ch)
{
return std::char_traits<Char>::to_char_type(ch);
}
static bool
ischar(int ch)
{
// we have to watch out for sign extensions (casting is there to
// silence certain compilers complaining about signed/unsigned
// mismatch)
return (
std::size_t(0) ==
std::size_t(ch & ~traits::wchar_t_size<sizeof(wchar_t)>::mask) ||
std::size_t(~0) ==
std::size_t(ch | traits::wchar_t_size<sizeof(wchar_t)>::mask)
) ? true : false; // any wchar_t, but no other bits set
}
static bool
isalnum(wchar_t ch)
{
using namespace std;
return iswalnum(to_int_type(ch)) ? true : false;
}
static bool
isalpha(wchar_t ch)
{
using namespace std;
return iswalpha(to_int_type(ch)) ? true : false;
}
static bool
iscntrl(wchar_t ch)
{
using namespace std;
return iswcntrl(to_int_type(ch)) ? true : false;
}
static bool
isdigit(wchar_t ch)
{
using namespace std;
return iswdigit(to_int_type(ch)) ? true : false;
}
static bool
isgraph(wchar_t ch)
{
using namespace std;
return iswgraph(to_int_type(ch)) ? true : false;
}
static bool
islower(wchar_t ch)
{
using namespace std;
return iswlower(to_int_type(ch)) ? true : false;
}
static bool
isprint(wchar_t ch)
{
using namespace std;
return iswprint(to_int_type(ch)) ? true : false;
}
static bool
ispunct(wchar_t ch)
{
using namespace std;
return iswpunct(to_int_type(ch)) ? true : false;
}
static bool
isspace(wchar_t ch)
{
using namespace std;
return iswspace(to_int_type(ch)) ? true : false;
}
static bool
isupper(wchar_t ch)
{
using namespace std;
return iswupper(to_int_type(ch)) ? true : false;
}
static bool
isxdigit(wchar_t ch)
{
using namespace std;
return iswxdigit(to_int_type(ch)) ? true : false;
}
static bool
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (wchar_t ch)
{
return (ch == L' ' || ch == L'\t');
}
///////////////////////////////////////////////////////////////////////
// Simple character conversions
///////////////////////////////////////////////////////////////////////
static wchar_t
tolower(wchar_t ch)
{
using namespace std;
return isupper(ch) ?
to_char_type<wchar_t>(towlower(to_int_type(ch))) : ch;
}
static wchar_t
toupper(wchar_t ch)
{
using namespace std;
return islower(ch) ?
to_char_type<wchar_t>(towupper(to_int_type(ch))) : ch;
}
static ::boost::uint32_t
toucs4(int ch)
{
return ch;
}
};
}}}
#endif
@@ -0,0 +1,339 @@
/*=============================================================================
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_UNICODE_1_JANUARY_12_2010_0728PM)
#define BOOST_SPIRIT_UNICODE_1_JANUARY_12_2010_0728PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/cstdint.hpp>
#include <boost/spirit/home/support/char_encoding/unicode/query.hpp>
namespace boost { namespace spirit { namespace char_encoding
{
///////////////////////////////////////////////////////////////////////////
// Test characters for specified conditions (using iso8859-1)
///////////////////////////////////////////////////////////////////////////
struct unicode
{
typedef ::boost::uint32_t char_type;
///////////////////////////////////////////////////////////////////////////
// Posix stuff
///////////////////////////////////////////////////////////////////////////
static bool
isascii_(char_type ch)
{
return 0 == (ch & ~0x7f);
}
static bool
ischar(char_type ch)
{
// unicode code points in the range 0x00 to 0x10FFFF
return ch <= 0x10FFFF;
}
static bool
isalnum(char_type ch)
{
return ucd::is_alphanumeric(ch);
}
static bool
isalpha(char_type ch)
{
return ucd::is_alphabetic(ch);
}
static bool
isdigit(char_type ch)
{
return ucd::is_decimal_number(ch);
}
static bool
isxdigit(char_type ch)
{
return ucd::is_hex_digit(ch);
}
static bool
iscntrl(char_type ch)
{
return ucd::is_control(ch);
}
static bool
isgraph(char_type ch)
{
return ucd::is_graph(ch);
}
static bool
islower(char_type ch)
{
return ucd::is_lowercase(ch);
}
static bool
isprint(char_type ch)
{
return ucd::is_print(ch);
}
static bool
ispunct(char_type ch)
{
return ucd::is_punctuation(ch);
}
static bool
isspace(char_type ch)
{
return ucd::is_white_space(ch);
}
static bool
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (char_type ch)
{
return ucd::is_blank(ch);
}
static bool
isupper(char_type ch)
{
return ucd::is_uppercase(ch);
}
///////////////////////////////////////////////////////////////////////////
// Simple character conversions
///////////////////////////////////////////////////////////////////////////
static char_type
tolower(char_type ch)
{
return ucd::to_lowercase(ch);
}
static char_type
toupper(char_type ch)
{
return ucd::to_uppercase(ch);
}
static ::boost::uint32_t
toucs4(char_type ch)
{
return ch;
}
///////////////////////////////////////////////////////////////////////////
// Major Categories
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_MAJOR_CATEGORY(name) \
static bool \
is_##name(char_type ch) \
{ \
return ucd::get_major_category(ch) == ucd::properties::name; \
} \
/***/
BOOST_SPIRIT_MAJOR_CATEGORY(letter)
BOOST_SPIRIT_MAJOR_CATEGORY(mark)
BOOST_SPIRIT_MAJOR_CATEGORY(number)
BOOST_SPIRIT_MAJOR_CATEGORY(separator)
BOOST_SPIRIT_MAJOR_CATEGORY(other)
BOOST_SPIRIT_MAJOR_CATEGORY(punctuation)
BOOST_SPIRIT_MAJOR_CATEGORY(symbol)
///////////////////////////////////////////////////////////////////////////
// General Categories
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_CATEGORY(name) \
static bool \
is_##name(char_type ch) \
{ \
return ucd::get_category(ch) == ucd::properties::name; \
} \
/***/
BOOST_SPIRIT_CATEGORY(uppercase_letter)
BOOST_SPIRIT_CATEGORY(lowercase_letter)
BOOST_SPIRIT_CATEGORY(titlecase_letter)
BOOST_SPIRIT_CATEGORY(modifier_letter)
BOOST_SPIRIT_CATEGORY(other_letter)
BOOST_SPIRIT_CATEGORY(nonspacing_mark)
BOOST_SPIRIT_CATEGORY(enclosing_mark)
BOOST_SPIRIT_CATEGORY(spacing_mark)
BOOST_SPIRIT_CATEGORY(decimal_number)
BOOST_SPIRIT_CATEGORY(letter_number)
BOOST_SPIRIT_CATEGORY(other_number)
BOOST_SPIRIT_CATEGORY(space_separator)
BOOST_SPIRIT_CATEGORY(line_separator)
BOOST_SPIRIT_CATEGORY(paragraph_separator)
BOOST_SPIRIT_CATEGORY(control)
BOOST_SPIRIT_CATEGORY(format)
BOOST_SPIRIT_CATEGORY(private_use)
BOOST_SPIRIT_CATEGORY(surrogate)
BOOST_SPIRIT_CATEGORY(unassigned)
BOOST_SPIRIT_CATEGORY(dash_punctuation)
BOOST_SPIRIT_CATEGORY(open_punctuation)
BOOST_SPIRIT_CATEGORY(close_punctuation)
BOOST_SPIRIT_CATEGORY(connector_punctuation)
BOOST_SPIRIT_CATEGORY(other_punctuation)
BOOST_SPIRIT_CATEGORY(initial_punctuation)
BOOST_SPIRIT_CATEGORY(final_punctuation)
BOOST_SPIRIT_CATEGORY(math_symbol)
BOOST_SPIRIT_CATEGORY(currency_symbol)
BOOST_SPIRIT_CATEGORY(modifier_symbol)
BOOST_SPIRIT_CATEGORY(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Derived Categories
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_DERIVED_CATEGORY(name) \
static bool \
is_##name(char_type ch) \
{ \
return ucd::is_##name(ch); \
} \
/***/
BOOST_SPIRIT_DERIVED_CATEGORY(alphabetic)
BOOST_SPIRIT_DERIVED_CATEGORY(uppercase)
BOOST_SPIRIT_DERIVED_CATEGORY(lowercase)
BOOST_SPIRIT_DERIVED_CATEGORY(white_space)
BOOST_SPIRIT_DERIVED_CATEGORY(hex_digit)
BOOST_SPIRIT_DERIVED_CATEGORY(noncharacter_code_point)
BOOST_SPIRIT_DERIVED_CATEGORY(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Scripts
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_SCRIPT(name) \
static bool \
is_##name(char_type ch) \
{ \
return ucd::get_script(ch) == ucd::properties::name; \
} \
/***/
BOOST_SPIRIT_SCRIPT(arabic)
BOOST_SPIRIT_SCRIPT(imperial_aramaic)
BOOST_SPIRIT_SCRIPT(armenian)
BOOST_SPIRIT_SCRIPT(avestan)
BOOST_SPIRIT_SCRIPT(balinese)
BOOST_SPIRIT_SCRIPT(bamum)
BOOST_SPIRIT_SCRIPT(bengali)
BOOST_SPIRIT_SCRIPT(bopomofo)
BOOST_SPIRIT_SCRIPT(braille)
BOOST_SPIRIT_SCRIPT(buginese)
BOOST_SPIRIT_SCRIPT(buhid)
BOOST_SPIRIT_SCRIPT(canadian_aboriginal)
BOOST_SPIRIT_SCRIPT(carian)
BOOST_SPIRIT_SCRIPT(cham)
BOOST_SPIRIT_SCRIPT(cherokee)
BOOST_SPIRIT_SCRIPT(coptic)
BOOST_SPIRIT_SCRIPT(cypriot)
BOOST_SPIRIT_SCRIPT(cyrillic)
BOOST_SPIRIT_SCRIPT(devanagari)
BOOST_SPIRIT_SCRIPT(deseret)
BOOST_SPIRIT_SCRIPT(egyptian_hieroglyphs)
BOOST_SPIRIT_SCRIPT(ethiopic)
BOOST_SPIRIT_SCRIPT(georgian)
BOOST_SPIRIT_SCRIPT(glagolitic)
BOOST_SPIRIT_SCRIPT(gothic)
BOOST_SPIRIT_SCRIPT(greek)
BOOST_SPIRIT_SCRIPT(gujarati)
BOOST_SPIRIT_SCRIPT(gurmukhi)
BOOST_SPIRIT_SCRIPT(hangul)
BOOST_SPIRIT_SCRIPT(han)
BOOST_SPIRIT_SCRIPT(hanunoo)
BOOST_SPIRIT_SCRIPT(hebrew)
BOOST_SPIRIT_SCRIPT(hiragana)
BOOST_SPIRIT_SCRIPT(katakana_or_hiragana)
BOOST_SPIRIT_SCRIPT(old_italic)
BOOST_SPIRIT_SCRIPT(javanese)
BOOST_SPIRIT_SCRIPT(kayah_li)
BOOST_SPIRIT_SCRIPT(katakana)
BOOST_SPIRIT_SCRIPT(kharoshthi)
BOOST_SPIRIT_SCRIPT(khmer)
BOOST_SPIRIT_SCRIPT(kannada)
BOOST_SPIRIT_SCRIPT(kaithi)
BOOST_SPIRIT_SCRIPT(tai_tham)
BOOST_SPIRIT_SCRIPT(lao)
BOOST_SPIRIT_SCRIPT(latin)
BOOST_SPIRIT_SCRIPT(lepcha)
BOOST_SPIRIT_SCRIPT(limbu)
BOOST_SPIRIT_SCRIPT(linear_b)
BOOST_SPIRIT_SCRIPT(lisu)
BOOST_SPIRIT_SCRIPT(lycian)
BOOST_SPIRIT_SCRIPT(lydian)
BOOST_SPIRIT_SCRIPT(malayalam)
BOOST_SPIRIT_SCRIPT(mongolian)
BOOST_SPIRIT_SCRIPT(meetei_mayek)
BOOST_SPIRIT_SCRIPT(myanmar)
BOOST_SPIRIT_SCRIPT(nko)
BOOST_SPIRIT_SCRIPT(ogham)
BOOST_SPIRIT_SCRIPT(ol_chiki)
BOOST_SPIRIT_SCRIPT(old_turkic)
BOOST_SPIRIT_SCRIPT(oriya)
BOOST_SPIRIT_SCRIPT(osmanya)
BOOST_SPIRIT_SCRIPT(phags_pa)
BOOST_SPIRIT_SCRIPT(inscriptional_pahlavi)
BOOST_SPIRIT_SCRIPT(phoenician)
BOOST_SPIRIT_SCRIPT(inscriptional_parthian)
BOOST_SPIRIT_SCRIPT(rejang)
BOOST_SPIRIT_SCRIPT(runic)
BOOST_SPIRIT_SCRIPT(samaritan)
BOOST_SPIRIT_SCRIPT(old_south_arabian)
BOOST_SPIRIT_SCRIPT(saurashtra)
BOOST_SPIRIT_SCRIPT(shavian)
BOOST_SPIRIT_SCRIPT(sinhala)
BOOST_SPIRIT_SCRIPT(sundanese)
BOOST_SPIRIT_SCRIPT(syloti_nagri)
BOOST_SPIRIT_SCRIPT(syriac)
BOOST_SPIRIT_SCRIPT(tagbanwa)
BOOST_SPIRIT_SCRIPT(tai_le)
BOOST_SPIRIT_SCRIPT(new_tai_lue)
BOOST_SPIRIT_SCRIPT(tamil)
BOOST_SPIRIT_SCRIPT(tai_viet)
BOOST_SPIRIT_SCRIPT(telugu)
BOOST_SPIRIT_SCRIPT(tifinagh)
BOOST_SPIRIT_SCRIPT(tagalog)
BOOST_SPIRIT_SCRIPT(thaana)
BOOST_SPIRIT_SCRIPT(thai)
BOOST_SPIRIT_SCRIPT(tibetan)
BOOST_SPIRIT_SCRIPT(ugaritic)
BOOST_SPIRIT_SCRIPT(vai)
BOOST_SPIRIT_SCRIPT(old_persian)
BOOST_SPIRIT_SCRIPT(cuneiform)
BOOST_SPIRIT_SCRIPT(yi)
BOOST_SPIRIT_SCRIPT(inherited)
BOOST_SPIRIT_SCRIPT(common)
BOOST_SPIRIT_SCRIPT(unknown)
#undef BOOST_SPIRIT_MAJOR_CATEGORY
#undef BOOST_SPIRIT_CATEGORY
#undef BOOST_SPIRIT_DERIVED_CATEGORY
#undef BOOST_SPIRIT_SCRIPT
};
}}}
#endif
@@ -0,0 +1,620 @@
/*=============================================================================
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)
AUTOGENERATED. DO NOT EDIT!!!
==============================================================================*/
#include <boost/cstdint.hpp>
namespace boost { namespace spirit { namespace ucd { namespace detail
{
static const ::boost::uint8_t lowercase_stage1[] = {
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 9,
6, 10, 6, 6, 11, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 13, 14, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
6, 6, 6, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
};
static const ::boost::uint32_t lowercase_stage2[] = {
// block 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
240, 241, 242, 243, 244, 245, 246, 0, 248, 249, 250, 251, 252, 253, 254, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 1
257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 0, 271, 0,
273, 0, 275, 0, 277, 0, 279, 0, 281, 0, 283, 0, 285, 0, 287, 0,
289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 0, 303, 0,
105, 0, 307, 0, 309, 0, 311, 0, 0, 314, 0, 316, 0, 318, 0, 320,
0, 322, 0, 324, 0, 326, 0, 328, 0, 0, 331, 0, 333, 0, 335, 0,
337, 0, 339, 0, 341, 0, 343, 0, 345, 0, 347, 0, 349, 0, 351, 0,
353, 0, 355, 0, 357, 0, 359, 0, 361, 0, 363, 0, 365, 0, 367, 0,
369, 0, 371, 0, 373, 0, 375, 0, 255, 378, 0, 380, 0, 382, 0, 0,
0, 595, 387, 0, 389, 0, 596, 392, 0, 598, 599, 396, 0, 0, 477, 601,
603, 402, 0, 608, 611, 0, 617, 616, 409, 0, 0, 0, 623, 626, 0, 629,
417, 0, 419, 0, 421, 0, 640, 424, 0, 643, 0, 0, 429, 0, 648, 432,
0, 650, 651, 436, 0, 438, 0, 658, 441, 0, 0, 0, 445, 0, 0, 0,
0, 0, 0, 0, 454, 454, 0, 457, 457, 0, 460, 460, 0, 462, 0, 464,
0, 466, 0, 468, 0, 470, 0, 472, 0, 474, 0, 476, 0, 0, 479, 0,
481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0,
0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0,
// block 2
513, 0, 515, 0, 517, 0, 519, 0, 521, 0, 523, 0, 525, 0, 527, 0,
529, 0, 531, 0, 533, 0, 535, 0, 537, 0, 539, 0, 541, 0, 543, 0,
414, 0, 547, 0, 549, 0, 551, 0, 553, 0, 555, 0, 557, 0, 559, 0,
561, 0, 563, 0, 0, 0, 0, 0, 0, 0, 11365, 572, 0, 410, 11366, 0,
0, 578, 0, 384, 649, 652, 583, 0, 585, 0, 587, 0, 589, 0, 591, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
881, 0, 883, 0, 0, 0, 887, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 940, 0, 941, 942, 943, 0, 972, 0, 973, 974,
0, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959,
960, 961, 0, 963, 964, 965, 966, 967, 968, 969, 970, 971, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983,
0, 0, 0, 0, 0, 0, 0, 0, 985, 0, 987, 0, 989, 0, 991, 0,
993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0,
0, 0, 0, 0, 952, 0, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893,
// block 4
1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119,
1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1121, 0, 1123, 0, 1125, 0, 1127, 0, 1129, 0, 1131, 0, 1133, 0, 1135, 0,
1137, 0, 1139, 0, 1141, 0, 1143, 0, 1145, 0, 1147, 0, 1149, 0, 1151, 0,
1153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1163, 0, 1165, 0, 1167, 0,
1169, 0, 1171, 0, 1173, 0, 1175, 0, 1177, 0, 1179, 0, 1181, 0, 1183, 0,
1185, 0, 1187, 0, 1189, 0, 1191, 0, 1193, 0, 1195, 0, 1197, 0, 1199, 0,
1201, 0, 1203, 0, 1205, 0, 1207, 0, 1209, 0, 1211, 0, 1213, 0, 1215, 0,
1231, 1218, 0, 1220, 0, 1222, 0, 1224, 0, 1226, 0, 1228, 0, 1230, 0, 0,
1233, 0, 1235, 0, 1237, 0, 1239, 0, 1241, 0, 1243, 0, 1245, 0, 1247, 0,
1249, 0, 1251, 0, 1253, 0, 1255, 0, 1257, 0, 1259, 0, 1261, 0, 1263, 0,
1265, 0, 1267, 0, 1269, 0, 1271, 0, 1273, 0, 1275, 0, 1277, 0, 1279, 0,
// block 5
1281, 0, 1283, 0, 1285, 0, 1287, 0, 1289, 0, 1291, 0, 1293, 0, 1295, 0,
1297, 0, 1299, 0, 1301, 0, 1303, 0, 1305, 0, 1307, 0, 1309, 0, 1311, 0,
1313, 0, 1315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407,
1408, 1409, 1410, 1411, 1412, 1413, 1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11520, 11521, 11522, 11523, 11524, 11525, 11526, 11527, 11528, 11529, 11530, 11531, 11532, 11533, 11534, 11535,
11536, 11537, 11538, 11539, 11540, 11541, 11542, 11543, 11544, 11545, 11546, 11547, 11548, 11549, 11550, 11551,
11552, 11553, 11554, 11555, 11556, 11557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 8
7681, 0, 7683, 0, 7685, 0, 7687, 0, 7689, 0, 7691, 0, 7693, 0, 7695, 0,
7697, 0, 7699, 0, 7701, 0, 7703, 0, 7705, 0, 7707, 0, 7709, 0, 7711, 0,
7713, 0, 7715, 0, 7717, 0, 7719, 0, 7721, 0, 7723, 0, 7725, 0, 7727, 0,
7729, 0, 7731, 0, 7733, 0, 7735, 0, 7737, 0, 7739, 0, 7741, 0, 7743, 0,
7745, 0, 7747, 0, 7749, 0, 7751, 0, 7753, 0, 7755, 0, 7757, 0, 7759, 0,
7761, 0, 7763, 0, 7765, 0, 7767, 0, 7769, 0, 7771, 0, 7773, 0, 7775, 0,
7777, 0, 7779, 0, 7781, 0, 7783, 0, 7785, 0, 7787, 0, 7789, 0, 7791, 0,
7793, 0, 7795, 0, 7797, 0, 7799, 0, 7801, 0, 7803, 0, 7805, 0, 7807, 0,
7809, 0, 7811, 0, 7813, 0, 7815, 0, 7817, 0, 7819, 0, 7821, 0, 7823, 0,
7825, 0, 7827, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0,
7841, 0, 7843, 0, 7845, 0, 7847, 0, 7849, 0, 7851, 0, 7853, 0, 7855, 0,
7857, 0, 7859, 0, 7861, 0, 7863, 0, 7865, 0, 7867, 0, 7869, 0, 7871, 0,
7873, 0, 7875, 0, 7877, 0, 7879, 0, 7881, 0, 7883, 0, 7885, 0, 7887, 0,
7889, 0, 7891, 0, 7893, 0, 7895, 0, 7897, 0, 7899, 0, 7901, 0, 7903, 0,
7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0,
7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0,
// block 9
0, 0, 0, 0, 0, 0, 0, 0, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943,
0, 0, 0, 0, 0, 0, 0, 0, 7952, 7953, 7954, 7955, 7956, 7957, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975,
0, 0, 0, 0, 0, 0, 0, 0, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991,
0, 0, 0, 0, 0, 0, 0, 0, 8000, 8001, 8002, 8003, 8004, 8005, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 8017, 0, 8019, 0, 8021, 0, 8023,
0, 0, 0, 0, 0, 0, 0, 0, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071,
0, 0, 0, 0, 0, 0, 0, 0, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087,
0, 0, 0, 0, 0, 0, 0, 0, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103,
0, 0, 0, 0, 0, 0, 0, 0, 8112, 8113, 8048, 8049, 8115, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8050, 8051, 8052, 8053, 8131, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8144, 8145, 8054, 8055, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0,
// block 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 969, 0, 0, 0, 107, 229, 0, 0, 0, 0,
0, 0, 8526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8560, 8561, 8562, 8563, 8564, 8565, 8566, 8567, 8568, 8569, 8570, 8571, 8572, 8573, 8574, 8575,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, 9433,
9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 12
11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327,
11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343,
11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11361, 0, 619, 7549, 637, 0, 0, 11368, 0, 11370, 0, 11372, 0, 593, 625, 592,
0, 0, 11379, 0, 0, 11382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11393, 0, 11395, 0, 11397, 0, 11399, 0, 11401, 0, 11403, 0, 11405, 0, 11407, 0,
11409, 0, 11411, 0, 11413, 0, 11415, 0, 11417, 0, 11419, 0, 11421, 0, 11423, 0,
11425, 0, 11427, 0, 11429, 0, 11431, 0, 11433, 0, 11435, 0, 11437, 0, 11439, 0,
11441, 0, 11443, 0, 11445, 0, 11447, 0, 11449, 0, 11451, 0, 11453, 0, 11455, 0,
11457, 0, 11459, 0, 11461, 0, 11463, 0, 11465, 0, 11467, 0, 11469, 0, 11471, 0,
11473, 0, 11475, 0, 11477, 0, 11479, 0, 11481, 0, 11483, 0, 11485, 0, 11487, 0,
11489, 0, 11491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 13
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42561, 0, 42563, 0, 42565, 0, 42567, 0, 42569, 0, 42571, 0, 42573, 0, 42575, 0,
42577, 0, 42579, 0, 42581, 0, 42583, 0, 42585, 0, 42587, 0, 42589, 0, 42591, 0,
0, 0, 42595, 0, 42597, 0, 42599, 0, 42601, 0, 42603, 0, 42605, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42625, 0, 42627, 0, 42629, 0, 42631, 0, 42633, 0, 42635, 0, 42637, 0, 42639, 0,
42641, 0, 42643, 0, 42645, 0, 42647, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 42787, 0, 42789, 0, 42791, 0, 42793, 0, 42795, 0, 42797, 0, 42799, 0,
0, 0, 42803, 0, 42805, 0, 42807, 0, 42809, 0, 42811, 0, 42813, 0, 42815, 0,
42817, 0, 42819, 0, 42821, 0, 42823, 0, 42825, 0, 42827, 0, 42829, 0, 42831, 0,
42833, 0, 42835, 0, 42837, 0, 42839, 0, 42841, 0, 42843, 0, 42845, 0, 42847, 0,
42849, 0, 42851, 0, 42853, 0, 42855, 0, 42857, 0, 42859, 0, 42861, 0, 42863, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 42874, 0, 42876, 0, 7545, 42879, 0,
42881, 0, 42883, 0, 42885, 0, 42887, 0, 0, 0, 0, 42892, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359,
65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 16
66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,
66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627, 66628, 66629, 66630, 66631,
66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
inline ::boost::uint32_t lowercase_lookup(::boost::uint32_t ch)
{
::boost::uint32_t block_offset = lowercase_stage1[ch / 256] * 256;
return lowercase_stage2[block_offset + ch % 256];
}
}}}} // namespace boost::spirit::unicode::detail
@@ -0,0 +1,305 @@
/*=============================================================================
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)
Autogenerated by MultiStageTable.py (Unicode multi-stage
table builder) (c) Peter Kankowski, 2008
==============================================================================*/
#if !defined(BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010)
#define BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010
#include <boost/cstdint.hpp>
# include "category_table.hpp"
# include "script_table.hpp"
# include "lowercase_table.hpp"
# include "uppercase_table.hpp"
namespace boost { namespace spirit { namespace ucd
{
// This header provides Basic (Level 1) Unicode Support
// See http://unicode.org/reports/tr18/ for details
struct properties
{
// bit pattern: xxMMMCCC
// MMM: major_category
// CCC: category
enum major_category
{
letter,
mark,
number,
separator,
other,
punctuation,
symbol
};
enum category
{
uppercase_letter = 0, // [Lu] an uppercase letter
lowercase_letter, // [Ll] a lowercase letter
titlecase_letter, // [Lt] a digraphic character, with first part uppercase
modifier_letter, // [Lm] a modifier letter
other_letter, // [Lo] other letters, including syllables and ideographs
nonspacing_mark = 8, // [Mn] a nonspacing combining mark (zero advance width)
enclosing_mark, // [Me] an enclosing combining mark
spacing_mark, // [Mc] a spacing combining mark (positive advance width)
decimal_number = 16, // [Nd] a decimal digit
letter_number, // [Nl] a letterlike numeric character
other_number, // [No] a numeric character of other type
space_separator = 24, // [Zs] a space character (of various non-zero widths)
line_separator, // [Zl] U+2028 LINE SEPARATOR only
paragraph_separator, // [Zp] U+2029 PARAGRAPH SEPARATOR only
control = 32, // [Cc] a C0 or C1 control code
format, // [Cf] a format control character
private_use, // [Co] a private-use character
surrogate, // [Cs] a surrogate code point
unassigned, // [Cn] a reserved unassigned code point or a noncharacter
dash_punctuation = 40, // [Pd] a dash or hyphen punctuation mark
open_punctuation, // [Ps] an opening punctuation mark (of a pair)
close_punctuation, // [Pe] a closing punctuation mark (of a pair)
connector_punctuation, // [Pc] a connecting punctuation mark, like a tie
other_punctuation, // [Po] a punctuation mark of other type
initial_punctuation, // [Pi] an initial quotation mark
final_punctuation, // [Pf] a final quotation mark
math_symbol = 48, // [Sm] a symbol of primarily mathematical use
currency_symbol, // [Sc] a currency sign
modifier_symbol, // [Sk] a non-letterlike modifier symbol
other_symbol // [So] a symbol of other type
};
enum derived_properties
{
alphabetic = 64,
uppercase = 128,
lowercase = 256,
white_space = 512,
hex_digit = 1024,
noncharacter_code_point = 2048,
default_ignorable_code_point = 4096
};
enum script
{
arabic = 0,
imperial_aramaic = 1,
armenian = 2,
avestan = 3,
balinese = 4,
bamum = 5,
bengali = 6,
bopomofo = 7,
braille = 8,
buginese = 9,
buhid = 10,
canadian_aboriginal = 11,
carian = 12,
cham = 13,
cherokee = 14,
coptic = 15,
cypriot = 16,
cyrillic = 17,
devanagari = 18,
deseret = 19,
egyptian_hieroglyphs = 20,
ethiopic = 21,
georgian = 22,
glagolitic = 23,
gothic = 24,
greek = 25,
gujarati = 26,
gurmukhi = 27,
hangul = 28,
han = 29,
hanunoo = 30,
hebrew = 31,
hiragana = 32,
katakana_or_hiragana = 33,
old_italic = 34,
javanese = 35,
kayah_li = 36,
katakana = 37,
kharoshthi = 38,
khmer = 39,
kannada = 40,
kaithi = 41,
tai_tham = 42,
lao = 43,
latin = 44,
lepcha = 45,
limbu = 46,
linear_b = 47,
lisu = 48,
lycian = 49,
lydian = 50,
malayalam = 51,
mongolian = 52,
meetei_mayek = 53,
myanmar = 54,
nko = 55,
ogham = 56,
ol_chiki = 57,
old_turkic = 58,
oriya = 59,
osmanya = 60,
phags_pa = 61,
inscriptional_pahlavi = 62,
phoenician = 63,
inscriptional_parthian = 64,
rejang = 65,
runic = 66,
samaritan = 67,
old_south_arabian = 68,
saurashtra = 69,
shavian = 70,
sinhala = 71,
sundanese = 72,
syloti_nagri = 73,
syriac = 74,
tagbanwa = 75,
tai_le = 76,
new_tai_lue = 77,
tamil = 78,
tai_viet = 79,
telugu = 80,
tifinagh = 81,
tagalog = 82,
thaana = 83,
thai = 84,
tibetan = 85,
ugaritic = 86,
vai = 87,
old_persian = 88,
cuneiform = 89,
yi = 90,
inherited = 91,
common = 92,
unknown = 93
};
};
inline properties::category get_category(::boost::uint32_t ch)
{
return static_cast<properties::category>(detail::category_lookup(ch) & 0x3F);
}
inline properties::major_category get_major_category(::boost::uint32_t ch)
{
return static_cast<properties::major_category>(get_category(ch) >> 3);
}
inline bool is_punctuation(::boost::uint32_t ch)
{
return get_major_category(ch) == properties::punctuation;
}
inline bool is_decimal_number(::boost::uint32_t ch)
{
return get_category(ch) == properties::decimal_number;
}
inline bool is_hex_digit(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::hex_digit) != 0;
}
inline bool is_control(::boost::uint32_t ch)
{
return get_category(ch) == properties::control;
}
inline bool is_alphabetic(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::alphabetic) != 0;
}
inline bool is_alphanumeric(::boost::uint32_t ch)
{
return is_decimal_number(ch) || is_alphabetic(ch);
}
inline bool is_uppercase(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::uppercase) != 0;
}
inline bool is_lowercase(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::lowercase) != 0;
}
inline bool is_white_space(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::white_space) != 0;
}
inline bool is_blank(::boost::uint32_t ch)
{
switch (ch)
{
case '\n': case '\v': case '\f': case '\r':
return false;
default:
return is_white_space(ch)
&& !( get_category(ch) == properties::line_separator
|| get_category(ch) == properties::paragraph_separator
);
}
}
inline bool is_graph(::boost::uint32_t ch)
{
return !( is_white_space(ch)
|| get_category(ch) == properties::control
|| get_category(ch) == properties::surrogate
|| get_category(ch) == properties::unassigned
);
}
inline bool is_print(::boost::uint32_t ch)
{
return (is_graph(ch) || is_blank(ch)) && !is_control(ch);
}
inline bool is_noncharacter_code_point(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::noncharacter_code_point) != 0;
}
inline bool is_default_ignorable_code_point(::boost::uint32_t ch)
{
return (detail::category_lookup(ch) & properties::default_ignorable_code_point) != 0;
}
inline properties::script get_script(::boost::uint32_t ch)
{
return static_cast<properties::script>(detail::script_lookup(ch) & 0x7F);
}
inline ::boost::uint32_t to_lowercase(::boost::uint32_t ch)
{
// The table returns 0 to signal that this code maps to itself
::boost::uint32_t r = detail::lowercase_lookup(ch);
return (r == 0)? ch : r;
}
inline ::boost::uint32_t to_uppercase(::boost::uint32_t ch)
{
// The table returns 0 to signal that this code maps to itself
::boost::uint32_t r = detail::uppercase_lookup(ch);
return (r == 0)? ch : r;
}
}}}
#endif
@@ -0,0 +1,639 @@
/*=============================================================================
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)
AUTOGENERATED. DO NOT EDIT!!!
==============================================================================*/
#include <boost/cstdint.hpp>
namespace boost { namespace spirit { namespace ucd { namespace detail
{
static const ::boost::uint8_t uppercase_stage1[] = {
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 9,
6, 10, 6, 6, 11, 6, 6, 6, 6, 6, 6, 6, 12, 13, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 14, 15, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16,
6, 6, 6, 6, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
};
static const ::boost::uint32_t uppercase_stage2[] = {
// block 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
208, 209, 210, 211, 212, 213, 214, 0, 216, 217, 218, 219, 220, 221, 222, 376,
// block 1
0, 256, 0, 258, 0, 260, 0, 262, 0, 264, 0, 266, 0, 268, 0, 270,
0, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286,
0, 288, 0, 290, 0, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302,
0, 73, 0, 306, 0, 308, 0, 310, 0, 0, 313, 0, 315, 0, 317, 0,
319, 0, 321, 0, 323, 0, 325, 0, 327, 0, 0, 330, 0, 332, 0, 334,
0, 336, 0, 338, 0, 340, 0, 342, 0, 344, 0, 346, 0, 348, 0, 350,
0, 352, 0, 354, 0, 356, 0, 358, 0, 360, 0, 362, 0, 364, 0, 366,
0, 368, 0, 370, 0, 372, 0, 374, 0, 0, 377, 0, 379, 0, 381, 83,
579, 0, 0, 386, 0, 388, 0, 0, 391, 0, 0, 0, 395, 0, 0, 0,
0, 0, 401, 0, 0, 502, 0, 0, 0, 408, 573, 0, 0, 0, 544, 0,
0, 416, 0, 418, 0, 420, 0, 0, 423, 0, 0, 0, 0, 428, 0, 0,
431, 0, 0, 0, 435, 0, 437, 0, 0, 440, 0, 0, 0, 444, 0, 503,
0, 0, 0, 0, 0, 452, 452, 0, 455, 455, 0, 458, 458, 0, 461, 0,
463, 0, 465, 0, 467, 0, 469, 0, 471, 0, 473, 0, 475, 398, 0, 478,
0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494,
0, 0, 497, 497, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510,
// block 2
0, 512, 0, 514, 0, 516, 0, 518, 0, 520, 0, 522, 0, 524, 0, 526,
0, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 0, 540, 0, 542,
0, 0, 0, 546, 0, 548, 0, 550, 0, 552, 0, 554, 0, 556, 0, 558,
0, 560, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0,
0, 0, 577, 0, 0, 0, 0, 582, 0, 584, 0, 586, 0, 588, 0, 590,
11375, 11373, 0, 385, 390, 0, 393, 394, 0, 399, 0, 400, 0, 0, 0, 0,
403, 0, 0, 404, 0, 0, 0, 0, 407, 406, 0, 11362, 0, 0, 0, 412,
0, 11374, 413, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 11364, 0, 0,
422, 0, 0, 425, 0, 0, 0, 0, 430, 580, 433, 434, 581, 0, 0, 0,
0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 3
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 880, 0, 882, 0, 0, 0, 886, 0, 0, 0, 1021, 1022, 1023, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 902, 904, 905, 906,
0, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927,
928, 929, 931, 931, 932, 933, 934, 935, 936, 937, 938, 939, 908, 910, 911, 0,
914, 920, 0, 0, 0, 934, 928, 975, 0, 984, 0, 986, 0, 988, 0, 990,
0, 992, 0, 994, 0, 996, 0, 998, 0, 1000, 0, 1002, 0, 1004, 0, 1006,
922, 929, 1017, 0, 0, 917, 0, 0, 1015, 0, 0, 1018, 0, 0, 0, 0,
// block 4
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071,
1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
0, 1120, 0, 1122, 0, 1124, 0, 1126, 0, 1128, 0, 1130, 0, 1132, 0, 1134,
0, 1136, 0, 1138, 0, 1140, 0, 1142, 0, 1144, 0, 1146, 0, 1148, 0, 1150,
0, 1152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 1164, 0, 1166,
0, 1168, 0, 1170, 0, 1172, 0, 1174, 0, 1176, 0, 1178, 0, 1180, 0, 1182,
0, 1184, 0, 1186, 0, 1188, 0, 1190, 0, 1192, 0, 1194, 0, 1196, 0, 1198,
0, 1200, 0, 1202, 0, 1204, 0, 1206, 0, 1208, 0, 1210, 0, 1212, 0, 1214,
0, 0, 1217, 0, 1219, 0, 1221, 0, 1223, 0, 1225, 0, 1227, 0, 1229, 1216,
0, 1232, 0, 1234, 0, 1236, 0, 1238, 0, 1240, 0, 1242, 0, 1244, 0, 1246,
0, 1248, 0, 1250, 0, 1252, 0, 1254, 0, 1256, 0, 1258, 0, 1260, 0, 1262,
0, 1264, 0, 1266, 0, 1268, 0, 1270, 0, 1272, 0, 1274, 0, 1276, 0, 1278,
// block 5
0, 1280, 0, 1282, 0, 1284, 0, 1286, 0, 1288, 0, 1290, 0, 1292, 0, 1294,
0, 1296, 0, 1298, 0, 1300, 0, 1302, 0, 1304, 0, 1306, 0, 1308, 0, 1310,
0, 1312, 0, 1314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343,
1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359,
1360, 1361, 1362, 1363, 1364, 1365, 1366, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 6
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 7
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 42877, 0, 0, 0, 11363, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 8
0, 7680, 0, 7682, 0, 7684, 0, 7686, 0, 7688, 0, 7690, 0, 7692, 0, 7694,
0, 7696, 0, 7698, 0, 7700, 0, 7702, 0, 7704, 0, 7706, 0, 7708, 0, 7710,
0, 7712, 0, 7714, 0, 7716, 0, 7718, 0, 7720, 0, 7722, 0, 7724, 0, 7726,
0, 7728, 0, 7730, 0, 7732, 0, 7734, 0, 7736, 0, 7738, 0, 7740, 0, 7742,
0, 7744, 0, 7746, 0, 7748, 0, 7750, 0, 7752, 0, 7754, 0, 7756, 0, 7758,
0, 7760, 0, 7762, 0, 7764, 0, 7766, 0, 7768, 0, 7770, 0, 7772, 0, 7774,
0, 7776, 0, 7778, 0, 7780, 0, 7782, 0, 7784, 0, 7786, 0, 7788, 0, 7790,
0, 7792, 0, 7794, 0, 7796, 0, 7798, 0, 7800, 0, 7802, 0, 7804, 0, 7806,
0, 7808, 0, 7810, 0, 7812, 0, 7814, 0, 7816, 0, 7818, 0, 7820, 0, 7822,
0, 7824, 0, 7826, 0, 7828, 0, 0, 0, 0, 0, 7776, 0, 0, 0, 0,
0, 7840, 0, 7842, 0, 7844, 0, 7846, 0, 7848, 0, 7850, 0, 7852, 0, 7854,
0, 7856, 0, 7858, 0, 7860, 0, 7862, 0, 7864, 0, 7866, 0, 7868, 0, 7870,
0, 7872, 0, 7874, 0, 7876, 0, 7878, 0, 7880, 0, 7882, 0, 7884, 0, 7886,
0, 7888, 0, 7890, 0, 7892, 0, 7894, 0, 7896, 0, 7898, 0, 7900, 0, 7902,
0, 7904, 0, 7906, 0, 7908, 0, 7910, 0, 7912, 0, 7914, 0, 7916, 0, 7918,
0, 7920, 0, 7922, 0, 7924, 0, 7926, 0, 7928, 0, 7930, 0, 7932, 0, 7934,
// block 9
7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 0, 0, 0, 0, 0, 0, 0, 0,
7960, 7961, 7962, 7963, 7964, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 0, 0, 0, 0, 0, 0, 0, 0,
7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 0, 0, 0, 0, 0, 0, 0, 0,
8008, 8009, 8010, 8011, 8012, 8013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8025, 0, 8027, 0, 8029, 0, 8031, 0, 0, 0, 0, 0, 0, 0, 0,
8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 0, 0, 0, 0, 0, 0, 0, 0,
8122, 8123, 8136, 8137, 8138, 8139, 8154, 8155, 8184, 8185, 8170, 8171, 8186, 8187, 0, 0,
8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 0, 0, 0, 0, 0, 0, 0, 0,
8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 0, 0, 0, 0, 0, 0, 0, 0,
8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 0, 0, 0, 0, 0, 0, 0, 0,
8120, 8121, 0, 8124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, 0,
0, 0, 0, 8140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8152, 8153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8168, 8169, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 10
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8498, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8544, 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 8558, 8559,
0, 0, 0, 0, 8579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 11
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413,
9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 12
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, 11278, 11279,
11280, 11281, 11282, 11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, 11294, 11295,
11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 11307, 11308, 11309, 11310, 0,
0, 11360, 0, 0, 0, 570, 574, 0, 11367, 0, 11369, 0, 11371, 0, 0, 0,
0, 0, 0, 11378, 0, 0, 11381, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 11392, 0, 11394, 0, 11396, 0, 11398, 0, 11400, 0, 11402, 0, 11404, 0, 11406,
0, 11408, 0, 11410, 0, 11412, 0, 11414, 0, 11416, 0, 11418, 0, 11420, 0, 11422,
0, 11424, 0, 11426, 0, 11428, 0, 11430, 0, 11432, 0, 11434, 0, 11436, 0, 11438,
0, 11440, 0, 11442, 0, 11444, 0, 11446, 0, 11448, 0, 11450, 0, 11452, 0, 11454,
0, 11456, 0, 11458, 0, 11460, 0, 11462, 0, 11464, 0, 11466, 0, 11468, 0, 11470,
0, 11472, 0, 11474, 0, 11476, 0, 11478, 0, 11480, 0, 11482, 0, 11484, 0, 11486,
0, 11488, 0, 11490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 13
4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271,
4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287,
4288, 4289, 4290, 4291, 4292, 4293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 14
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 42560, 0, 42562, 0, 42564, 0, 42566, 0, 42568, 0, 42570, 0, 42572, 0, 42574,
0, 42576, 0, 42578, 0, 42580, 0, 42582, 0, 42584, 0, 42586, 0, 42588, 0, 42590,
0, 0, 0, 42594, 0, 42596, 0, 42598, 0, 42600, 0, 42602, 0, 42604, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 42624, 0, 42626, 0, 42628, 0, 42630, 0, 42632, 0, 42634, 0, 42636, 0, 42638,
0, 42640, 0, 42642, 0, 42644, 0, 42646, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 42786, 0, 42788, 0, 42790, 0, 42792, 0, 42794, 0, 42796, 0, 42798,
0, 0, 0, 42802, 0, 42804, 0, 42806, 0, 42808, 0, 42810, 0, 42812, 0, 42814,
0, 42816, 0, 42818, 0, 42820, 0, 42822, 0, 42824, 0, 42826, 0, 42828, 0, 42830,
0, 42832, 0, 42834, 0, 42836, 0, 42838, 0, 42840, 0, 42842, 0, 42844, 0, 42846,
0, 42848, 0, 42850, 0, 42852, 0, 42854, 0, 42856, 0, 42858, 0, 42860, 0, 42862,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42873, 0, 42875, 0, 0, 42878,
0, 42880, 0, 42882, 0, 42884, 0, 42886, 0, 0, 0, 0, 42891, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 16
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326, 65327,
65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 65337, 65338, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// block 17
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 66560, 66561, 66562, 66563, 66564, 66565, 66566, 66567,
66568, 66569, 66570, 66571, 66572, 66573, 66574, 66575, 66576, 66577, 66578, 66579, 66580, 66581, 66582, 66583,
66584, 66585, 66586, 66587, 66588, 66589, 66590, 66591, 66592, 66593, 66594, 66595, 66596, 66597, 66598, 66599,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
inline ::boost::uint32_t uppercase_lookup(::boost::uint32_t ch)
{
::boost::uint32_t block_offset = uppercase_stage1[ch / 256] * 256;
return uppercase_stage2[block_offset + ch % 256];
}
}}}} // namespace boost::spirit::unicode::detail
@@ -0,0 +1,249 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2009 Daniel Nuffer
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)
=============================================================================*/
#ifndef BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
#if defined(_MSC_VER)
#pragma once
#endif
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <climits>
#include <boost/spirit/home/support/char_set/range_run.hpp>
namespace boost { namespace spirit { namespace support { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: basic character set implementation using range_run
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset
{
basic_chset() {}
basic_chset(basic_chset const& arg_)
: rr(arg_.rr) {}
bool
test(Char v) const
{
return rr.test(v);
}
void
set(Char from, Char to)
{
rr.set(range<Char>(from, to));
}
void
set(Char c)
{
rr.set(range<Char>(c, c));
}
void
clear(Char from, Char to)
{
rr.clear(range<Char>(from, to));
}
void
clear(Char c)
{
rr.clear(range<Char>(c, c));
}
void
clear()
{
rr.clear();
}
void
inverse()
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= *this;
swap(inv);
}
void
swap(basic_chset& x)
{
rr.swap(x.rr);
}
basic_chset&
operator|=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.set(*iter);
return *this;
}
basic_chset&
operator&=(basic_chset const& x)
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= x;
*this -= inv;
return *this;
}
basic_chset&
operator-=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.clear(*iter);
return *this;
}
basic_chset&
operator^=(basic_chset const& x)
{
basic_chset bma = x;
bma -= *this;
*this -= x;
*this |= bma;
return *this;
}
private: range_run<Char> rr;
};
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset_8bit
{
basic_chset_8bit() {}
basic_chset_8bit(basic_chset_8bit const& arg_)
: bset(arg_.bset) {}
bool
test(Char v) const
{
return bset.test((unsigned char)v);
}
void
set(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.set((unsigned char)i);
}
void
set(Char c)
{
bset.set((unsigned char)c);
}
void
clear(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.reset((unsigned char)i);
}
void
clear(Char c)
{
bset.reset((unsigned char)c);
}
void
clear()
{
bset.reset();
}
void
inverse()
{
bset.flip();
}
void
swap(basic_chset_8bit& x)
{
std::swap(bset, x.bset);
}
basic_chset_8bit&
operator|=(basic_chset_8bit const& x)
{
bset |= x.bset;
return *this;
}
basic_chset_8bit&
operator&=(basic_chset_8bit const& x)
{
bset &= x.bset;
return *this;
}
basic_chset_8bit&
operator-=(basic_chset_8bit const& x)
{
bset &= ~x.bset;
return *this;
}
basic_chset_8bit&
operator^=(basic_chset_8bit const& x)
{
bset ^= x.bset;
return *this;
}
private: std::bitset<256> bset;
};
/////////////////////////////////
template <>
struct basic_chset<char>
: basic_chset_8bit<char> {};
/////////////////////////////////
template <>
struct basic_chset<signed char>
: basic_chset_8bit<signed char> {};
/////////////////////////////////
template <>
struct basic_chset<unsigned char>
: basic_chset_8bit<unsigned char> {};
#endif // #if (CHAR_BIT == 8)
}}}}
#endif
@@ -0,0 +1,32 @@
/*=============================================================================
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_RANGE_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit { namespace support { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// A closed range (first, last)
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct range
{
typedef T value_type;
range() : first(), last() {}
range(T first_, T last_) : first(first_), last(last_) {}
T first;
T last;
};
}}}}
#endif
@@ -0,0 +1,98 @@
/*=============================================================================
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_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/integer_traits.hpp>
namespace boost { namespace spirit { namespace support { namespace detail
{
template <typename Range>
inline bool
is_valid(Range const& range)
{
// test for valid ranges
return range.first <= range.last;
}
template <typename Range>
inline bool
includes(Range const& range, Range const& other)
{
// see if two ranges intersect
return (range.first <= other.first) && (range.last >= other.last);
}
template <typename Range>
inline bool
includes(Range const& range, typename Range::value_type val)
{
// see if val is in range
return (range.first <= val) && (range.last >= val);
}
template <typename Range>
inline bool
can_merge(Range const& range, Range const& other)
{
// see if a 'range' overlaps, or is adjacent to
// another range 'other', so we can merge them
typedef typename Range::value_type value_type;
typedef integer_traits<value_type> integer_traits;
value_type decr_first =
range.first == integer_traits::const_min
? range.first : range.first-1;
value_type incr_last =
range.last == integer_traits::const_max
? range.last : range.last+1;
return (decr_first <= other.last) && (incr_last >= other.first);
}
template <typename Range>
inline void
merge(Range& result, Range const& other)
{
// merge two ranges
if (result.first > other.first)
result.first = other.first;
if (result.last < other.last)
result.last = other.last;
}
template <typename Range>
struct range_compare
{
// compare functor with a value or another range
typedef typename Range::value_type value_type;
bool operator()(Range const& x, const value_type y) const
{
return x.first < y;
}
bool operator()(value_type const x, Range const& y) const
{
return x < y.first;
}
bool operator()(Range const& x, Range const& y) const
{
return x.first < y.first;
}
};
}}}}
#endif
@@ -0,0 +1,56 @@
/*=============================================================================
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_RANGE_RUN_MAY_16_2006_0801_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/char_set/range.hpp>
#include <vector>
namespace boost { namespace spirit { namespace support { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// range_run
//
// An implementation of a sparse bit (boolean) set. The set uses
// a sorted vector of disjoint ranges. This class implements the
// bare minimum essentials from which the full range of set
// operators can be implemented. The set is constructed from
// ranges. Internally, adjacent or overlapping ranges are
// coalesced.
//
// range_runs are very space-economical in situations where there
// are lots of ranges and a few individual disjoint values.
// Searching is O(log n) where n is the number of ranges.
//
// { Low level interface }
///////////////////////////////////////////////////////////////////////////
template <typename Char>
class range_run
{
public:
typedef range<Char> range_type;
typedef std::vector<range_type> storage_type;
void swap(range_run& other);
bool test(Char v) const;
void set(range_type const& range);
void clear(range_type const& range);
void clear();
private:
storage_type run;
};
}}}}
#include <boost/spirit/home/support/char_set/range_run_impl.hpp>
#endif
@@ -0,0 +1,185 @@
/*=============================================================================
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_RANGE_RUN_MAY_16_2006_0807_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/char_set/range_functions.hpp>
#include <boost/assert.hpp>
#include <algorithm>
namespace boost { namespace spirit { namespace support { namespace detail
{
template <typename Run, typename Iterator, typename Range>
inline bool
try_merge(Run& run, Iterator iter, Range const& range)
{
// if *iter intersects with, or is adjacent to, 'range'...
if (can_merge(*iter, range))
{
// merge range and *iter
merge(*iter, range);
// collapse all subsequent ranges that can merge with *iter:
Iterator i = iter+1;
// 1. skip subsequent ranges completely included in *iter
while (i != run.end() && i->last <= iter->last)
++i;
// 2. collapse next range if adjacent or overlapping with *iter
if (i != run.end() && i->first-1 <= iter->last)
{
iter->last = i->last;
++i;
}
// erase all ranges that were collapsed
run.erase(iter+1, i);
return true;
}
return false;
}
template <typename Char>
inline bool
range_run<Char>::test(Char val) const
{
if (run.empty())
return false;
// search the ranges for one that potentially includes val
typename storage_type::const_iterator iter =
std::upper_bound(
run.begin(), run.end(), val,
range_compare<range_type>()
);
// return true if *(iter-1) includes val
return iter != run.begin() && includes(*(--iter), val);
}
template <typename Char>
inline void
range_run<Char>::swap(range_run& other)
{
run.swap(other.run);
}
template <typename Char>
void
range_run<Char>::set(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (run.empty())
{
// the vector is empty, insert 'range'
run.push_back(range);
return;
}
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
if (iter != run.begin())
{
// if *(iter-1) includes 'range', return early
if (includes(*(iter-1), range))
{
return;
}
// if *(iter-1) can merge with 'range', merge them and return
if (try_merge(run, iter-1, range))
{
return;
}
}
// if *iter can merge with with 'range', merge them
if (iter == run.end() || !try_merge(run, iter, range))
{
// no overlap, insert 'range'
run.insert(iter, range);
}
}
template <typename Char>
void
range_run<Char>::clear(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (!run.empty())
{
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
// 'range' starts with or after another range:
if (iter != run.begin())
{
typename storage_type::iterator const left_iter = iter-1;
// 'range' starts after '*left_iter':
if (left_iter->first < range.first)
{
// if 'range' is completely included inside '*left_iter':
// need to break it apart into two ranges (punch a hole),
if (left_iter->last > range.last)
{
Char save_last = left_iter->last;
left_iter->last = range.first-1;
run.insert(iter, range_type(range.last+1, save_last));
return;
}
// if 'range' contains 'left_iter->last':
// truncate '*left_iter' (clip its right)
else if (left_iter->last >= range.first)
{
left_iter->last = range.first-1;
}
}
// 'range' has the same left bound as '*left_iter': it
// must be removed or truncated by the code below
else
{
iter = left_iter;
}
}
// remove or truncate subsequent ranges that overlap with 'range':
typename storage_type::iterator i = iter;
// 1. skip subsequent ranges completely included in 'range'
while (i != run.end() && i->last <= range.last)
++i;
// 2. clip left of next range if overlapping with 'range'
if (i != run.end() && i->first <= range.last)
i->first = range.last+1;
// erase all ranges that 'range' contained
run.erase(iter, i);
}
}
template <typename Char>
inline void
range_run<Char>::clear()
{
run.clear();
}
}}}}
#endif
@@ -0,0 +1,437 @@
/*=============================================================================
Copyright (c) 2001-2011 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_COMMON_PLACEHOLDERS_OCTOBER_16_2008_0102PM
#define BOOST_SPIRIT_COMMON_PLACEHOLDERS_OCTOBER_16_2008_0102PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.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/support/char_class.hpp>
#include <boost/mpl/vector.hpp>
#if defined(BOOST_SPIRIT_UNICODE)
# include <boost/spirit/home/support/char_encoding/unicode.hpp>
#endif
namespace boost { namespace spirit
{
typedef mpl::vector<
spirit::char_encoding::ascii
, spirit::char_encoding::iso8859_1
, spirit::char_encoding::standard
, spirit::char_encoding::standard_wide
#if defined(BOOST_SPIRIT_UNICODE)
, spirit::char_encoding::unicode
#endif
>
char_encodings;
template <typename T>
struct is_char_encoding : mpl::false_ {};
template <>
struct is_char_encoding<spirit::char_encoding::ascii> : mpl::true_ {};
template <>
struct is_char_encoding<spirit::char_encoding::iso8859_1> : mpl::true_ {};
template <>
struct is_char_encoding<spirit::char_encoding::standard> : mpl::true_ {};
template <>
struct is_char_encoding<spirit::char_encoding::standard_wide> : mpl::true_ {};
#if defined(BOOST_SPIRIT_UNICODE)
template <>
struct is_char_encoding<spirit::char_encoding::unicode> : mpl::true_ {};
#endif
template <typename Encoding>
struct encoding
: proto::terminal<tag::char_code<tag::encoding, Encoding> >::type
{};
// Our basic terminals
BOOST_SPIRIT_DEFINE_TERMINALS_NAME(
( verbatim, verbatim_type )
( no_delimit, no_delimit_type )
( lexeme, lexeme_type )
( no_skip, no_skip_type )
( omit, omit_type )
( raw, raw_type )
( as_string, as_string_type )
( as_wstring, as_wstring_type )
( inf, inf_type )
( eol, eol_type )
( eoi, eoi_type )
( buffer, buffer_type )
( true_, true_type )
( false_, false_type )
( matches, matches_type )
( hold, hold_type )
( strict, strict_type )
( relaxed, relaxed_type )
( duplicate, duplicate_type )
)
// Our extended terminals
BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(
( lit, lit_type )
( bin, bin_type )
( oct, oct_type )
( hex, hex_type )
( bool_, bool_type )
( ushort_, ushort_type )
( ulong_, ulong_type )
( uint_, uint_type )
( short_, short_type )
( long_, long_type )
( int_, int_type )
( ulong_long, ulong_long_type )
( long_long, long_long_type )
( float_, float_type )
( double_, double_type )
( long_double, long_double_type )
( repeat, repeat_type )
( eps, eps_type )
( pad, pad_type )
( byte_, byte_type )
( word, word_type )
( big_word, big_word_type )
( little_word, little_word_type )
( dword, dword_type )
( big_dword, big_dword_type )
( little_dword, little_dword_type )
( qword, qword_type )
( big_qword, big_qword_type )
( little_qword, little_qword_type )
( bin_float, bin_float_type )
( big_bin_float, big_bin_float_type )
( little_bin_float, little_bin_float_type )
( bin_double, bin_double_type )
( big_bin_double, big_bin_double_type )
( little_bin_double, little_bin_double_type )
( skip, skip_type )
( delimit, delimit_type )
( stream, stream_type )
( wstream, wstream_type )
( left_align, left_align_type )
( right_align, right_align_type )
( center, center_type )
( maxwidth, maxwidth_type )
( set_state, set_state_type )
( in_state, in_state_type )
( token, token_type )
( tokenid, tokenid_type )
( raw_token, raw_token_type )
( tokenid_mask, tokenid_mask_type )
( attr, attr_type )
( columns, columns_type )
( auto_, auto_type )
)
// special tags (used mainly for stateful tag types)
namespace tag
{
struct attr_cast { BOOST_SPIRIT_IS_TAG() };
struct as { BOOST_SPIRIT_IS_TAG() };
}
}}
///////////////////////////////////////////////////////////////////////////////
// Here we place the character-set sensitive placeholders. We have one set
// each for ascii, iso8859_1, standard and standard_wide and unicode. These
// placeholders are placed in its char-set namespace. For example, there exist
// a placeholder spirit::ascii::alnum for ascii versions of alnum.
#define BOOST_SPIRIT_TAG_CHAR_SPEC(charset) \
typedef tag::char_code<tag::char_, charset> char_; \
typedef tag::char_code<tag::string, charset> string; \
/***/
#ifdef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define BOOST_SPIRIT_CHAR_SPEC(charset) \
typedef spirit::terminal<tag::charset::char_> char_type; \
typedef spirit::terminal<tag::charset::string> string_type; \
/***/
#else
#define BOOST_SPIRIT_CHAR_SPEC(charset) \
typedef spirit::terminal<tag::charset::char_> char_type; \
char_type const char_ = char_type(); \
\
inline void silence_unused_warnings_##char_() { (void) char_; } \
\
typedef spirit::terminal<tag::charset::string> string_type; \
string_type const string = string_type(); \
\
inline void silence_unused_warnings_##string() { (void) string; } \
/***/
#endif
#ifdef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define BOOST_SPIRIT_CHAR_CODE(name, charset) \
typedef proto::terminal<tag::char_code<tag::name, charset> >::type \
name##_type; \
/***/
#else
#define BOOST_SPIRIT_CHAR_CODE(name, charset) \
typedef proto::terminal<tag::char_code<tag::name, charset> >::type \
name##_type; \
name##_type const name = name##_type(); \
\
inline void silence_unused_warnings_##name() { (void) name; } \
/***/
#endif
#define BOOST_SPIRIT_DEFINE_CHAR_CODES(charset) \
namespace boost { namespace spirit { namespace tag { namespace charset \
{ \
BOOST_SPIRIT_TAG_CHAR_SPEC(spirit::char_encoding::charset) \
}}}} \
namespace boost { namespace spirit { namespace charset \
{ \
BOOST_SPIRIT_CHAR_SPEC(charset) \
\
BOOST_SPIRIT_CHAR_CODE(alnum, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(alpha, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(blank, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(cntrl, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(digit, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(graph, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(print, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(punct, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(space, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(xdigit, spirit::char_encoding::charset) \
\
BOOST_SPIRIT_CHAR_CODE(no_case, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(lower, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(upper, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(lowernum, spirit::char_encoding::charset) \
BOOST_SPIRIT_CHAR_CODE(uppernum, spirit::char_encoding::charset) \
}}} \
/***/
BOOST_SPIRIT_DEFINE_CHAR_CODES(ascii)
BOOST_SPIRIT_DEFINE_CHAR_CODES(iso8859_1)
BOOST_SPIRIT_DEFINE_CHAR_CODES(standard)
BOOST_SPIRIT_DEFINE_CHAR_CODES(standard_wide)
namespace boost { namespace spirit { namespace traits
{
template <typename Char>
struct char_encoding_from_char;
template <>
struct char_encoding_from_char<char>
: mpl::identity<spirit::char_encoding::standard>
{};
template <>
struct char_encoding_from_char<wchar_t>
: mpl::identity<spirit::char_encoding::standard_wide>
{};
template <typename T>
struct char_encoding_from_char<T const>
: char_encoding_from_char<T>
{};
}}}
#if defined(BOOST_SPIRIT_UNICODE)
BOOST_SPIRIT_DEFINE_CHAR_CODES(unicode)
namespace boost { namespace spirit { namespace tag { namespace unicode
{
BOOST_SPIRIT_TAG_CHAR_SPEC(spirit::char_encoding::unicode)
}}}}
namespace boost { namespace spirit { namespace unicode
{
#define BOOST_SPIRIT_UNICODE_CHAR_CODE(name) \
BOOST_SPIRIT_CHAR_CODE(name, spirit::char_encoding::unicode) \
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CHAR_CODE(letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(mark)
BOOST_SPIRIT_UNICODE_CHAR_CODE(number)
BOOST_SPIRIT_UNICODE_CHAR_CODE(separator)
BOOST_SPIRIT_UNICODE_CHAR_CODE(other)
BOOST_SPIRIT_UNICODE_CHAR_CODE(punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CHAR_CODE(uppercase_letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lowercase_letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(titlecase_letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(modifier_letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_letter)
BOOST_SPIRIT_UNICODE_CHAR_CODE(nonspacing_mark)
BOOST_SPIRIT_UNICODE_CHAR_CODE(enclosing_mark)
BOOST_SPIRIT_UNICODE_CHAR_CODE(spacing_mark)
BOOST_SPIRIT_UNICODE_CHAR_CODE(decimal_number)
BOOST_SPIRIT_UNICODE_CHAR_CODE(letter_number)
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_number)
BOOST_SPIRIT_UNICODE_CHAR_CODE(space_separator)
BOOST_SPIRIT_UNICODE_CHAR_CODE(line_separator)
BOOST_SPIRIT_UNICODE_CHAR_CODE(paragraph_separator)
BOOST_SPIRIT_UNICODE_CHAR_CODE(control)
BOOST_SPIRIT_UNICODE_CHAR_CODE(format)
BOOST_SPIRIT_UNICODE_CHAR_CODE(private_use)
BOOST_SPIRIT_UNICODE_CHAR_CODE(surrogate)
BOOST_SPIRIT_UNICODE_CHAR_CODE(unassigned)
BOOST_SPIRIT_UNICODE_CHAR_CODE(dash_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(open_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(close_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(connector_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(initial_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(final_punctuation)
BOOST_SPIRIT_UNICODE_CHAR_CODE(math_symbol)
BOOST_SPIRIT_UNICODE_CHAR_CODE(currency_symbol)
BOOST_SPIRIT_UNICODE_CHAR_CODE(modifier_symbol)
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CHAR_CODE(alphabetic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(uppercase)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lowercase)
BOOST_SPIRIT_UNICODE_CHAR_CODE(white_space)
BOOST_SPIRIT_UNICODE_CHAR_CODE(hex_digit)
BOOST_SPIRIT_UNICODE_CHAR_CODE(noncharacter_code_point)
BOOST_SPIRIT_UNICODE_CHAR_CODE(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_UNICODE_CHAR_CODE(arabic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(imperial_aramaic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(armenian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(avestan)
BOOST_SPIRIT_UNICODE_CHAR_CODE(balinese)
BOOST_SPIRIT_UNICODE_CHAR_CODE(bamum)
BOOST_SPIRIT_UNICODE_CHAR_CODE(bengali)
BOOST_SPIRIT_UNICODE_CHAR_CODE(bopomofo)
BOOST_SPIRIT_UNICODE_CHAR_CODE(braille)
BOOST_SPIRIT_UNICODE_CHAR_CODE(buginese)
BOOST_SPIRIT_UNICODE_CHAR_CODE(buhid)
BOOST_SPIRIT_UNICODE_CHAR_CODE(canadian_aboriginal)
BOOST_SPIRIT_UNICODE_CHAR_CODE(carian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(cham)
BOOST_SPIRIT_UNICODE_CHAR_CODE(cherokee)
BOOST_SPIRIT_UNICODE_CHAR_CODE(coptic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(cypriot)
BOOST_SPIRIT_UNICODE_CHAR_CODE(cyrillic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(devanagari)
BOOST_SPIRIT_UNICODE_CHAR_CODE(deseret)
BOOST_SPIRIT_UNICODE_CHAR_CODE(egyptian_hieroglyphs)
BOOST_SPIRIT_UNICODE_CHAR_CODE(ethiopic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(georgian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(glagolitic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(gothic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(greek)
BOOST_SPIRIT_UNICODE_CHAR_CODE(gujarati)
BOOST_SPIRIT_UNICODE_CHAR_CODE(gurmukhi)
BOOST_SPIRIT_UNICODE_CHAR_CODE(hangul)
BOOST_SPIRIT_UNICODE_CHAR_CODE(han)
BOOST_SPIRIT_UNICODE_CHAR_CODE(hanunoo)
BOOST_SPIRIT_UNICODE_CHAR_CODE(hebrew)
BOOST_SPIRIT_UNICODE_CHAR_CODE(hiragana)
BOOST_SPIRIT_UNICODE_CHAR_CODE(katakana_or_hiragana)
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_italic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(javanese)
BOOST_SPIRIT_UNICODE_CHAR_CODE(kayah_li)
BOOST_SPIRIT_UNICODE_CHAR_CODE(katakana)
BOOST_SPIRIT_UNICODE_CHAR_CODE(kharoshthi)
BOOST_SPIRIT_UNICODE_CHAR_CODE(khmer)
BOOST_SPIRIT_UNICODE_CHAR_CODE(kannada)
BOOST_SPIRIT_UNICODE_CHAR_CODE(kaithi)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_tham)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lao)
BOOST_SPIRIT_UNICODE_CHAR_CODE(latin)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lepcha)
BOOST_SPIRIT_UNICODE_CHAR_CODE(limbu)
BOOST_SPIRIT_UNICODE_CHAR_CODE(linear_b)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lisu)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lycian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(lydian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(malayalam)
BOOST_SPIRIT_UNICODE_CHAR_CODE(mongolian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(meetei_mayek)
BOOST_SPIRIT_UNICODE_CHAR_CODE(myanmar)
BOOST_SPIRIT_UNICODE_CHAR_CODE(nko)
BOOST_SPIRIT_UNICODE_CHAR_CODE(ogham)
BOOST_SPIRIT_UNICODE_CHAR_CODE(ol_chiki)
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_turkic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(oriya)
BOOST_SPIRIT_UNICODE_CHAR_CODE(osmanya)
BOOST_SPIRIT_UNICODE_CHAR_CODE(phags_pa)
BOOST_SPIRIT_UNICODE_CHAR_CODE(inscriptional_pahlavi)
BOOST_SPIRIT_UNICODE_CHAR_CODE(phoenician)
BOOST_SPIRIT_UNICODE_CHAR_CODE(inscriptional_parthian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(rejang)
BOOST_SPIRIT_UNICODE_CHAR_CODE(runic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(samaritan)
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_south_arabian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(saurashtra)
BOOST_SPIRIT_UNICODE_CHAR_CODE(shavian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(sinhala)
BOOST_SPIRIT_UNICODE_CHAR_CODE(sundanese)
BOOST_SPIRIT_UNICODE_CHAR_CODE(syloti_nagri)
BOOST_SPIRIT_UNICODE_CHAR_CODE(syriac)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tagbanwa)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_le)
BOOST_SPIRIT_UNICODE_CHAR_CODE(new_tai_lue)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tamil)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_viet)
BOOST_SPIRIT_UNICODE_CHAR_CODE(telugu)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tifinagh)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tagalog)
BOOST_SPIRIT_UNICODE_CHAR_CODE(thaana)
BOOST_SPIRIT_UNICODE_CHAR_CODE(thai)
BOOST_SPIRIT_UNICODE_CHAR_CODE(tibetan)
BOOST_SPIRIT_UNICODE_CHAR_CODE(ugaritic)
BOOST_SPIRIT_UNICODE_CHAR_CODE(vai)
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_persian)
BOOST_SPIRIT_UNICODE_CHAR_CODE(cuneiform)
BOOST_SPIRIT_UNICODE_CHAR_CODE(yi)
BOOST_SPIRIT_UNICODE_CHAR_CODE(inherited)
BOOST_SPIRIT_UNICODE_CHAR_CODE(common)
BOOST_SPIRIT_UNICODE_CHAR_CODE(unknown)
#undef BOOST_SPIRIT_UNICODE_CHAR_CODE
}}}
#endif
#endif
@@ -0,0 +1,589 @@
/*=============================================================================
Copyright (c) 2001-2011 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_CONTAINER_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains some container utils for stl containers. The
// utilities provided also accept spirit's unused_type; all no-ops.
// Compiler optimization will easily strip these away.
///////////////////////////////////////////////////////////////////////////
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
}
template <typename T, typename Enable/* = void*/>
struct is_container
: mpl::bool_<
detail::has_value_type<T>::value &&
detail::has_iterator<T>::value &&
detail::has_size_type<T>::value &&
detail::has_reference<T>::value>
{};
template <typename T>
struct is_container<T&>
: is_container<T>
{};
template <typename T>
struct is_container<boost::optional<T> >
: is_container<T>
{};
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template<typename T>
struct is_container<boost::variant<T> >
: is_container<T>
{};
template<typename T0, typename T1, typename ...TN>
struct is_container<boost::variant<T0, T1, TN...> >
: mpl::bool_<is_container<T0>::value ||
is_container<boost::variant<T1, TN...> >::value>
{};
#else
#define BOOST_SPIRIT_IS_CONTAINER(z, N, data) \
is_container<BOOST_PP_CAT(T, N)>::value || \
/***/
// make sure unused variant parameters do not affect the outcome
template <>
struct is_container<boost::detail::variant::void_>
: mpl::false_
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
, BOOST_SPIRIT_IS_CONTAINER, _) false>
{};
#undef BOOST_SPIRIT_IS_CONTAINER
#endif
template <typename T, typename Enable/* = void*/>
struct is_iterator_range
: mpl::false_
{};
template <typename T>
struct is_iterator_range<iterator_range<T> >
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct remove_value_const
{
typedef T type;
};
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;
};
}
///////////////////////////////////////////////////////////////////////
//[customization_container_value_default
template <typename Container, typename Enable/* = void*/>
struct container_value
: detail::remove_value_const<typename Container::value_type>
{};
//]
template <typename T>
struct container_value<T&>
: container_value<T>
{};
// this will be instantiated if the optional holds a container
template <typename T>
struct container_value<boost::optional<T> >
: container_value<T>
{};
// this will be instantiated if the variant holds a container
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
typedef typename
variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
types;
typedef typename
mpl::find_if<types, is_container<mpl::_1> >::type
iter;
typedef typename container_value<
typename mpl::if_<
is_same<iter, typename mpl::end<types>::type>
, unused_type, typename mpl::deref<iter>::type
>::type
>::type type;
};
//[customization_container_value_unused
template <>
struct container_value<unused_type>
{
typedef unused_type type;
};
//]
template <>
struct container_value<unused_type const>
{
typedef unused_type type;
};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable/* = void*/>
struct container_iterator
{
typedef typename Container::iterator type;
};
template <typename Container>
struct container_iterator<Container&>
: container_iterator<Container>
{};
template <typename Container>
struct container_iterator<Container const>
{
typedef typename Container::const_iterator type;
};
template <typename T>
struct container_iterator<optional<T> >
: container_iterator<T>
{};
template <typename T>
struct container_iterator<optional<T> const>
: container_iterator<T const>
{};
template <typename Iterator>
struct container_iterator<iterator_range<Iterator> >
{
typedef typename range_const_iterator<
iterator_range<Iterator> >::type type;
};
template <>
struct container_iterator<unused_type>
{
typedef unused_type const* type;
};
template <>
struct container_iterator<unused_type const>
{
typedef unused_type const* type;
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable/* = void*/>
struct optional_attribute
{
typedef T const& type;
static type call(T const& val)
{
return val;
}
static bool is_valid(T const&)
{
return true;
}
};
template <typename T>
struct optional_attribute<boost::optional<T> >
{
typedef T const& type;
static type call(boost::optional<T> const& val)
{
return boost::get<T>(val);
}
static bool is_valid(boost::optional<T> const& val)
{
return !!val;
}
};
template <typename T>
typename optional_attribute<T>::type
optional_value(T const& val)
{
return optional_attribute<T>::call(val);
}
inline unused_type optional_value(unused_type)
{
return unused;
}
template <typename T>
bool has_optional_value(T const& val)
{
return optional_attribute<T>::is_valid(val);
}
inline bool has_optional_value(unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename T>
bool push_back(Container& c, T const& val);
//[customization_push_back_default
template <typename Container, typename T, typename Enable/* = void*/>
struct push_back_container
{
static bool call(Container& c, T const& val)
{
c.insert(c.end(), val);
return true;
}
};
//]
template <typename Container, typename T>
struct push_back_container<optional<Container>, T>
{
static bool call(boost::optional<Container>& c, T const& val)
{
if (!c)
c = Container();
return push_back(boost::get<Container>(c), val);
}
};
namespace detail
{
template <typename T>
struct push_back_visitor : public static_visitor<>
{
typedef bool result_type;
push_back_visitor(T const& t) : t_(t) {}
template <typename Container>
bool push_back_impl(Container& c, mpl::true_) const
{
return push_back(c, t_);
}
template <typename T_>
bool push_back_impl(T_&, mpl::false_) const
{
// this variant doesn't hold a container
BOOST_ASSERT(false && "This variant doesn't hold a container");
return false;
}
template <typename T_>
bool operator()(T_& c) const
{
return push_back_impl(c, typename is_container<T_>::type());
}
T const& t_;
};
}
template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T>
struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T>
{
static bool call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
{
return apply_visitor(detail::push_back_visitor<T>(val), c);
}
};
template <typename Container, typename T>
bool push_back(Container& c, T const& val)
{
return push_back_container<Container, T>::call(c, val);
}
//[customization_push_back_unused
template <typename Container>
bool push_back(Container&, unused_type)
{
return true;
}
//]
template <typename T>
bool push_back(unused_type, T const&)
{
return true;
}
inline bool push_back(unused_type, unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable/* = void*/>
struct is_empty_container
{
static bool call(Container const& c)
{
return c.empty();
}
};
template <typename Container>
bool is_empty(Container const& c)
{
return is_empty_container<Container>::call(c);
}
inline bool is_empty(unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
// Ensure the attribute is actually a container type
template <typename Container, typename Enable/* = void*/>
struct make_container_attribute
{
static void call(Container&)
{
// for static types this function does nothing
}
};
template <typename T>
void make_container(T& t)
{
make_container_attribute<T>::call(t);
}
inline void make_container(unused_type)
{
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable/* = void*/>
struct begin_container
{
static typename container_iterator<Container>::type call(Container& c)
{
return c.begin();
}
};
template <typename Container>
typename spirit::result_of::begin<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 spirit::result_of::end<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;
}
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace result_of
{
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct optional_value
{
typedef T type;
};
template <typename T>
struct optional_value<boost::optional<T> >
{
typedef T type;
};
template <typename T>
struct optional_value<boost::optional<T> const>
{
typedef T const type;
};
template <>
struct optional_value<unused_type>
{
typedef unused_type type;
};
template <>
struct optional_value<unused_type const>
{
typedef unused_type type;
};
///////////////////////////////////////////////////////////////////////////
template <typename Container>
struct begin
: traits::container_iterator<Container>
{};
template <typename Container>
struct end
: traits::container_iterator<Container>
{};
template <typename Iterator>
struct deref
: traits::deref_iterator<Iterator>
{};
template <>
struct deref<unused_type const*>
{
typedef unused_type type;
};
}}}
#endif
@@ -0,0 +1,299 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Thomas Heller
Distributed under the 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_CONTEXT_OCTOBER_31_2008_0654PM)
#define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/support/nonterminal/expand_arg.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/limits.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/as_list.hpp>
#include <boost/fusion/include/transform.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/at.hpp>
///////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
typedef phoenix::actor<attribute<n> > \
BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
phoenix::actor<attribute<n> > const \
BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)();
/***/
#define SPIRIT_USING_ATTRIBUTE(z, n, data) \
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
using spirit::BOOST_PP_CAT(_r, n); \
/***/
#else
#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
typedef phoenix::actor<attribute<n> > \
BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
/***/
#define SPIRIT_USING_ATTRIBUTE(z, n, data) \
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
/***/
#endif
namespace boost { namespace spirit
{
template <int>
struct attribute;
template <int>
struct local_variable;
}}
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
template <int N>
, boost::spirit::attribute<N>
, mpl::false_ // is not nullary
, v2_eval(
proto::make<
boost::spirit::attribute<N>()
>
, proto::call<
functional::env(proto::_state)
>
)
)
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
template <int N>
, boost::spirit::local_variable<N>
, mpl::false_ // is not nullary
, v2_eval(
proto::make<
boost::spirit::local_variable<N>()
>
, proto::call<
functional::env(proto::_state)
>
)
)
namespace boost { namespace spirit
{
template <typename Attributes, typename Locals>
struct context
{
typedef Attributes attributes_type;
typedef Locals locals_type;
context(typename Attributes::car_type attribute)
: attributes(attribute, fusion::nil_()), locals() {}
template <typename Args, typename Context>
context(
typename Attributes::car_type attribute
, Args const& args
, Context& caller_context
) : attributes(
attribute
, fusion::as_list(
fusion::transform(
args
, detail::expand_arg<Context>(caller_context)
)
)
)
, locals() {}
context(Attributes const& attributes_)
: attributes(attributes_), locals() {}
Attributes attributes; // The attributes
Locals locals; // Local variables
};
template <typename Context>
struct attributes_of
{
typedef typename Context::attributes_type type;
};
template <typename Context>
struct attributes_of<Context const>
{
typedef typename Context::attributes_type const type;
};
template <typename Context>
struct attributes_of<Context &>
: attributes_of<Context>
{};
template <typename Context>
struct locals_of
{
typedef typename Context::locals_type type;
};
template <typename Context>
struct locals_of<Context const>
{
typedef typename Context::locals_type const type;
};
template <typename Context>
struct locals_of<Context &>
{
typedef typename Context::locals_type type;
};
template <int N>
struct attribute
{
typedef mpl::true_ no_nullary;
template <typename Env>
struct result
{
typedef typename
attributes_of<typename
mpl::at_c<typename Env::args_type, 1>::type
>::type
attributes_type;
typedef typename
fusion::result_of::size<attributes_type>::type
attributes_size;
// report invalid argument not found (N is out of bounds)
BOOST_SPIRIT_ASSERT_MSG(
(N < attributes_size::value),
index_is_out_of_bounds, ());
typedef typename
fusion::result_of::at_c<attributes_type, N>::type
type;
};
template <typename Env>
typename result<Env>::type
eval(Env const& env) const
{
return fusion::at_c<N>((fusion::at_c<1>(env.args())).attributes);
}
};
template <int N>
struct local_variable
{
typedef mpl::true_ no_nullary;
template <typename Env>
struct result
{
typedef typename
locals_of<typename
mpl::at_c<typename Env::args_type, 1>::type
>::type
locals_type;
typedef typename
fusion::result_of::size<locals_type>::type
locals_size;
// report invalid argument not found (N is out of bounds)
BOOST_SPIRIT_ASSERT_MSG(
(N < locals_size::value),
index_is_out_of_bounds, ());
typedef typename
fusion::result_of::at_c<locals_type, N>::type
type;
};
template <typename Env>
typename result<Env>::type
eval(Env const& env) const
{
return get_arg<N>((fusion::at_c<1>(env.args())).locals);
}
};
typedef phoenix::actor<attribute<0> > _val_type;
typedef phoenix::actor<attribute<0> > _r0_type;
typedef phoenix::actor<attribute<1> > _r1_type;
typedef phoenix::actor<attribute<2> > _r2_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
// _val refers to the 'return' value of a rule (same as _r0)
// _r1, _r2, ... refer to the rule arguments
_val_type const _val = _val_type();
_r0_type const _r0 = _r0_type();
_r1_type const _r1 = _r1_type();
_r2_type const _r2 = _r2_type();
#endif
// Bring in the rest of the attributes (_r4 .. _rN+1), using PP
BOOST_PP_REPEAT_FROM_TO(
3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _)
typedef phoenix::actor<local_variable<0> > _a_type;
typedef phoenix::actor<local_variable<1> > _b_type;
typedef phoenix::actor<local_variable<2> > _c_type;
typedef phoenix::actor<local_variable<3> > _d_type;
typedef phoenix::actor<local_variable<4> > _e_type;
typedef phoenix::actor<local_variable<5> > _f_type;
typedef phoenix::actor<local_variable<6> > _g_type;
typedef phoenix::actor<local_variable<7> > _h_type;
typedef phoenix::actor<local_variable<8> > _i_type;
typedef phoenix::actor<local_variable<9> > _j_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
// _a, _b, ... refer to the local variables of a rule
_a_type const _a = _a_type();
_b_type const _b = _b_type();
_c_type const _c = _c_type();
_d_type const _d = _d_type();
_e_type const _e = _e_type();
_f_type const _f = _f_type();
_g_type const _g = _g_type();
_h_type const _h = _h_type();
_i_type const _i = _i_type();
_j_type const _j = _j_type();
#endif
// You can bring these in with the using directive
// without worrying about bringing in too much.
namespace labels
{
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::_val;
using spirit::_a;
using spirit::_b;
using spirit::_c;
using spirit::_d;
using spirit::_e;
using spirit::_f;
using spirit::_g;
using spirit::_h;
using spirit::_i;
using spirit::_j;
#endif
}
}}
#endif
@@ -0,0 +1,114 @@
/*=============================================================================
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)
==============================================================================*/
#ifndef BOOST_PP_IS_ITERATING
#if !defined(BOOST_SPIRIT_AS_VARIANT_NOVEMBER_16_2007_0420PM)
#define BOOST_SPIRIT_AS_VARIANT_NOVEMBER_16_2007_0420PM
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/value_of.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/limits/list.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace detail
{
template <int size>
struct as_variant_impl;
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
#else
template <>
struct as_variant_impl<0>
{
template <typename Iterator>
struct apply
{
typedef variant<> type;
};
};
#endif
#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
BOOST_PP_CAT(I, BOOST_PP_INC(n));
#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
BOOST_PP_CAT(T, n);
#define BOOST_PP_FILENAME_1 <boost/spirit/home/support/detail/as_variant.hpp>
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_MPL_LIMIT_LIST_SIZE)
#else
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_VARIANT_LIMIT_TYPES)
#endif
#include BOOST_PP_ITERATE()
#undef BOOST_FUSION_NEXT_ITERATOR
#undef BOOST_FUSION_NEXT_CALL_ITERATOR
#undef BOOST_FUSION_VALUE_OF_ITERATOR
template <typename Sequence>
struct as_variant
{
// build a variant generator being able to generate a variant holding
// all of the types as given in the typelist
typedef typename
detail::as_variant_impl<fusion::result_of::size<Sequence>::value>
gen;
// use this generator to create the actual variant
typedef typename gen::template apply<
typename fusion::result_of::begin<Sequence>::type
>::type
type;
};
}}}
#endif
#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#define N BOOST_PP_ITERATION()
template <>
struct as_variant_impl<N>
{
template <typename I0>
struct apply
{
BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
typedef variant<BOOST_PP_ENUM_PARAMS(N, T)> type;
};
};
#undef N
#endif // defined(BOOST_PP_IS_ITERATING)
@@ -0,0 +1,29 @@
// 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_ENDIAN_MAR_21_2009_0349PM)
#define SPIRIT_ENDIAN_MAR_21_2009_0349PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/version.hpp>
// We need to treat the endian number types as PODs
#if !defined(BOOST_ENDIAN_FORCE_PODNESS)
#define BOOST_ENDIAN_FORCE_PODNESS 1
#endif
// If Boost has the endian library, use it, otherwise use an adapted version
// included with Spirit
// #if BOOST_VERSION >= 105100
// #include <boost/endian/integers.hpp>
// #else
#include <boost/spirit/home/support/detail/endian/endian.hpp>
// #endif
#endif
@@ -0,0 +1,115 @@
// boost/integer/cover_operators.hpp ----------------------------------------//
// Copyright Darin Adler 2000
// Copyright Beman Dawes 2008
// Distributed under the 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 the class being covered has a non-explicit conversion to an integer type
// then a smaller number of cover operations are needed. Define the macro
// BOOST_MINIMAL_INTEGER_COVER_OPERATORS to indicate this.
// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
//----------------------------------------------------------------------------//
#ifndef BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
#define BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
#if defined(_MSC_VER)
#pragma once
#endif
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
# include <boost/operators.hpp>
# endif
#include <iosfwd>
namespace boost { namespace spirit
{
namespace endian
{
// A class that adds integer operators to an integer cover class
template <typename T, typename IntegerType>
class cover_operators
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
: boost::operators<T>
# endif
{
// The other operations take advantage of the type conversion that's
// built into unary +.
// Unary operations.
friend IntegerType operator+(const T& x) { return x; }
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
friend IntegerType operator-(const T& x) { return -+x; }
friend IntegerType operator~(const T& x) { return ~+x; }
friend IntegerType operator!(const T& x) { return !+x; }
// The basic ordering operations.
friend bool operator==(const T& x, IntegerType y) { return +x == y; }
friend bool operator<(const T& x, IntegerType y) { return +x < y; }
# endif
// The basic arithmetic operations.
friend T& operator+=(T& x, IntegerType y) { return x = +x + y; }
friend T& operator-=(T& x, IntegerType y) { return x = +x - y; }
friend T& operator*=(T& x, IntegerType y) { return x = +x * y; }
friend T& operator/=(T& x, IntegerType y) { return x = +x / y; }
friend T& operator%=(T& x, IntegerType y) { return x = +x % y; }
friend T& operator&=(T& x, IntegerType y) { return x = +x & y; }
friend T& operator|=(T& x, IntegerType y) { return x = +x | y; }
friend T& operator^=(T& x, IntegerType y) { return x = +x ^ y; }
friend T& operator<<=(T& x, IntegerType y) { return x = +x << y; }
friend T& operator>>=(T& x, IntegerType y) { return x = +x >> y; }
// A few binary arithmetic operations not covered by operators base class.
friend IntegerType operator<<(const T& x, IntegerType y) { return +x << y; }
friend IntegerType operator>>(const T& x, IntegerType y) { return +x >> y; }
// Auto-increment and auto-decrement can be defined in terms of the
// arithmetic operations.
friend T& operator++(T& x) { return x += 1; }
friend T& operator--(T& x) { return x -= 1; }
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
friend T operator++(T& x, int)
{
T tmp(x);
x += 1;
return tmp;
}
friend T operator--(T& x, int)
{
T tmp(x);
x -= 1;
return tmp;
}
# endif
# ifndef BOOST_NO_IO_COVER_OPERATORS
// TODO: stream I/O needs to be templatized on the stream type, so will
// work with wide streams, etc.
// Stream input and output.
friend std::ostream& operator<<(std::ostream& s, const T& x)
{ return s << +x; }
friend std::istream& operator>>(std::istream& s, T& x)
{
IntegerType i;
if (s >> i)
x = i;
return s;
}
# endif
};
} // namespace endian
}} // namespace boost::spirit
#endif // BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
@@ -0,0 +1,569 @@
// Boost endian.hpp header file -------------------------------------------------------//
// (C) Copyright Darin Adler 2000
// (C) Copyright Beman Dawes 2006, 2009
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See library home page at http://www.boost.org/libs/endian
//--------------------------------------------------------------------------------------//
// Original design developed by Darin Adler based on classes developed by Mark
// Borgerding. Four original class templates were combined into a single endian
// class template by Beman Dawes, who also added the unrolled_byte_loops sign
// partial specialization to correctly extend the sign when cover integer size
// differs from endian representation size.
// TODO: When a compiler supporting constexpr becomes available, try possible uses.
#ifndef BOOST_SPIRIT_ENDIAN_HPP
#define BOOST_SPIRIT_ENDIAN_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#ifdef BOOST_ENDIAN_LOG
# include <iostream>
#endif
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
# pragma pack(push, 1)
#endif
#include <boost/config.hpp>
#include <boost/detail/endian.hpp>
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#define BOOST_NO_IO_COVER_OPERATORS
#include <boost/spirit/home/support/detail/endian/cover_operators.hpp>
#undef BOOST_NO_IO_COVER_OPERATORS
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
#include <iosfwd>
#include <climits>
# if CHAR_BIT != 8
# error Platforms with CHAR_BIT != 8 are not supported
# endif
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
# if defined(BOOST_ENDIAN_FORCE_PODNESS)
# define BOOST_ENDIAN_NO_CTORS
# endif
namespace boost { namespace spirit
{
namespace detail
{
// Unrolled loops for loading and storing streams of bytes.
template <typename T, std::size_t n_bytes,
bool sign=boost::is_signed<T>::value >
struct unrolled_byte_loops
{
typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
{ return *bytes | (next::load_little(bytes + 1) << 8); }
static void store_big(char* bytes, T value)
{
*(bytes - 1) = static_cast<char>(value);
next::store_big(bytes - 1, value >> 8);
}
static void store_little(char* bytes, T value)
{
*bytes = static_cast<char>(value);
next::store_little(bytes + 1, value >> 8);
}
};
template <typename T>
struct unrolled_byte_loops<T, 1, false>
{
static T load_big(const unsigned char* bytes)
{ return *(bytes - 1); }
static T load_little(const unsigned char* bytes)
{ return *bytes; }
static void store_big(char* bytes, T value)
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value)
{ *bytes = static_cast<char>(value); }
};
template <typename T>
struct unrolled_byte_loops<T, 1, true>
{
static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
{ return *(bytes - 1); }
static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
{ return *bytes; }
static void store_big(char* bytes, T value)
{ *(bytes - 1) = static_cast<char>(value); }
static void store_little(char* bytes, T value)
{ *bytes = static_cast<char>(value); }
};
template <typename T, std::size_t n_bytes>
inline
T load_big_endian(const void* bytes)
{
return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_big
(static_cast<const unsigned char*>(bytes) + n_bytes));
}
template <>
inline
float load_big_endian<float, 4>(const void* bytes)
{
const unsigned char *b = reinterpret_cast<const unsigned char *>(
bytes);
b += 3;
float value;
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
for(std::size_t i = 0; i < 4; ++i)
{
*v++ = *b--;
}
return value;
}
template <>
inline
double load_big_endian<double, 8>(const void* bytes)
{
const unsigned char *b = reinterpret_cast<const unsigned char *>(
bytes);
b += 7;
double value;
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
for(std::size_t i = 0; i < 8; ++i)
{
*v++ = *b--;
}
return value;
}
template <typename T, std::size_t n_bytes>
inline
T load_little_endian(const void* bytes)
{
return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_little
(static_cast<const unsigned char*>(bytes)));
}
template <>
inline
float load_little_endian<float, 4>(const void* bytes)
{
const unsigned char *b = reinterpret_cast<const unsigned char *>(
bytes);
float value;
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
for(std::size_t i = 0; i < 4; ++i)
{
*v++ = *b++;
}
return value;
}
template <>
inline
double load_little_endian<double, 8>(const void* bytes)
{
const unsigned char *b = reinterpret_cast<const unsigned char *>(
bytes);
double value;
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
for(std::size_t i = 0; i < 8; ++i)
{
*v++ = *b++;
}
return value;
}
template <typename T, std::size_t n_bytes>
inline
void store_big_endian(void* bytes, T value)
{
unrolled_byte_loops<T, n_bytes>::store_big
(static_cast<char*>(bytes) + n_bytes, value);
}
template <>
inline
void store_big_endian<float, 4>(void* bytes, float value)
{
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
b += 3;
const unsigned char *v = reinterpret_cast<const unsigned char *>(
&value);
for(std::size_t i = 0; i < 4; ++i)
{
*b-- = *v++;
}
}
template <>
inline
void store_big_endian<double, 8>(void* bytes, double value)
{
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
b += 7;
const unsigned char *v = reinterpret_cast<const unsigned char *>(
&value);
for(std::size_t i = 0; i < 8; ++i)
{
*b-- = *v++;
}
}
template <typename T, std::size_t n_bytes>
inline
void store_little_endian(void* bytes, T value)
{
unrolled_byte_loops<T, n_bytes>::store_little
(static_cast<char*>(bytes), value);
}
template <>
inline
void store_little_endian<float, 4>(void* bytes, float value)
{
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
const unsigned char *v = reinterpret_cast<const unsigned char *>(
&value);
for(std::size_t i = 0; i < 4; ++i)
{
*b++ = *v++;
}
}
template <>
inline
void store_little_endian<double, 8>(void* bytes, double value)
{
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
const unsigned char *v = reinterpret_cast<const unsigned char *>(
&value);
for(std::size_t i = 0; i < 8; ++i)
{
*b++ = *v++;
}
}
} // namespace detail
namespace endian
{
# ifdef BOOST_ENDIAN_LOG
bool endian_log(true);
# endif
// endian class template and specializations ---------------------------------------//
BOOST_SCOPED_ENUM_START(endianness) { big, little, native }; BOOST_SCOPED_ENUM_END
BOOST_SCOPED_ENUM_START(alignment) { unaligned, aligned }; BOOST_SCOPED_ENUM_END
template <BOOST_SCOPED_ENUM(endianness) E, typename T, std::size_t n_bits,
BOOST_SCOPED_ENUM(alignment) A = alignment::unaligned>
class endian;
// Specializations that represent unaligned bytes.
// Taking an integer type as a parameter provides a nice way to pass both
// the size and signedness of the desired integer and get the appropriate
// corresponding integer type for the interface.
// unaligned big endian specialization
template <typename T, std::size_t n_bits>
class endian< endianness::big, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::big, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
explicit endian(T val)
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::clog << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
detail::store_big_endian<T, n_bits/8>(m_value, val);
}
# endif
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::clog << "big, unaligned, " << n_bits << "-bits, convert(" << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
# endif
return detail::load_big_endian<T, n_bits/8>(m_value);
}
private:
char m_value[n_bits/8];
};
// unaligned little endian specialization
template <typename T, std::size_t n_bits>
class endian< endianness::little, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::little, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
explicit endian(T val)
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::clog << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
# endif
detail::store_little_endian<T, n_bits/8>(m_value, val);
}
# endif
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
std::clog << "little, unaligned, " << n_bits << "-bits, convert(" << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
# endif
return detail::load_little_endian<T, n_bits/8>(m_value);
}
private:
char m_value[n_bits/8];
};
// unaligned native endian specialization
template <typename T, std::size_t n_bits>
class endian< endianness::native, T, n_bits, alignment::unaligned >
: cover_operators< endian< endianness::native, T, n_bits >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
public:
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
# ifdef BOOST_BIG_ENDIAN
explicit endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); }
# else
explicit endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
# endif
# endif
# ifdef BOOST_BIG_ENDIAN
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
# else
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(m_value); }
# endif
private:
char m_value[n_bits/8];
};
// Specializations that mimic built-in integer types.
// These typically have the same alignment as the underlying types.
// aligned big endian specialization
template <typename T, std::size_t n_bits>
class endian< endianness::big, T, n_bits, alignment::aligned >
: cover_operators< endian< endianness::big, T, n_bits, alignment::aligned >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
public:
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
# ifdef BOOST_BIG_ENDIAN
endian(T val) : m_value(val) { }
# else
explicit endian(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); }
# endif
# endif
# ifdef BOOST_BIG_ENDIAN
endian & operator=(T val) { m_value = val; return *this; }
operator T() const { return m_value; }
# else
endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const { return detail::load_big_endian<T, sizeof(T)>(&m_value); }
# endif
private:
T m_value;
};
// aligned little endian specialization
template <typename T, std::size_t n_bits>
class endian< endianness::little, T, n_bits, alignment::aligned >
: cover_operators< endian< endianness::little, T, n_bits, alignment::aligned >, T >
{
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
public:
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
# ifdef BOOST_LITTLE_ENDIAN
endian(T val) : m_value(val) { }
# else
explicit endian(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); }
# endif
# endif
# ifdef BOOST_LITTLE_ENDIAN
endian & operator=(T val) { m_value = val; return *this; }
operator T() const { return m_value; }
#else
endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const { return detail::load_little_endian<T, sizeof(T)>(&m_value); }
#endif
private:
T m_value;
};
// naming convention typedefs ------------------------------------------------------//
// unaligned big endian signed integer types
typedef endian< endianness::big, int_least8_t, 8 > big8_t;
typedef endian< endianness::big, int_least16_t, 16 > big16_t;
typedef endian< endianness::big, int_least32_t, 24 > big24_t;
typedef endian< endianness::big, int_least32_t, 32 > big32_t;
typedef endian< endianness::big, int_least64_t, 40 > big40_t;
typedef endian< endianness::big, int_least64_t, 48 > big48_t;
typedef endian< endianness::big, int_least64_t, 56 > big56_t;
typedef endian< endianness::big, int_least64_t, 64 > big64_t;
// unaligned big endian unsigned integer types
typedef endian< endianness::big, uint_least8_t, 8 > ubig8_t;
typedef endian< endianness::big, uint_least16_t, 16 > ubig16_t;
typedef endian< endianness::big, uint_least32_t, 24 > ubig24_t;
typedef endian< endianness::big, uint_least32_t, 32 > ubig32_t;
typedef endian< endianness::big, uint_least64_t, 40 > ubig40_t;
typedef endian< endianness::big, uint_least64_t, 48 > ubig48_t;
typedef endian< endianness::big, uint_least64_t, 56 > ubig56_t;
typedef endian< endianness::big, uint_least64_t, 64 > ubig64_t;
// unaligned little endian signed integer types
typedef endian< endianness::little, int_least8_t, 8 > little8_t;
typedef endian< endianness::little, int_least16_t, 16 > little16_t;
typedef endian< endianness::little, int_least32_t, 24 > little24_t;
typedef endian< endianness::little, int_least32_t, 32 > little32_t;
typedef endian< endianness::little, int_least64_t, 40 > little40_t;
typedef endian< endianness::little, int_least64_t, 48 > little48_t;
typedef endian< endianness::little, int_least64_t, 56 > little56_t;
typedef endian< endianness::little, int_least64_t, 64 > little64_t;
// unaligned little endian unsigned integer types
typedef endian< endianness::little, uint_least8_t, 8 > ulittle8_t;
typedef endian< endianness::little, uint_least16_t, 16 > ulittle16_t;
typedef endian< endianness::little, uint_least32_t, 24 > ulittle24_t;
typedef endian< endianness::little, uint_least32_t, 32 > ulittle32_t;
typedef endian< endianness::little, uint_least64_t, 40 > ulittle40_t;
typedef endian< endianness::little, uint_least64_t, 48 > ulittle48_t;
typedef endian< endianness::little, uint_least64_t, 56 > ulittle56_t;
typedef endian< endianness::little, uint_least64_t, 64 > ulittle64_t;
// unaligned native endian signed integer types
typedef endian< endianness::native, int_least8_t, 8 > native8_t;
typedef endian< endianness::native, int_least16_t, 16 > native16_t;
typedef endian< endianness::native, int_least32_t, 24 > native24_t;
typedef endian< endianness::native, int_least32_t, 32 > native32_t;
typedef endian< endianness::native, int_least64_t, 40 > native40_t;
typedef endian< endianness::native, int_least64_t, 48 > native48_t;
typedef endian< endianness::native, int_least64_t, 56 > native56_t;
typedef endian< endianness::native, int_least64_t, 64 > native64_t;
// unaligned native endian unsigned integer types
typedef endian< endianness::native, uint_least8_t, 8 > unative8_t;
typedef endian< endianness::native, uint_least16_t, 16 > unative16_t;
typedef endian< endianness::native, uint_least32_t, 24 > unative24_t;
typedef endian< endianness::native, uint_least32_t, 32 > unative32_t;
typedef endian< endianness::native, uint_least64_t, 40 > unative40_t;
typedef endian< endianness::native, uint_least64_t, 48 > unative48_t;
typedef endian< endianness::native, uint_least64_t, 56 > unative56_t;
typedef endian< endianness::native, uint_least64_t, 64 > unative64_t;
#define BOOST_HAS_INT16_T
#define BOOST_HAS_INT32_T
#define BOOST_HAS_INT64_T
// These types only present if platform has exact size integers:
// aligned big endian signed integer types
// aligned big endian unsigned integer types
// aligned little endian signed integer types
// aligned little endian unsigned integer types
// aligned native endian typedefs are not provided because
// <cstdint> types are superior for this use case
# if defined(BOOST_HAS_INT16_T)
typedef endian< endianness::big, int16_t, 16, alignment::aligned > aligned_big16_t;
typedef endian< endianness::big, uint16_t, 16, alignment::aligned > aligned_ubig16_t;
typedef endian< endianness::little, int16_t, 16, alignment::aligned > aligned_little16_t;
typedef endian< endianness::little, uint16_t, 16, alignment::aligned > aligned_ulittle16_t;
# endif
# if defined(BOOST_HAS_INT32_T)
typedef endian< endianness::big, int32_t, 32, alignment::aligned > aligned_big32_t;
typedef endian< endianness::big, uint32_t, 32, alignment::aligned > aligned_ubig32_t;
typedef endian< endianness::little, int32_t, 32, alignment::aligned > aligned_little32_t;
typedef endian< endianness::little, uint32_t, 32, alignment::aligned > aligned_ulittle32_t;
# endif
# if defined(BOOST_HAS_INT64_T)
typedef endian< endianness::big, int64_t, 64, alignment::aligned > aligned_big64_t;
typedef endian< endianness::big, uint64_t, 64, alignment::aligned > aligned_ubig64_t;
typedef endian< endianness::little, int64_t, 64, alignment::aligned > aligned_little64_t;
typedef endian< endianness::little, uint64_t, 64, alignment::aligned > aligned_ulittle64_t;
# endif
} // namespace endian
}} // namespace boost::spirit
// import the namespace above into boost::endian
namespace boost { namespace endian
{
using namespace boost::spirit::endian;
}}
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
# pragma pack(pop)
#endif
#endif // BOOST_SPIRIT_ENDIAN_HPP
@@ -0,0 +1,75 @@
// 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_GET_ENCODING_JANUARY_13_2009_1255PM)
#define BOOST_SPIRIT_GET_ENCODING_JANUARY_13_2009_1255PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace detail
{
template <typename Modifiers, typename Encoding>
struct get_implicit_encoding
{
// Extract the implicit encoding from the Modifiers
// If one is not found, Encoding is used. The explicit
// encoding is the first viable encoding that can be
// extracted from the Modifiers (there can be more than one).
typedef typename
mpl::find_if<
char_encodings,
has_modifier<Modifiers, tag::char_encoding_base<mpl::_1> >
>::type
iter;
typedef typename
mpl::eval_if<
is_same<iter, typename mpl::end<char_encodings>::type>,
mpl::identity<Encoding>,
mpl::deref<iter>
>::type
type;
};
template <typename Modifiers, typename Encoding>
struct get_encoding
{
// Extract the explicit encoding from the Modifiers
// If one is not found, get implicit encoding (see above).
// Explicit encoding is the encoding explicitly declared
// using the encoding[c] directive.
typedef typename
mpl::find_if<
char_encodings,
has_modifier<Modifiers, tag::char_code<tag::encoding, mpl::_1> >
>::type
iter;
typedef typename
mpl::eval_if<
is_same<iter, typename mpl::end<char_encodings>::type>,
get_implicit_encoding<Modifiers, Encoding>,
mpl::deref<iter>
>::type
type;
};
template <typename Modifiers, typename Encoding, bool case_modifier = false>
struct get_encoding_with_case : mpl::identity<Encoding> {};
template <typename Modifiers, typename Encoding>
struct get_encoding_with_case<Modifiers, Encoding, true>
: get_encoding<Modifiers, Encoding> {};
}}}
#endif
@@ -0,0 +1,457 @@
/*=============================================================================
Copyright (c) 2007-2011 Hartmut Kaiser
Copyright (c) Christopher Diggins 2005
Copyright (c) Pablo Aguilar 2005
Copyright (c) Kevlin Henney 2001
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
The class boost::spirit::hold_any is built based on the any class
published here: http://www.codeproject.com/cpp/dynamic_typing.asp. It adds
support for std streaming operator<<() and operator>>().
==============================================================================*/
#if !defined(BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM)
#define BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/assert.hpp>
#include <boost/detail/sp_typeinfo.hpp>
#include <stdexcept>
#include <typeinfo>
#include <algorithm>
#include <iosfwd>
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4100) // 'x': unreferenced formal parameter
# pragma warning(disable: 4127) // conditional expression is constant
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
struct bad_any_cast
: std::bad_cast
{
bad_any_cast(boost::detail::sp_typeinfo const& src, boost::detail::sp_typeinfo const& dest)
: from(src.name()), to(dest.name())
{}
virtual const char* what() const throw() { return "bad any cast"; }
const char* from;
const char* to;
};
namespace detail
{
// function pointer table
template <typename Char>
struct fxn_ptr_table
{
boost::detail::sp_typeinfo const& (*get_type)();
void (*static_delete)(void**);
void (*destruct)(void**);
void (*clone)(void* const*, void**);
void (*move)(void* const*, void**);
std::basic_istream<Char>& (*stream_in)(std::basic_istream<Char>&, void**);
std::basic_ostream<Char>& (*stream_out)(std::basic_ostream<Char>&, void* const*);
};
// static functions for small value-types
template <typename Small>
struct fxns;
template <>
struct fxns<mpl::true_>
{
template<typename T, typename Char>
struct type
{
static boost::detail::sp_typeinfo const& get_type()
{
return BOOST_SP_TYPEID(T);
}
static void static_delete(void** x)
{
reinterpret_cast<T*>(x)->~T();
}
static void destruct(void** x)
{
reinterpret_cast<T*>(x)->~T();
}
static void clone(void* const* src, void** dest)
{
new (dest) T(*reinterpret_cast<T const*>(src));
}
static void move(void* const* src, void** dest)
{
*reinterpret_cast<T*>(dest) =
*reinterpret_cast<T const*>(src);
}
static std::basic_istream<Char>&
stream_in (std::basic_istream<Char>& i, void** obj)
{
i >> *reinterpret_cast<T*>(obj);
return i;
}
static std::basic_ostream<Char>&
stream_out(std::basic_ostream<Char>& o, void* const* obj)
{
o << *reinterpret_cast<T const*>(obj);
return o;
}
};
};
// static functions for big value-types (bigger than a void*)
template <>
struct fxns<mpl::false_>
{
template<typename T, typename Char>
struct type
{
static boost::detail::sp_typeinfo const& get_type()
{
return BOOST_SP_TYPEID(T);
}
static void static_delete(void** x)
{
// destruct and free memory
delete (*reinterpret_cast<T**>(x));
}
static void destruct(void** x)
{
// destruct only, we'll reuse memory
(*reinterpret_cast<T**>(x))->~T();
}
static void clone(void* const* src, void** dest)
{
*dest = new T(**reinterpret_cast<T* const*>(src));
}
static void move(void* const* src, void** dest)
{
**reinterpret_cast<T**>(dest) =
**reinterpret_cast<T* const*>(src);
}
static std::basic_istream<Char>&
stream_in(std::basic_istream<Char>& i, void** obj)
{
i >> **reinterpret_cast<T**>(obj);
return i;
}
static std::basic_ostream<Char>&
stream_out(std::basic_ostream<Char>& o, void* const* obj)
{
o << **reinterpret_cast<T* const*>(obj);
return o;
}
};
};
template <typename T>
struct get_table
{
typedef mpl::bool_<(sizeof(T) <= sizeof(void*))> is_small;
template <typename Char>
static fxn_ptr_table<Char>* get()
{
static fxn_ptr_table<Char> static_table =
{
fxns<is_small>::template type<T, Char>::get_type,
fxns<is_small>::template type<T, Char>::static_delete,
fxns<is_small>::template type<T, Char>::destruct,
fxns<is_small>::template type<T, Char>::clone,
fxns<is_small>::template type<T, Char>::move,
fxns<is_small>::template type<T, Char>::stream_in,
fxns<is_small>::template type<T, Char>::stream_out
};
return &static_table;
}
};
///////////////////////////////////////////////////////////////////////
struct empty {};
template <typename Char>
inline std::basic_istream<Char>&
operator>> (std::basic_istream<Char>& i, empty&)
{
// If this assertion fires you tried to insert from a std istream
// into an empty hold_any instance. This simply can't work, because
// there is no way to figure out what type to extract from the
// stream.
// The only way to make this work is to assign an arbitrary
// value of the required type to the hold_any instance you want to
// stream to. This assignment has to be executed before the actual
// call to the operator>>().
BOOST_ASSERT(false &&
"Tried to insert from a std istream into an empty "
"hold_any instance");
return i;
}
template <typename Char>
inline std::basic_ostream<Char>&
operator<< (std::basic_ostream<Char>& o, empty const&)
{
return o;
}
}
///////////////////////////////////////////////////////////////////////////
template <typename Char>
class basic_hold_any
{
public:
// constructors
template <typename T>
explicit basic_hold_any(T const& x)
: table(spirit::detail::get_table<T>::template get<Char>()), object(0)
{
if (spirit::detail::get_table<T>::is_small::value)
new (&object) T(x);
else
object = new T(x);
}
basic_hold_any()
: table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
object(0)
{
}
basic_hold_any(basic_hold_any const& x)
: table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
object(0)
{
assign(x);
}
~basic_hold_any()
{
table->static_delete(&object);
}
// assignment
basic_hold_any& assign(basic_hold_any const& x)
{
if (&x != this) {
// are we copying between the same type?
if (table == x.table) {
// if so, we can avoid reallocation
table->move(&x.object, &object);
}
else {
reset();
x.table->clone(&x.object, &object);
table = x.table;
}
}
return *this;
}
template <typename T>
basic_hold_any& assign(T const& x)
{
// are we copying between the same type?
spirit::detail::fxn_ptr_table<Char>* x_table =
spirit::detail::get_table<T>::template get<Char>();
if (table == x_table) {
// if so, we can avoid deallocating and re-use memory
table->destruct(&object); // first destruct the old content
if (spirit::detail::get_table<T>::is_small::value) {
// create copy on-top of object pointer itself
new (&object) T(x);
}
else {
// create copy on-top of old version
new (object) T(x);
}
}
else {
if (spirit::detail::get_table<T>::is_small::value) {
// create copy on-top of object pointer itself
table->destruct(&object); // first destruct the old content
new (&object) T(x);
}
else {
reset(); // first delete the old content
object = new T(x);
}
table = x_table; // update table pointer
}
return *this;
}
// assignment operator
#ifdef BOOST_HAS_RVALUE_REFS
template <typename T>
basic_hold_any& operator=(T&& x)
{
return assign(std::forward<T>(x));
}
#else
template <typename T>
basic_hold_any& operator=(T& x)
{
return assign(x);
}
template <typename T>
basic_hold_any& operator=(T const& x)
{
return assign(x);
}
#endif
// utility functions
basic_hold_any& swap(basic_hold_any& x)
{
std::swap(table, x.table);
std::swap(object, x.object);
return *this;
}
boost::detail::sp_typeinfo const& type() const
{
return table->get_type();
}
template <typename T>
T const& cast() const
{
if (type() != BOOST_SP_TYPEID(T))
throw bad_any_cast(type(), BOOST_SP_TYPEID(T));
return spirit::detail::get_table<T>::is_small::value ?
*reinterpret_cast<T const*>(&object) :
*reinterpret_cast<T const*>(object);
}
// implicit casting is disabled by default for compatibility with boost::any
#ifdef BOOST_SPIRIT_ANY_IMPLICIT_CASTING
// automatic casting operator
template <typename T>
operator T const& () const { return cast<T>(); }
#endif // implicit casting
bool empty() const
{
return table == spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
}
void reset()
{
if (!empty())
{
table->static_delete(&object);
table = spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
object = 0;
}
}
// these functions have been added in the assumption that the embedded
// type has a corresponding operator defined, which is completely safe
// because spirit::hold_any is used only in contexts where these operators
// do exist
template <typename Char_>
friend inline std::basic_istream<Char_>&
operator>> (std::basic_istream<Char_>& i, basic_hold_any<Char_>& obj)
{
return obj.table->stream_in(i, &obj.object);
}
template <typename Char_>
friend inline std::basic_ostream<Char_>&
operator<< (std::basic_ostream<Char_>& o, basic_hold_any<Char_> const& obj)
{
return obj.table->stream_out(o, &obj.object);
}
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private: // types
template <typename T, typename Char_>
friend T* any_cast(basic_hold_any<Char_> *);
#else
public: // types (public so any_cast can be non-friend)
#endif
// fields
spirit::detail::fxn_ptr_table<Char>* table;
void* object;
};
// boost::any-like casting
template <typename T, typename Char>
inline T* any_cast (basic_hold_any<Char>* operand)
{
if (operand && operand->type() == BOOST_SP_TYPEID(T)) {
return spirit::detail::get_table<T>::is_small::value ?
reinterpret_cast<T*>(&operand->object) :
reinterpret_cast<T*>(operand->object);
}
return 0;
}
template <typename T, typename Char>
inline T const* any_cast(basic_hold_any<Char> const* operand)
{
return any_cast<T>(const_cast<basic_hold_any<Char>*>(operand));
}
template <typename T, typename Char>
T any_cast(basic_hold_any<Char>& operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
nonref* result = any_cast<nonref>(&operand);
if(!result)
boost::throw_exception(bad_any_cast(operand.type(), BOOST_SP_TYPEID(T)));
return *result;
}
template <typename T, typename Char>
T const& any_cast(basic_hold_any<Char> const& operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
return any_cast<nonref const&>(const_cast<basic_hold_any<Char> &>(operand));
}
///////////////////////////////////////////////////////////////////////////////
// backwards compatibility
typedef basic_hold_any<char> hold_any;
typedef basic_hold_any<wchar_t> whold_any;
namespace traits
{
template <typename T>
struct is_hold_any : mpl::false_ {};
template <typename Char>
struct is_hold_any<basic_hold_any<Char> > : mpl::true_ {};
}
}} // namespace boost::spirit
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#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_SUPPORT_DETAIL_IS_SPIRIT_TAG_MAR_28_2011_0341PM)
#define BOOST_SPIRIT_SUPPORT_DETAIL_IS_SPIRIT_TAG_MAR_28_2011_0341PM
#if defined(_MSC_VER)
#pragma once
#endif
#define BOOST_SPIRIT_IS_TAG() typedef void is_spirit_tag;
#endif
@@ -0,0 +1,54 @@
// char_traits.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_CHAR_TRAITS_H
#define BOOST_LEXER_CHAR_TRAITS_H
// Make sure wchar_t is defined
#include <string>
namespace boost
{
namespace lexer
{
template<typename CharT>
struct char_traits
{
typedef CharT char_type;
typedef CharT index_type;
static index_type call (CharT ch)
{
return ch;
}
};
template<>
struct char_traits<char>
{
typedef char char_type;
typedef unsigned char index_type;
static index_type call (char ch)
{
return static_cast<index_type>(ch);
}
};
template<>
struct char_traits<wchar_t>
{
typedef wchar_t char_type;
typedef wchar_t index_type;
static index_type call (wchar_t ch)
{
return ch;
}
};
}
}
#endif
@@ -0,0 +1,39 @@
// consts.h
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_CONSTS_H
#define BOOST_LEXER_CONSTS_H
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#include "size_t.hpp"
namespace boost
{
namespace lexer
{
enum regex_flags {none = 0, icase = 1, dot_not_newline = 2};
// 0 = end state, 1 = id, 2 = unique_id, 3 = lex state, 4 = bol, 5 = eol,
// 6 = dead_state_index
enum {end_state_index, id_index, unique_id_index, state_index, bol_index,
eol_index, dead_state_index, dfa_offset};
const std::size_t max_macro_len = 30;
const std::size_t num_chars = 256;
// If sizeof(wchar_t) == sizeof(size_t) then don't overflow to 0
// by adding one to comparison.
const std::size_t num_wchar_ts =
(boost::integer_traits<wchar_t>::const_max < 0x110000) ?
boost::integer_traits<wchar_t>::const_max +
static_cast<std::size_t> (1) : 0x110000;
const std::size_t null_token = static_cast<std::size_t> (~0);
const std::size_t bol_token = static_cast<std::size_t> (~1);
const std::size_t eol_token = static_cast<std::size_t> (~2);
const std::size_t end_state = 1;
const std::size_t npos = static_cast<std::size_t> (~0);
}
}
#endif
@@ -0,0 +1,71 @@
// ptr_list.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_PTR_LIST_HPP
#define BOOST_LEXER_PTR_LIST_HPP
#include <list>
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename Type>
class ptr_list
{
public:
typedef std::list<Type *> list;
ptr_list ()
{
}
~ptr_list ()
{
clear ();
}
list *operator -> ()
{
return &_list;
}
const list *operator -> () const
{
return &_list;
}
list &operator * ()
{
return _list;
}
const list &operator * () const
{
return _list;
}
void clear ()
{
while (!_list.empty ())
{
delete _list.front ();
_list.pop_front ();
}
}
private:
list _list;
ptr_list (const ptr_list &); // No copy construction.
ptr_list &operator = (const ptr_list &); // No assignment.
};
}
}
}
#endif
@@ -0,0 +1,108 @@
// ptr_vector.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_PTR_VECTOR_HPP
#define BOOST_LEXER_PTR_VECTOR_HPP
#include "../size_t.hpp"
#include <vector>
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename Type>
class ptr_vector
{
public:
typedef std::vector<Type *> vector;
ptr_vector ()
{
}
~ptr_vector ()
{
clear ();
}
vector *operator -> ()
{
return &_vector;
}
const vector *operator -> () const
{
return &_vector;
}
vector &operator * ()
{
return _vector;
}
const vector &operator * () const
{
return _vector;
}
Type * &operator [] (const std::size_t index_)
{
return _vector[index_];
}
Type * const &operator [] (const std::size_t index_) const
{
return _vector[index_];
}
bool operator == (const ptr_vector &rhs_) const
{
bool equal_ = _vector.size () == rhs_._vector.size ();
if (equal_)
{
typename vector::const_iterator lhs_iter_ = _vector.begin ();
typename vector::const_iterator end_ = _vector.end ();
typename vector::const_iterator rhs_iter_ = rhs_._vector.begin ();
for (; equal_ && lhs_iter_ != end_; ++lhs_iter_, ++rhs_iter_)
{
equal_ = **lhs_iter_ == **rhs_iter_;
}
}
return equal_;
}
void clear ()
{
if (!_vector.empty ())
{
Type **iter_ = &_vector.front ();
Type **end_ = iter_ + _vector.size ();
for (; iter_ != end_; ++iter_)
{
delete *iter_;
}
}
_vector.clear ();
}
private:
vector _vector;
ptr_vector (const ptr_vector &); // No copy construction.
ptr_vector &operator = (const ptr_vector &); // No assignment.
};
}
}
}
#endif
@@ -0,0 +1,77 @@
// char_state_machine.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_CHAR_STATE_MACHINE_HPP
#define BOOST_LEXER_CHAR_STATE_MACHINE_HPP
#include "../consts.hpp"
#include <map>
#include "../size_t.hpp"
#include "../string_token.hpp"
#include <vector>
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
struct basic_char_state_machine
{
struct state
{
typedef basic_string_token<CharT> string_token;
typedef std::map<std::size_t, string_token> size_t_string_token_map;
typedef std::pair<std::size_t, string_token> size_t_string_token_pair;
bool _end_state;
std::size_t _id;
std::size_t _unique_id;
std::size_t _state;
std::size_t _bol_index;
std::size_t _eol_index;
size_t_string_token_map _transitions;
state () :
_end_state (false),
_id (0),
_unique_id (npos),
_state (0),
_bol_index (npos),
_eol_index (npos)
{
}
};
typedef std::vector<state> state_vector;
typedef std::vector<state_vector> state_vector_vector;
state_vector_vector _sm_vector;
bool empty () const
{
return _sm_vector.empty ();
}
void clear ()
{
_sm_vector.clear ();
}
void swap (basic_char_state_machine &csm_)
{
_sm_vector.swap (csm_._sm_vector);
}
};
typedef basic_char_state_machine<char> char_state_machine;
typedef basic_char_state_machine<wchar_t> wchar_state_machine;
}
}
}
#endif
@@ -0,0 +1,281 @@
// debug.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_DEBUG_HPP
#define BOOST_LEXER_DEBUG_HPP
#include <map>
#include <ostream>
#include "rules.hpp"
#include "size_t.hpp"
#include "state_machine.hpp"
#include "string_token.hpp"
#include <vector>
namespace boost
{
namespace lexer
{
template<typename CharT>
class basic_debug
{
public:
typedef std::basic_ostream<CharT> ostream;
typedef std::basic_string<CharT> string;
typedef std::vector<std::size_t> size_t_vector;
static void escape_control_chars (const string &in_, string &out_)
{
const CharT *ptr_ = in_.c_str ();
std::size_t size_ = in_.size ();
out_.clear ();
while (size_)
{
basic_string_token<CharT>::escape_char (*ptr_, out_);
++ptr_;
--size_;
}
}
static void dump (const basic_state_machine<CharT> &state_machine_,
basic_rules<CharT> &rules_, ostream &stream_)
{
typename basic_state_machine<CharT>::iterator iter_ =
state_machine_.begin ();
typename basic_state_machine<CharT>::iterator end_ =
state_machine_.end ();
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
dfa_ < dfas_; ++dfa_)
{
lexer_state (stream_);
stream_ << rules_.state (dfa_) << std::endl << std::endl;
dump_ex (iter_, stream_);
}
}
static void dump (const basic_state_machine<CharT> &state_machine_,
ostream &stream_)
{
typename basic_state_machine<CharT>::iterator iter_ =
state_machine_.begin ();
typename basic_state_machine<CharT>::iterator end_ =
state_machine_.end ();
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
dfa_ < dfas_; ++dfa_)
{
lexer_state (stream_);
stream_ << dfa_ << std::endl << std::endl;
dump_ex (iter_, stream_);
}
}
protected:
typedef std::basic_stringstream<CharT> stringstream;
static void dump_ex (typename basic_state_machine<CharT>::iterator &iter_,
ostream &stream_)
{
const std::size_t states_ = iter_->states;
for (std::size_t i_ = 0; i_ < states_; ++i_)
{
state (stream_);
stream_ << i_ << std::endl;
if (iter_->end_state)
{
end_state (stream_);
stream_ << iter_->id;
unique_id (stream_);
stream_ << iter_->unique_id;
dfa (stream_);
stream_ << iter_->goto_dfa;
stream_ << std::endl;
}
if (iter_->bol_index != npos)
{
bol (stream_);
stream_ << iter_->bol_index << std::endl;
}
if (iter_->eol_index != npos)
{
eol (stream_);
stream_ << iter_->eol_index << std::endl;
}
const std::size_t transitions_ = iter_->transitions;
if (transitions_ == 0)
{
++iter_;
}
for (std::size_t t_ = 0; t_ < transitions_; ++t_)
{
std::size_t goto_state_ = iter_->goto_state;
if (iter_->token.any ())
{
any (stream_);
}
else
{
open_bracket (stream_);
if (iter_->token._negated)
{
negated (stream_);
}
string charset_;
CharT c_ = 0;
escape_control_chars (iter_->token._charset,
charset_);
c_ = *charset_.c_str ();
if (!iter_->token._negated &&
(c_ == '^' || c_ == ']'))
{
stream_ << '\\';
}
stream_ << charset_;
close_bracket (stream_);
}
stream_ << goto_state_ << std::endl;
++iter_;
}
stream_ << std::endl;
}
}
static void lexer_state (std::ostream &stream_)
{
stream_ << "Lexer state: ";
}
static void lexer_state (std::wostream &stream_)
{
stream_ << L"Lexer state: ";
}
static void state (std::ostream &stream_)
{
stream_ << "State: ";
}
static void state (std::wostream &stream_)
{
stream_ << L"State: ";
}
static void bol (std::ostream &stream_)
{
stream_ << " BOL -> ";
}
static void bol (std::wostream &stream_)
{
stream_ << L" BOL -> ";
}
static void eol (std::ostream &stream_)
{
stream_ << " EOL -> ";
}
static void eol (std::wostream &stream_)
{
stream_ << L" EOL -> ";
}
static void end_state (std::ostream &stream_)
{
stream_ << " END STATE, Id = ";
}
static void end_state (std::wostream &stream_)
{
stream_ << L" END STATE, Id = ";
}
static void unique_id (std::ostream &stream_)
{
stream_ << ", Unique Id = ";
}
static void unique_id (std::wostream &stream_)
{
stream_ << L", Unique Id = ";
}
static void any (std::ostream &stream_)
{
stream_ << " . -> ";
}
static void any (std::wostream &stream_)
{
stream_ << L" . -> ";
}
static void open_bracket (std::ostream &stream_)
{
stream_ << " [";
}
static void open_bracket (std::wostream &stream_)
{
stream_ << L" [";
}
static void negated (std::ostream &stream_)
{
stream_ << "^";
}
static void negated (std::wostream &stream_)
{
stream_ << L"^";
}
static void close_bracket (std::ostream &stream_)
{
stream_ << "] -> ";
}
static void close_bracket (std::wostream &stream_)
{
stream_ << L"] -> ";
}
static void dfa (std::ostream &stream_)
{
stream_ << ", dfa = ";
}
static void dfa (std::wostream &stream_)
{
stream_ << L", dfa = ";
}
};
typedef basic_debug<char> debug;
typedef basic_debug<wchar_t> wdebug;
}
}
#endif
@@ -0,0 +1,475 @@
// file_input.hpp
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_FILE_INPUT
#define BOOST_LEXER_FILE_INPUT
#include "char_traits.hpp"
// memcpy
#include <cstring>
#include <fstream>
#include "size_t.hpp"
#include "state_machine.hpp"
namespace boost
{
namespace lexer
{
template<typename CharT, typename Traits = char_traits<CharT> >
class basic_file_input
{
public:
class iterator
{
public:
friend class basic_file_input;
struct data
{
std::size_t id;
std::size_t unique_id;
const CharT *start;
const CharT *end;
std::size_t state;
// Construct in end() state.
data () :
id (0),
unique_id (npos),
state (npos)
{
}
bool operator == (const data &rhs_) const
{
return id == rhs_.id && unique_id == rhs_.unique_id &&
start == rhs_.start && end == rhs_.end &&
state == rhs_.state;
}
};
iterator () :
_input (0)
{
}
bool operator == (const iterator &rhs_) const
{
return _data == rhs_._data;
}
bool operator != (const iterator &rhs_) const
{
return !(*this == rhs_);
}
data &operator * ()
{
return _data;
}
data *operator -> ()
{
return &_data;
}
// Let compiler generate operator = ().
// prefix version
iterator &operator ++ ()
{
next_token ();
return *this;
}
// postfix version
iterator operator ++ (int)
{
iterator iter_ = *this;
next_token ();
return iter_;
}
void next_token ()
{
const detail::internals &internals_ =
_input->_state_machine->data ();
_data.start = _data.end;
if (internals_._dfa->size () == 1)
{
_data.id = _input->next (&internals_._lookup->front ()->
front (), internals_._dfa_alphabet.front (),
&internals_._dfa->front ()->front (), _data.start,
_data.end, _data.unique_id);
}
else
{
_data.id = _input->next (internals_, _data.state, _data.start,
_data.end, _data.unique_id);
}
if (_data.id == 0)
{
_data.start = 0;
_data.end = 0;
// Ensure current state matches that returned by end().
_data.state = npos;
}
}
private:
// Not owner (obviously!)
basic_file_input *_input;
data _data;
};
friend class iterator;
// Make it explict that we are NOT taking a copy of state_machine_!
basic_file_input (const basic_state_machine<CharT> *state_machine_,
std::basic_ifstream<CharT> *is_,
const std::streamsize buffer_size_ = 4096,
const std::streamsize buffer_increment_ = 1024) :
_state_machine (state_machine_),
_stream (is_),
_buffer_size (buffer_size_),
_buffer_increment (buffer_increment_),
_buffer (_buffer_size, '!')
{
_start_buffer = &_buffer.front ();
_end_buffer = _start_buffer + _buffer.size ();
_start_token = _end_buffer;
_end_token = _end_buffer;
}
iterator begin ()
{
iterator iter_;
iter_._input = this;
// Over-ride default of 0 (EOF)
iter_._data.id = npos;
iter_._data.start = 0;
iter_._data.end = 0;
iter_._data.state = 0;
++iter_;
return iter_;
}
iterator end ()
{
iterator iter_;
iter_._input = this;
iter_._data.start = 0;
iter_._data.end = 0;
return iter_;
}
void flush ()
{
// This temporary is mandatory, otherwise the
// pointer calculations won't work!
const CharT *temp_ = _end_buffer;
_start_token = _end_token = _end_buffer;
reload_buffer (temp_, true, _end_token);
}
private:
typedef std::basic_istream<CharT> istream;
typedef std::vector<CharT> buffer;
const basic_state_machine<CharT> *_state_machine;
const std::streamsize _buffer_size;
const std::streamsize _buffer_increment;
buffer _buffer;
CharT *_start_buffer;
istream *_stream;
const CharT *_start_token;
const CharT *_end_token;
CharT *_end_buffer;
std::size_t next (const detail::internals &internals_,
std::size_t &start_state_, const CharT * &start_, const CharT * &end_,
std::size_t &unique_id_)
{
_start_token = _end_token;
again:
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
front ();
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
const CharT *curr_ = _start_token;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
const CharT *end_token_ = curr_;
for (;;)
{
if (curr_ >= _end_buffer)
{
if (!reload_buffer (curr_, end_state_, end_token_))
{
// EOF
break;
}
}
const std::size_t BOL_state_ = ptr_[bol_index];
const std::size_t EOL_state_ = ptr_[eol_index];
if (BOL_state_ && (_start_token == _start_buffer ||
*(_start_token - 1) == '\n'))
{
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
}
else if (EOL_state_ && *curr_ == '\n')
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
}
else
{
const std::size_t state_ =
ptr_[lookup_[static_cast<typename Traits::index_type>
(*curr_++)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
}
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
start_state_ = *(ptr_ + state_index);
end_token_ = curr_;
}
}
if (_start_token >= _end_buffer)
{
// No more tokens...
unique_id_ = npos;
return 0;
}
const std::size_t EOL_state_ = ptr_[eol_index];
if (EOL_state_ && curr_ == end_)
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
start_state_ = *(ptr_ + state_index);
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
_end_token = end_token_;
if (id_ == 0) goto again;
}
else
{
// No match causes char to be skipped
_end_token = _start_token + 1;
id_ = npos;
uid_ = npos;
}
start_ = _start_token;
end_ = _end_token;
unique_id_ = uid_;
return id_;
}
std::size_t next (const std::size_t * const lookup_,
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
const CharT * &start_, const CharT * &end_, std::size_t &unique_id_)
{
_start_token = _end_token;
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
const CharT *curr_ = _start_token;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
const CharT *end_token_ = curr_;
for (;;)
{
if (curr_ >= _end_buffer)
{
if (!reload_buffer (curr_, end_state_, end_token_))
{
// EOF
break;
}
}
const std::size_t BOL_state_ = ptr_[bol_index];
const std::size_t EOL_state_ = ptr_[eol_index];
if (BOL_state_ && (_start_token == _start_buffer ||
*(_start_token - 1) == '\n'))
{
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
}
else if (EOL_state_ && *curr_ == '\n')
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
}
else
{
const std::size_t state_ =
ptr_[lookup_[static_cast<typename Traits::index_type>
(*curr_++)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
}
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_token_ = curr_;
}
}
if (_start_token >= _end_buffer)
{
// No more tokens...
unique_id_ = npos;
return 0;
}
const std::size_t EOL_state_ = ptr_[eol_index];
if (EOL_state_ && curr_ == end_)
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
_end_token = end_token_;
}
else
{
// No match causes char to be skipped
_end_token = _start_token + 1;
id_ = npos;
uid_ = npos;
}
start_ = _start_token;
end_ = _end_token;
unique_id_ = uid_;
return id_;
}
bool reload_buffer (const CharT * &curr_, const bool end_state_,
const CharT * &end_token_)
{
bool success_ = !_stream->eof ();
if (success_)
{
const CharT *old_start_token_ = _start_token;
std::size_t old_size_ = _buffer.size ();
std::size_t count_ = 0;
if (_start_token - 1 == _start_buffer)
{
// Run out of buffer space, so increase.
_buffer.resize (old_size_ + _buffer_increment, '!');
_start_buffer = &_buffer.front ();
_start_token = _start_buffer + 1;
_stream->read (_start_buffer + old_size_,
_buffer_increment);
count_ = _stream->gcount ();
_end_buffer = _start_buffer + old_size_ + count_;
}
else if (_start_token < _end_buffer)
{
const std::size_t len_ = _end_buffer - _start_token;
// Some systems have memcpy in namespace std.
using namespace std;
memcpy (_start_buffer, _start_token - 1, (len_ + 1) *
sizeof (CharT));
_stream->read (_start_buffer + len_ + 1,
static_cast<std::streamsize> (_buffer.size () - len_ - 1));
count_ = _stream->gcount ();
_start_token = _start_buffer + 1;
_end_buffer = _start_buffer + len_ + 1 + count_;
}
else
{
_stream->read (_start_buffer, static_cast<std::streamsize>
(_buffer.size ()));
count_ = _stream->gcount ();
_start_token = _start_buffer;
_end_buffer = _start_buffer + count_;
}
if (end_state_)
{
end_token_ = _start_token +
(end_token_ - old_start_token_);
}
curr_ = _start_token + (curr_ - old_start_token_);
}
return success_;
}
// Disallow copying of buffer
basic_file_input (const basic_file_input &);
const basic_file_input &operator = (const basic_file_input &);
};
typedef basic_file_input<char> file_input;
typedef basic_file_input<wchar_t> wfile_input;
}
}
#endif
@@ -0,0 +1,577 @@
// generate_cpp.hpp
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_GENERATE_CPP_HPP
#define BOOST_LEXER_GENERATE_CPP_HPP
#include "char_traits.hpp"
#include "consts.hpp"
#include "internals.hpp"
#include <iostream>
#include <boost/detail/iterator.hpp>
#include "runtime_error.hpp"
#include "size_t.hpp"
#include "state_machine.hpp"
#include <vector>
namespace boost
{
namespace lexer
{
template<typename CharT>
void generate_cpp (const basic_state_machine<CharT> &state_machine_,
std::ostream &os_, const bool use_pointers_ = false,
const bool skip_unknown_ = true, const bool optimise_parameters_ = true,
const char *name_ = "next_token")
{
const detail::internals &sm_ = state_machine_.data ();
if (sm_._lookup->size () == 0)
{
throw runtime_error ("Cannot generate code from an empty "
"state machine");
}
std::string upper_name_ (__DATE__);
const std::size_t lookups_ = sm_._lookup->front ()->size ();
const std::size_t dfas_ = sm_._dfa->size ();
std::string::size_type pos_ = upper_name_.find (' ');
const char *iterator_ = 0;
if (use_pointers_)
{
if (lookups_ == 256)
{
iterator_ = "const char *";
}
else
{
iterator_ = "const wchar_t *";
}
}
else
{
iterator_ = "Iterator &";
}
while (pos_ != std::string::npos)
{
upper_name_.replace (pos_, 1, "_");
pos_ = upper_name_.find (' ', pos_);
}
upper_name_ += '_';
upper_name_ += __TIME__;
pos_ = upper_name_.find (':');
while (pos_ != std::string::npos)
{
upper_name_.erase (pos_, 1);
pos_ = upper_name_.find (':', pos_);
}
upper_name_ = '_' + upper_name_;
upper_name_ = name_ + upper_name_;
std::transform (upper_name_.begin (), upper_name_.end (),
upper_name_.begin (), ::toupper);
os_ << "#ifndef " << upper_name_ + '\n';
os_ << "#define " << upper_name_ + '\n';
os_ << "// Copyright (c) 2008-2009 Ben Hanson\n";
os_ << "//\n";
os_ << "// Distributed under the Boost Software License, "
"Version 1.0. (See accompanying\n";
os_ << "// file licence_1_0.txt or copy at "
"http://www.boost.org/LICENSE_1_0.txt)\n\n";
os_ << "// Auto-generated by boost::lexer\n";
os_ << "template<typename Iterator>\n";
os_ << "std::size_t " << name_ << " (";
if (dfas_ > 1 || !optimise_parameters_)
{
os_ << "std::size_t &start_state_, ";
}
if (use_pointers_)
{
os_ << iterator_ << " &";
}
else
{
os_ << iterator_;
}
os_ << "start_token_, ";
if (use_pointers_)
{
os_ << iterator_ << " const ";
}
else
{
os_ << "const " << iterator_;
}
os_ << "end_, \n";
os_ << " std::size_t &unique_id_";
if (sm_._seen_BOL_assertion || !optimise_parameters_)
{
os_ << ", bool &beg_of_line_";
}
os_ << ")\n";
os_ << "{\n";
os_ << " enum {end_state_index, id_index, unique_id_index, state_index, bol_index,\n";
os_ << " eol_index, dead_state_index, dfa_offset};\n";
os_ << " static const std::size_t npos = static_cast"
"<std::size_t>(~0);\n";
if (dfas_ > 1)
{
std::size_t state_ = 0;
for (; state_ < dfas_; ++state_)
{
std::size_t i_ = 0;
std::size_t j_ = 1;
std::size_t count_ = lookups_ / 8;
const std::size_t *lookup_ = &sm_._lookup[state_]->front ();
const std::size_t *dfa_ = &sm_._dfa[state_]->front ();
os_ << " static const std::size_t lookup" << state_ << "_[" <<
lookups_ << "] = {";
for (; i_ < count_; ++i_)
{
const std::size_t index_ = i_ * 8;
os_ << lookup_[index_];
for (; j_ < 8; ++j_)
{
os_ << ", " << lookup_[index_ + j_];
}
if (i_ < count_ - 1)
{
os_ << "," << std::endl << " ";
}
j_ = 1;
}
os_ << "};\n";
count_ = sm_._dfa[state_]->size ();
os_ << " static const std::size_t dfa" << state_ << "_[" <<
count_ << "] = {";
count_ /= 8;
for (i_ = 0; i_ < count_; ++i_)
{
const std::size_t index_ = i_ * 8;
os_ << dfa_[index_];
for (j_ = 1; j_ < 8; ++j_)
{
os_ << ", " << dfa_[index_ + j_];
}
if (i_ < count_ - 1)
{
os_ << "," << std::endl << " ";
}
}
const std::size_t mod_ = sm_._dfa[state_]->size () % 8;
if (mod_)
{
const std::size_t index_ = count_ * 8;
if (count_)
{
os_ << ",\n ";
}
os_ << dfa_[index_];
for (j_ = 1; j_ < mod_; ++j_)
{
os_ << ", " << dfa_[index_ + j_];
}
}
os_ << "};\n";
}
std::size_t count_ = sm_._dfa_alphabet.size ();
std::size_t i_ = 1;
os_ << " static const std::size_t *lookup_arr_[" << count_ <<
"] = {";
os_ << "lookup0_";
for (i_ = 1; i_ < count_; ++i_)
{
os_ << ", " << "lookup" << i_ << "_";
}
os_ << "};\n";
os_ << " static const std::size_t dfa_alphabet_arr_[" << count_ <<
"] = {";
os_ << sm_._dfa_alphabet.front ();
for (i_ = 1; i_ < count_; ++i_)
{
os_ << ", " << sm_._dfa_alphabet[i_];
}
os_ << "};\n";
os_ << " static const std::size_t *dfa_arr_[" << count_ <<
"] = {";
os_ << "dfa0_";
for (i_ = 1; i_ < count_; ++i_)
{
os_ << ", " << "dfa" << i_ << "_";
}
os_ << "};\n";
}
else
{
const std::size_t *lookup_ = &sm_._lookup->front ()->front ();
const std::size_t *dfa_ = &sm_._dfa->front ()->front ();
std::size_t i_ = 0;
std::size_t j_ = 1;
std::size_t count_ = lookups_ / 8;
os_ << " static const std::size_t lookup_[";
os_ << sm_._lookup->front ()->size () << "] = {";
for (; i_ < count_; ++i_)
{
const std::size_t index_ = i_ * 8;
os_ << lookup_[index_];
for (; j_ < 8; ++j_)
{
os_ << ", " << lookup_[index_ + j_];
}
if (i_ < count_ - 1)
{
os_ << "," << std::endl << " ";
}
j_ = 1;
}
os_ << "};\n";
os_ << " static const std::size_t dfa_alphabet_ = " <<
sm_._dfa_alphabet.front () << ";\n";
os_ << " static const std::size_t dfa_[" <<
sm_._dfa->front ()->size () << "] = {";
count_ = sm_._dfa->front ()->size () / 8;
for (i_ = 0; i_ < count_; ++i_)
{
const std::size_t index_ = i_ * 8;
os_ << dfa_[index_];
for (j_ = 1; j_ < 8; ++j_)
{
os_ << ", " << dfa_[index_ + j_];
}
if (i_ < count_ - 1)
{
os_ << "," << std::endl << " ";
}
}
const std::size_t mod_ = sm_._dfa->front ()->size () % 8;
if (mod_)
{
const std::size_t index_ = count_ * 8;
if (count_)
{
os_ << ",\n ";
}
os_ << dfa_[index_];
for (j_ = 1; j_ < mod_; ++j_)
{
os_ << ", " << dfa_[index_ + j_];
}
}
os_ << "};\n";
}
os_ << "\n if (start_token_ == end_)\n";
os_ << " {\n";
os_ << " unique_id_ = npos;\n";
os_ << " return 0;\n";
os_ << " }\n\n";
if (dfas_ > 1)
{
os_ << "again:\n";
os_ << " const std::size_t * lookup_ = "
"lookup_arr_[start_state_];\n";
os_ << " std::size_t dfa_alphabet_ = "
"dfa_alphabet_arr_[start_state_];\n";
os_ << " const std::size_t *dfa_ = dfa_arr_[start_state_];\n";
}
os_ << " const std::size_t *ptr_ = dfa_ + dfa_alphabet_;\n";
os_ << " Iterator curr_ = start_token_;\n";
os_ << " bool end_state_ = *ptr_ != 0;\n";
os_ << " std::size_t id_ = *(ptr_ + id_index);\n";
os_ << " std::size_t uid_ = *(ptr_ + unique_id_index);\n";
if (dfas_ > 1)
{
os_ << " std::size_t end_start_state_ = start_state_;\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " bool bol_ = beg_of_line_;\n";
os_ << " bool end_bol_ = bol_;\n";
}
os_ << " Iterator end_token_ = start_token_;\n";
os_ << '\n';
os_ << " while (curr_ != end_)\n";
os_ << " {\n";
if (sm_._seen_BOL_assertion)
{
os_ << " const std::size_t BOL_state_ = ptr_[bol_index];\n";
}
if (sm_._seen_EOL_assertion)
{
os_ << " const std::size_t EOL_state_ = ptr_[eol_index];\n";
}
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
{
os_ << '\n';
}
if (sm_._seen_BOL_assertion)
{
os_ << " if (BOL_state_ && bol_)\n";
os_ << " {\n";
os_ << " ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
os_ << " }\n";
}
if (sm_._seen_EOL_assertion)
{
os_ << " ";
if (sm_._seen_BOL_assertion)
{
os_ << "else ";
}
os_ << "if (EOL_state_ && *curr_ == '\\n')\n";
os_ << " {\n";
os_ << " ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
os_ << " }\n";
}
std::string tab_ (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion ? " " : "");
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
{
os_ << " else\n";
os_ << " {\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " ";
if (lookups_ == 256)
{
os_ << "char";
}
else
{
os_ << "wchar_t";
}
os_ << " prev_char_ = *curr_++;\n\n";
os_ << " bol_ = prev_char_ == '\\n';\n\n";
}
os_ << tab_;
os_ << " const std::size_t state_ =\n";
os_ << tab_;
os_ << " ptr_[lookup_[";
if (lookups_ == 256)
{
os_ << "static_cast<unsigned char>(";
}
if (sm_._seen_BOL_assertion)
{
os_ << "prev_char";
}
else
{
os_ << "*curr_++";
}
if (lookups_ == 256)
{
os_ << ')';
}
os_ << "]];\n\n";
os_ << tab_;
os_ << " if (state_ == 0) break;\n\n";
os_ << tab_;
os_ << " ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
{
os_ << " }\n";
}
os_ << '\n';
os_ << " if (*ptr_)\n";
os_ << " {\n";
os_ << " end_state_ = true;\n";
os_ << " id_ = *(ptr_ + id_index);\n";
os_ << " uid_ = *(ptr_ + unique_id_index);\n";
if (dfas_ > 1)
{
os_ << " end_start_state_ = *(ptr_ + state_index);\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " end_bol_ = bol_;\n";
}
os_ << " end_token_ = curr_;\n";
os_ << " }\n";
os_ << " }\n";
os_ << '\n';
if (sm_._seen_EOL_assertion)
{
os_ << " const std::size_t EOL_state_ = ptr_[eol_index];\n";
os_ << '\n';
os_ << " if (EOL_state_ && curr_ == end_)\n";
os_ << " {\n";
os_ << " ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
os_ << '\n';
os_ << " if (*ptr_)\n";
os_ << " {\n";
os_ << " end_state_ = true;\n";
os_ << " id_ = *(ptr_ + id_index);\n";
os_ << " uid_ = *(ptr_ + unique_id_index);\n";
if (dfas_ > 1)
{
os_ << " end_start_state_ = *(ptr_ + state_index);\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " end_bol_ = bol_;\n";
}
os_ << " end_token_ = curr_;\n";
os_ << " }\n";
os_ << " }\n";
os_ << '\n';
}
os_ << " if (end_state_)\n";
os_ << " {\n";
os_ << " // return longest match\n";
if (dfas_ > 1)
{
os_ << " start_state_ = end_start_state_;\n";
}
if (sm_._seen_BOL_assertion && dfas_ < 2)
{
os_ << " beg_of_line_ = end_bol_;\n";
}
os_ << " start_token_ = end_token_;\n";
if (dfas_ > 1)
{
os_ << '\n';
os_ << " if (id_ == 0)\n";
os_ << " {\n";
if (sm_._seen_BOL_assertion)
{
os_ << " bol_ = end_bol_;\n";
}
os_ << " goto again;\n";
os_ << " }\n";
if (sm_._seen_BOL_assertion)
{
os_ << " else\n";
os_ << " {\n";
os_ << " beg_of_line_ = end_bol_;\n";
os_ << " }\n";
}
}
os_ << " }\n";
os_ << " else\n";
os_ << " {\n";
if (sm_._seen_BOL_assertion)
{
os_ << " beg_of_line_ = *start_token_ == '\\n';\n";
}
if (skip_unknown_)
{
os_ << " // No match causes char to be skipped\n";
os_ << " ++start_token_;\n";
}
os_ << " id_ = npos;\n";
os_ << " uid_ = npos;\n";
os_ << " }\n";
os_ << '\n';
os_ << " unique_id_ = uid_;\n";
os_ << " return id_;\n";
os_ << "}\n";
os_ << "\n#endif\n";
}
}
}
#endif
@@ -0,0 +1,440 @@
// generate_re2c.hpp
// Copyright (c) 2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef LEXERTL_GENERATE_RE2C_HPP
#define LEXERTL_GENERATE_RE2C_HPP
#include "char_traits.hpp"
#include "consts.hpp"
#include "internals.hpp"
#include <iostream>
#include "runtime_error.hpp"
#include "size_t.hpp"
#include "state_machine.hpp"
#include <vector>
namespace boost
{
namespace lexer
{
// check whether state0_0 is referenced from any of the other states
template <typename Char>
bool need_label0_0(boost::lexer::basic_state_machine<Char> const &sm_)
{
typedef typename boost::lexer::basic_state_machine<Char>::iterator
iterator_type;
iterator_type iter_ = sm_.begin();
std::size_t states_ = iter_->states;
for (std::size_t state_ = 0; state_ < states_; ++state_)
{
if (0 == iter_->bol_index || 0 == iter_->eol_index)
{
return true;
}
std::size_t const transitions_ = iter_->transitions;
for (std::size_t t_ = 0; t_ < transitions_; ++t_)
{
if (0 == iter_->goto_state)
{
return true;
}
++iter_;
}
if (transitions_ == 0) ++iter_;
}
return false;
}
template<typename CharT>
void generate_re2c (const basic_state_machine<CharT> &state_machine_,
std::ostream &os_, const bool use_pointers_ = false,
const bool skip_unknown_ = true, const bool optimise_parameters_ = true,
const char *name_ = "next_token")
{
typedef typename boost::lexer::basic_string_token<CharT> string_token;
const detail::internals &sm_ = state_machine_.data ();
if (sm_._lookup->size () == 0)
{
throw runtime_error ("Cannot generate code from an empty "
"state machine");
}
std::string upper_name_ (__DATE__);
const std::size_t lookups_ = sm_._lookup->front ()->size ();
typename boost::lexer::basic_state_machine<CharT>::iterator iter_ =
state_machine_.begin();
typename boost::lexer::basic_state_machine<CharT>::iterator end_ =
state_machine_.end();
const std::size_t dfas_ = sm_._dfa->size ();
std::string::size_type pos_ = upper_name_.find (' ');
const char *iterator_ = 0;
if (use_pointers_)
{
if (lookups_ == 256)
{
iterator_ = "const char *";
}
else
{
iterator_ = "const wchar_t *";
}
}
else
{
iterator_ = "Iterator &";
}
while (pos_ != std::string::npos)
{
upper_name_.replace (pos_, 1, "_");
pos_ = upper_name_.find (' ', pos_);
}
upper_name_ += '_';
upper_name_ += __TIME__;
pos_ = upper_name_.find (':');
while (pos_ != std::string::npos)
{
upper_name_.erase (pos_, 1);
pos_ = upper_name_.find (':', pos_);
}
upper_name_ = '_' + upper_name_;
upper_name_ = name_ + upper_name_;
std::transform (upper_name_.begin (), upper_name_.end (),
upper_name_.begin (), ::toupper);
os_ << "#ifndef " << upper_name_ + '\n';
os_ << "#define " << upper_name_ + '\n';
os_ << "// Copyright (c) 2008-2009 Ben Hanson\n";
os_ << "//\n";
os_ << "// Distributed under the Boost Software License, "
"Version 1.0. (See accompanying\n";
os_ << "// file licence_1_0.txt or copy at "
"http://www.boost.org/LICENSE_1_0.txt)\n\n";
os_ << "// Auto-generated by boost::lexer\n";
os_ << "template<typename Iterator>\n";
os_ << "std::size_t " << name_ << " (";
if (dfas_ > 1 || !optimise_parameters_)
{
os_ << "std::size_t &start_state_, ";
}
if (use_pointers_)
{
os_ << iterator_ << " &";
}
else
{
os_ << iterator_;
}
os_ << "start_token_, ";
if (use_pointers_)
{
os_ << iterator_ << " const ";
}
else
{
os_ << "const " << iterator_;
}
os_ << "end_, \n";
os_ << " std::size_t &unique_id_";
if (sm_._seen_BOL_assertion || !optimise_parameters_)
{
os_ << ", bool &beg_of_line_";
}
os_ << ")\n";
os_ << "{\n";
os_ << " static const std::size_t npos = static_cast"
"<std::size_t>(~0);\n";
os_ << "\n if (start_token_ == end_)\n";
os_ << " {\n";
os_ << " unique_id_ = npos;\n";
os_ << " return 0;\n";
os_ << " }\n\n";
if (dfas_ > 1)
{
os_ << "again:\n";
}
os_ << " Iterator curr_ = start_token_;\n";
os_ << " bool end_state_ = false;\n";
os_ << " std::size_t id_ = npos;\n";
os_ << " std::size_t uid_ = npos;\n";
if (dfas_ > 1)
{
os_ << " std::size_t end_start_state_ = start_state_;\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " bool bol_ = beg_of_line_;\n";
os_ << " bool end_bol_ = bol_;\n";
}
os_ << " Iterator end_token_ = start_token_;\n";
os_ << '\n';
if (dfas_ > 1)
{
os_ << " switch (start_state_)\n";
os_ << " {\n";
for (std::size_t i_ = 0; i_ < dfas_; ++i_)
{
os_ << " case " << i_ << ":\n";
os_ << " goto " << i_ << "_0;\n";
os_ << " // Not needed, but to prevent warnings\n";
os_ << " break;\n";
}
os_ << " default:\n";
os_ << " throw std::runtime_error (\"Invalid start state!\")\n";
os_ << " break;\n";
os_ << " }\n\n";
}
os_ << " ";
if (lookups_ == 256)
{
os_ << "char";
}
else
{
os_ << "wchar_t";
}
os_ << " ch_ = 0;\n\n";
bool need_state0_0_label = need_label0_0(state_machine_);
for (std::size_t dfa_ = 0; dfa_ < dfas_; ++dfa_)
{
const std::size_t states_ = iter_->states;
for (std::size_t state_ = 0; state_ < states_; ++state_)
{
const std::size_t transitions_ = iter_->transitions;
std::size_t t_ = 0;
if (dfas_ > 1 || dfa_ != 0 || state_ != 0 || need_state0_0_label)
{
os_ << "state" << dfa_ << '_' << state_ << ":\n";
}
if (iter_->end_state)
{
os_ << " end_state_ = true;\n";
os_ << " id_ = " << iter_->id << ";\n";
os_ << " uid_ = " << iter_->unique_id << ";\n";
os_ << " end_token_ = curr_;\n";
if (dfas_ > 1)
{
os_ << " end_start_state_ = " << iter_->goto_dfa <<
";\n";
}
if (sm_._seen_BOL_assertion)
{
os_ << " end_bol_ = bol_;\n";
}
if (transitions_) os_ << '\n';
}
if (t_ < transitions_ || iter_->bol_index != boost::lexer::npos ||
iter_->eol_index != boost::lexer::npos)
{
os_ << " if (curr_ == end_) goto end;\n\n";
os_ << " ch_ = *curr_;\n";
if (iter_->bol_index != boost::lexer::npos)
{
os_ << "\n if (bol_) goto state" << dfa_ << '_' <<
iter_->bol_index << ";\n\n";
}
if (iter_->eol_index != boost::lexer::npos)
{
os_ << "\n if (ch_ == '\n') goto state" << dfa_ << '_' <<
iter_->eol_index << ";\n\n";
}
os_ << " ++curr_;\n";
}
for (; t_ < transitions_; ++t_)
{
const char *ptr_ = iter_->token._charset.c_str();
const char *end_ = ptr_ + iter_->token._charset.size();
char start_char_ = 0;
char curr_char_ = 0;
bool range_ = false;
bool first_char_ = true;
os_ << "\n if (";
while (ptr_ != end_)
{
curr_char_ = *ptr_++;
if (*ptr_ == curr_char_ + 1)
{
if (!range_)
{
start_char_ = curr_char_;
}
range_ = true;
}
else
{
if (!first_char_)
{
if (iter_->token._negated)
{
os_ << " && ";
}
else
{
os_ << " || ";
}
}
first_char_ = false;
if (range_)
{
typename string_token::string temp_;
if (iter_->token._negated)
{
os_ << "!";
}
string_token::escape_char (start_char_, temp_);
os_ << "(ch_ >= '" << temp_;
temp_.clear ();
string_token::escape_char (curr_char_, temp_);
os_ << "' && ch_ <= '" << temp_ << "')";
range_ = false;
}
else
{
typename string_token::string temp_;
os_ << "ch_ ";
if (iter_->token._negated)
{
os_ << "!=";
}
else
{
os_ << "==";
}
string_token::escape_char (curr_char_, temp_);
os_ << " '" << temp_ << "'";
}
}
}
os_ << ") goto state" << dfa_ << '_' << iter_->goto_state <<
";\n\n";
++iter_;
}
if (!(dfa_ == dfas_ - 1 && state_ == states_ - 1))
{
os_ << " goto end;\n";
}
if (transitions_ == 0) ++iter_;
}
}
os_ << "end:\n";
os_ << " if (end_state_)\n";
os_ << " {\n";
os_ << " // return longest match\n";
if (dfas_ > 1)
{
os_ << " start_state_ = end_start_state_;\n";
}
if (sm_._seen_BOL_assertion && dfas_ < 2)
{
os_ << " beg_of_line_ = end_bol_;\n";
}
os_ << " start_token_ = end_token_;\n";
if (dfas_ > 1)
{
os_ << '\n';
os_ << " if (id_ == 0)\n";
os_ << " {\n";
if (sm_._seen_BOL_assertion)
{
os_ << " bol_ = end_bol_;\n";
}
os_ << " goto again;\n";
os_ << " }\n";
if (sm_._seen_BOL_assertion)
{
os_ << " else\n";
os_ << " {\n";
os_ << " beg_of_line_ = end_bol_;\n";
os_ << " }\n";
}
}
os_ << " }\n";
os_ << " else\n";
os_ << " {\n";
if (sm_._seen_BOL_assertion)
{
os_ << " beg_of_line_ = *start_token_ == '\\n';\n";
}
if (skip_unknown_)
{
os_ << " // No match causes char to be skipped\n";
os_ << " ++start_token_;\n";
}
os_ << " id_ = npos;\n";
os_ << " uid_ = npos;\n";
os_ << " }\n";
os_ << '\n';
os_ << " unique_id_ = uid_;\n";
os_ << " return id_;\n";
os_ << "}\n";
os_ << "\n#endif\n";
}
}
}
#endif
@@ -0,0 +1,864 @@
// generator.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_GENERATOR_HPP
#define BOOST_LEXER_GENERATOR_HPP
#include "char_traits.hpp"
// memcmp()
#include <cstring>
#include "partition/charset.hpp"
#include "partition/equivset.hpp"
#include <memory>
#include <limits>
#include "parser/tree/node.hpp"
#include "parser/parser.hpp"
#include "containers/ptr_list.hpp"
#include "rules.hpp"
#include "state_machine.hpp"
namespace boost
{
namespace lexer
{
template<typename CharT, typename Traits = char_traits<CharT> >
class basic_generator
{
public:
typedef typename detail::internals::size_t_vector size_t_vector;
typedef basic_rules<CharT> rules;
static void build (const rules &rules_,
basic_state_machine<CharT> &state_machine_)
{
std::size_t index_ = 0;
std::size_t size_ = rules_.statemap ().size ();
node_ptr_vector node_ptr_vector_;
detail::internals &internals_ = const_cast<detail::internals &>
(state_machine_.data ());
bool seen_BOL_assertion_ = false;
bool seen_EOL_assertion_ = false;
state_machine_.clear ();
for (; index_ < size_; ++index_)
{
internals_._lookup->push_back (static_cast<size_t_vector *>(0));
internals_._lookup->back () = new size_t_vector;
internals_._dfa_alphabet.push_back (0);
internals_._dfa->push_back (static_cast<size_t_vector *>(0));
internals_._dfa->back () = new size_t_vector;
}
for (index_ = 0, size_ = internals_._lookup->size ();
index_ < size_; ++index_)
{
internals_._lookup[index_]->resize (sizeof (CharT) == 1 ?
num_chars : num_wchar_ts, dead_state_index);
if (!rules_.regexes ()[index_].empty ())
{
// vector mapping token indexes to partitioned token index sets
index_set_vector set_mapping_;
// syntax tree
detail::node *root_ = build_tree (rules_, index_,
node_ptr_vector_, internals_, set_mapping_);
build_dfa (root_, set_mapping_,
internals_._dfa_alphabet[index_],
*internals_._dfa[index_]);
if (internals_._seen_BOL_assertion)
{
seen_BOL_assertion_ = true;
}
if (internals_._seen_EOL_assertion)
{
seen_EOL_assertion_ = true;
}
internals_._seen_BOL_assertion = false;
internals_._seen_EOL_assertion = false;
}
}
internals_._seen_BOL_assertion = seen_BOL_assertion_;
internals_._seen_EOL_assertion = seen_EOL_assertion_;
}
static void minimise (basic_state_machine<CharT> &state_machine_)
{
detail::internals &internals_ = const_cast<detail::internals &>
(state_machine_.data ());
const std::size_t machines_ = internals_._dfa->size ();
for (std::size_t i_ = 0; i_ < machines_; ++i_)
{
const std::size_t dfa_alphabet_ = internals_._dfa_alphabet[i_];
size_t_vector *dfa_ = internals_._dfa[i_];
if (dfa_alphabet_ != 0)
{
std::size_t size_ = 0;
do
{
size_ = dfa_->size ();
minimise_dfa (dfa_alphabet_, *dfa_, size_);
} while (dfa_->size () != size_);
}
}
}
protected:
typedef detail::basic_charset<CharT> charset;
typedef detail::ptr_list<charset> charset_list;
typedef std::auto_ptr<charset> charset_ptr;
typedef detail::equivset equivset;
typedef detail::ptr_list<equivset> equivset_list;
typedef std::auto_ptr<equivset> equivset_ptr;
typedef typename charset::index_set index_set;
typedef std::vector<index_set> index_set_vector;
typedef detail::basic_parser<CharT> parser;
typedef typename parser::node_ptr_vector node_ptr_vector;
typedef std::set<const detail::node *> node_set;
typedef detail::ptr_vector<node_set> node_set_vector;
typedef std::vector<const detail::node *> node_vector;
typedef detail::ptr_vector<node_vector> node_vector_vector;
typedef typename parser::string string;
typedef std::pair<string, string> string_pair;
typedef typename parser::tokeniser::string_token string_token;
typedef std::deque<string_pair> macro_deque;
typedef std::pair<string, const detail::node *> macro_pair;
typedef typename parser::macro_map::iterator macro_iter;
typedef std::pair<macro_iter, bool> macro_iter_pair;
typedef typename parser::tokeniser::token_map token_map;
static detail::node *build_tree (const rules &rules_,
const std::size_t state_, node_ptr_vector &node_ptr_vector_,
detail::internals &internals_, index_set_vector &set_mapping_)
{
size_t_vector *lookup_ = internals_._lookup[state_];
const typename rules::string_deque_deque &regexes_ =
rules_.regexes ();
const typename rules::id_vector_deque &ids_ = rules_.ids ();
const typename rules::id_vector_deque &unique_ids_ =
rules_.unique_ids ();
const typename rules::id_vector_deque &states_ = rules_.states ();
typename rules::string_deque::const_iterator regex_iter_ =
regexes_[state_].begin ();
typename rules::string_deque::const_iterator regex_iter_end_ =
regexes_[state_].end ();
typename rules::id_vector::const_iterator ids_iter_ =
ids_[state_].begin ();
typename rules::id_vector::const_iterator unique_ids_iter_ =
unique_ids_[state_].begin ();
typename rules::id_vector::const_iterator states_iter_ =
states_[state_].begin ();
const typename rules::string &regex_ = *regex_iter_;
// map of regex charset tokens (strings) to index
token_map token_map_;
const typename rules::string_pair_deque &macrodeque_ =
rules_.macrodeque ();
typename parser::macro_map macromap_;
typename detail::node::node_vector tree_vector_;
build_macros (token_map_, macrodeque_, macromap_,
rules_.flags (), rules_.locale (), node_ptr_vector_,
internals_._seen_BOL_assertion, internals_._seen_EOL_assertion);
detail::node *root_ = parser::parse (regex_.c_str (),
regex_.c_str () + regex_.size (), *ids_iter_, *unique_ids_iter_,
*states_iter_, rules_.flags (), rules_.locale (), node_ptr_vector_,
macromap_, token_map_, internals_._seen_BOL_assertion,
internals_._seen_EOL_assertion);
++regex_iter_;
++ids_iter_;
++unique_ids_iter_;
++states_iter_;
tree_vector_.push_back (root_);
// build syntax trees
while (regex_iter_ != regex_iter_end_)
{
// re-declare var, otherwise we perform an assignment..!
const typename rules::string &regex2_ = *regex_iter_;
root_ = parser::parse (regex2_.c_str (),
regex2_.c_str () + regex2_.size (), *ids_iter_,
*unique_ids_iter_, *states_iter_, rules_.flags (),
rules_.locale (), node_ptr_vector_, macromap_, token_map_,
internals_._seen_BOL_assertion,
internals_._seen_EOL_assertion);
tree_vector_.push_back (root_);
++regex_iter_;
++ids_iter_;
++unique_ids_iter_;
++states_iter_;
}
if (internals_._seen_BOL_assertion)
{
// Fixup BOLs
typename detail::node::node_vector::iterator iter_ =
tree_vector_.begin ();
typename detail::node::node_vector::iterator end_ =
tree_vector_.end ();
for (; iter_ != end_; ++iter_)
{
fixup_bol (*iter_, node_ptr_vector_);
}
}
// join trees
{
typename detail::node::node_vector::iterator iter_ =
tree_vector_.begin ();
typename detail::node::node_vector::iterator end_ =
tree_vector_.end ();
if (iter_ != end_)
{
root_ = *iter_;
++iter_;
}
for (; iter_ != end_; ++iter_)
{
node_ptr_vector_->push_back (static_cast<detail::selection_node *>(0));
node_ptr_vector_->back () = new detail::selection_node
(root_, *iter_);
root_ = node_ptr_vector_->back ();
}
}
// partitioned token list
charset_list token_list_;
set_mapping_.resize (token_map_.size ());
partition_tokens (token_map_, token_list_);
typename charset_list::list::const_iterator iter_ =
token_list_->begin ();
typename charset_list::list::const_iterator end_ =
token_list_->end ();
std::size_t index_ = 0;
for (; iter_ != end_; ++iter_, ++index_)
{
const charset *cs_ = *iter_;
typename charset::index_set::const_iterator set_iter_ =
cs_->_index_set.begin ();
typename charset::index_set::const_iterator set_end_ =
cs_->_index_set.end ();
fill_lookup (cs_->_token, lookup_, index_);
for (; set_iter_ != set_end_; ++set_iter_)
{
set_mapping_[*set_iter_].insert (index_);
}
}
internals_._dfa_alphabet[state_] = token_list_->size () + dfa_offset;
return root_;
}
static void build_macros (token_map &token_map_,
const macro_deque &macrodeque_,
typename parser::macro_map &macromap_, const regex_flags flags_,
const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
bool &seen_BOL_assertion_, bool &seen_EOL_assertion_)
{
for (typename macro_deque::const_iterator iter_ =
macrodeque_.begin (), end_ = macrodeque_.end ();
iter_ != end_; ++iter_)
{
const typename rules::string &name_ = iter_->first;
const typename rules::string &regex_ = iter_->second;
detail::node *node_ = parser::parse (regex_.c_str (),
regex_.c_str () + regex_.size (), 0, 0, 0, flags_,
locale_, node_ptr_vector_, macromap_, token_map_,
seen_BOL_assertion_, seen_EOL_assertion_);
macro_iter_pair map_iter_ = macromap_.
insert (macro_pair (name_, static_cast<const detail::node *>
(0)));
map_iter_.first->second = node_;
}
}
static void build_dfa (detail::node *root_,
const index_set_vector &set_mapping_, const std::size_t dfa_alphabet_,
size_t_vector &dfa_)
{
typename detail::node::node_vector *followpos_ =
&root_->firstpos ();
node_set_vector seen_sets_;
node_vector_vector seen_vectors_;
size_t_vector hash_vector_;
// 'jam' state
dfa_.resize (dfa_alphabet_, 0);
closure (followpos_, seen_sets_, seen_vectors_,
hash_vector_, dfa_alphabet_, dfa_);
std::size_t *ptr_ = 0;
for (std::size_t index_ = 0; index_ < seen_vectors_->size (); ++index_)
{
equivset_list equiv_list_;
build_equiv_list (seen_vectors_[index_], set_mapping_, equiv_list_);
for (typename equivset_list::list::const_iterator iter_ =
equiv_list_->begin (), end_ = equiv_list_->end ();
iter_ != end_; ++iter_)
{
equivset *equivset_ = *iter_;
const std::size_t transition_ = closure
(&equivset_->_followpos, seen_sets_, seen_vectors_,
hash_vector_, dfa_alphabet_, dfa_);
if (transition_ != npos)
{
ptr_ = &dfa_.front () + ((index_ + 1) * dfa_alphabet_);
// Prune abstemious transitions from end states.
if (*ptr_ && !equivset_->_greedy) continue;
for (typename detail::equivset::index_vector::const_iterator
equiv_iter_ = equivset_->_index_vector.begin (),
equiv_end_ = equivset_->_index_vector.end ();
equiv_iter_ != equiv_end_; ++equiv_iter_)
{
const std::size_t equiv_index_ = *equiv_iter_;
if (equiv_index_ == bol_token)
{
if (ptr_[eol_index] == 0)
{
ptr_[bol_index] = transition_;
}
}
else if (equiv_index_ == eol_token)
{
if (ptr_[bol_index] == 0)
{
ptr_[eol_index] = transition_;
}
}
else
{
ptr_[equiv_index_ + dfa_offset] = transition_;
}
}
}
}
}
}
static std::size_t closure (typename detail::node::node_vector *followpos_,
node_set_vector &seen_sets_, node_vector_vector &seen_vectors_,
size_t_vector &hash_vector_, const std::size_t size_,
size_t_vector &dfa_)
{
bool end_state_ = false;
std::size_t id_ = 0;
std::size_t unique_id_ = npos;
std::size_t state_ = 0;
std::size_t hash_ = 0;
if (followpos_->empty ()) return npos;
std::size_t index_ = 0;
std::auto_ptr<node_set> set_ptr_ (new node_set);
std::auto_ptr<node_vector> vector_ptr_ (new node_vector);
for (typename detail::node::node_vector::const_iterator iter_ =
followpos_->begin (), end_ = followpos_->end ();
iter_ != end_; ++iter_)
{
closure_ex (*iter_, end_state_, id_, unique_id_, state_,
set_ptr_.get (), vector_ptr_.get (), hash_);
}
bool found_ = false;
typename size_t_vector::const_iterator hash_iter_ =
hash_vector_.begin ();
typename size_t_vector::const_iterator hash_end_ =
hash_vector_.end ();
typename node_set_vector::vector::const_iterator set_iter_ =
seen_sets_->begin ();
for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_)
{
found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_;
++index_;
if (found_) break;
}
if (!found_)
{
seen_sets_->push_back (static_cast<node_set *>(0));
seen_sets_->back () = set_ptr_.release ();
seen_vectors_->push_back (static_cast<node_vector *>(0));
seen_vectors_->back () = vector_ptr_.release ();
hash_vector_.push_back (hash_);
// State 0 is the jam state...
index_ = seen_sets_->size ();
const std::size_t old_size_ = dfa_.size ();
dfa_.resize (old_size_ + size_, 0);
if (end_state_)
{
dfa_[old_size_] |= end_state;
dfa_[old_size_ + id_index] = id_;
dfa_[old_size_ + unique_id_index] = unique_id_;
dfa_[old_size_ + state_index] = state_;
}
}
return index_;
}
static void closure_ex (detail::node *node_, bool &end_state_,
std::size_t &id_, std::size_t &unique_id_, std::size_t &state_,
node_set *set_ptr_, node_vector *vector_ptr_, std::size_t &hash_)
{
const bool temp_end_state_ = node_->end_state ();
if (temp_end_state_)
{
if (!end_state_)
{
end_state_ = true;
id_ = node_->id ();
unique_id_ = node_->unique_id ();
state_ = node_->lexer_state ();
}
}
if (set_ptr_->insert (node_).second)
{
vector_ptr_->push_back (node_);
hash_ += reinterpret_cast<std::size_t> (node_);
}
}
static void partition_tokens (const token_map &map_,
charset_list &lhs_)
{
charset_list rhs_;
fill_rhs_list (map_, rhs_);
if (!rhs_->empty ())
{
typename charset_list::list::iterator iter_;
typename charset_list::list::iterator end_;
charset_ptr overlap_ (new charset);
lhs_->push_back (static_cast<charset *>(0));
lhs_->back () = rhs_->front ();
rhs_->pop_front ();
while (!rhs_->empty ())
{
charset_ptr r_ (rhs_->front ());
rhs_->pop_front ();
iter_ = lhs_->begin ();
end_ = lhs_->end ();
while (!r_->empty () && iter_ != end_)
{
typename charset_list::list::iterator l_iter_ = iter_;
(*l_iter_)->intersect (*r_.get (), *overlap_.get ());
if (overlap_->empty ())
{
++iter_;
}
else if ((*l_iter_)->empty ())
{
delete *l_iter_;
*l_iter_ = overlap_.release ();
// VC++ 6 Hack:
charset_ptr temp_overlap_ (new charset);
overlap_ = temp_overlap_;
++iter_;
}
else if (r_->empty ())
{
delete r_.release ();
r_ = overlap_;
// VC++ 6 Hack:
charset_ptr temp_overlap_ (new charset);
overlap_ = temp_overlap_;
break;
}
else
{
iter_ = lhs_->insert (++iter_,
static_cast<charset *>(0));
*iter_ = overlap_.release ();
// VC++ 6 Hack:
charset_ptr temp_overlap_ (new charset);
overlap_ = temp_overlap_;
++iter_;
end_ = lhs_->end ();
}
}
if (!r_->empty ())
{
lhs_->push_back (static_cast<charset *>(0));
lhs_->back () = r_.release ();
}
}
}
}
static void fill_rhs_list (const token_map &map_,
charset_list &list_)
{
typename parser::tokeniser::token_map::const_iterator iter_ =
map_.begin ();
typename parser::tokeniser::token_map::const_iterator end_ =
map_.end ();
for (; iter_ != end_; ++iter_)
{
list_->push_back (static_cast<charset *>(0));
list_->back () = new charset (iter_->first, iter_->second);
}
}
static void fill_lookup (const string_token &token_,
size_t_vector *lookup_, const std::size_t index_)
{
const CharT *curr_ = token_._charset.c_str ();
const CharT *chars_end_ = curr_ + token_._charset.size ();
std::size_t *ptr_ = &lookup_->front ();
const std::size_t max_ = sizeof (CharT) == 1 ?
num_chars : num_wchar_ts;
if (token_._negated)
{
// $$$ FIXME JDG July 2014 $$$
// this code is problematic on platforms where wchar_t is signed
// with min generating negative numbers. This crashes with BAD_ACCESS
// because of the vector index below:
// ptr_[static_cast<typename Traits::index_type>(curr_char_)]
CharT curr_char_ = 0; // (std::numeric_limits<CharT>::min)();
std::size_t i_ = 0;
while (curr_ < chars_end_)
{
while (*curr_ > curr_char_)
{
ptr_[static_cast<typename Traits::index_type>
(curr_char_)] = index_ + dfa_offset;
++curr_char_;
++i_;
}
++curr_char_;
++curr_;
++i_;
}
for (; i_ < max_; ++i_)
{
ptr_[static_cast<typename Traits::index_type>(curr_char_)] =
index_ + dfa_offset;
++curr_char_;
}
}
else
{
while (curr_ < chars_end_)
{
ptr_[static_cast<typename Traits::index_type>(*curr_)] =
index_ + dfa_offset;
++curr_;
}
}
}
static void build_equiv_list (const node_vector *vector_,
const index_set_vector &set_mapping_, equivset_list &lhs_)
{
equivset_list rhs_;
fill_rhs_list (vector_, set_mapping_, rhs_);
if (!rhs_->empty ())
{
typename equivset_list::list::iterator iter_;
typename equivset_list::list::iterator end_;
equivset_ptr overlap_ (new equivset);
lhs_->push_back (static_cast<equivset *>(0));
lhs_->back () = rhs_->front ();
rhs_->pop_front ();
while (!rhs_->empty ())
{
equivset_ptr r_ (rhs_->front ());
rhs_->pop_front ();
iter_ = lhs_->begin ();
end_ = lhs_->end ();
while (!r_->empty () && iter_ != end_)
{
typename equivset_list::list::iterator l_iter_ = iter_;
(*l_iter_)->intersect (*r_.get (), *overlap_.get ());
if (overlap_->empty ())
{
++iter_;
}
else if ((*l_iter_)->empty ())
{
delete *l_iter_;
*l_iter_ = overlap_.release ();
// VC++ 6 Hack:
equivset_ptr temp_overlap_ (new equivset);
overlap_ = temp_overlap_;
++iter_;
}
else if (r_->empty ())
{
delete r_.release ();
r_ = overlap_;
// VC++ 6 Hack:
equivset_ptr temp_overlap_ (new equivset);
overlap_ = temp_overlap_;
break;
}
else
{
iter_ = lhs_->insert (++iter_,
static_cast<equivset *>(0));
*iter_ = overlap_.release ();
// VC++ 6 Hack:
equivset_ptr temp_overlap_ (new equivset);
overlap_ = temp_overlap_;
++iter_;
end_ = lhs_->end ();
}
}
if (!r_->empty ())
{
lhs_->push_back (static_cast<equivset *>(0));
lhs_->back () = r_.release ();
}
}
}
}
static void fill_rhs_list (const node_vector *vector_,
const index_set_vector &set_mapping_, equivset_list &list_)
{
typename node_vector::const_iterator iter_ =
vector_->begin ();
typename node_vector::const_iterator end_ =
vector_->end ();
for (; iter_ != end_; ++iter_)
{
const detail::node *node_ = *iter_;
if (!node_->end_state ())
{
const std::size_t token_ = node_->token ();
if (token_ != null_token)
{
list_->push_back (static_cast<equivset *>(0));
if (token_ == bol_token || token_ == eol_token)
{
std::set<std::size_t> index_set_;
index_set_.insert (token_);
list_->back () = new equivset (index_set_,
node_->greedy (), token_, node_->followpos ());
}
else
{
list_->back () = new equivset (set_mapping_[token_],
node_->greedy (), token_, node_->followpos ());
}
}
}
}
}
static void fixup_bol (detail::node * &root_,
node_ptr_vector &node_ptr_vector_)
{
typename detail::node::node_vector *first_ = &root_->firstpos ();
bool found_ = false;
typename detail::node::node_vector::const_iterator iter_ =
first_->begin ();
typename detail::node::node_vector::const_iterator end_ =
first_->end ();
for (; iter_ != end_; ++iter_)
{
const detail::node *node_ = *iter_;
found_ = !node_->end_state () && node_->token () == bol_token;
if (found_) break;
}
if (!found_)
{
node_ptr_vector_->push_back (static_cast<detail::leaf_node *>(0));
node_ptr_vector_->back () = new detail::leaf_node
(bol_token, true);
detail::node *lhs_ = node_ptr_vector_->back ();
node_ptr_vector_->push_back (static_cast<detail::leaf_node *>(0));
node_ptr_vector_->back () = new detail::leaf_node
(null_token, true);
detail::node *rhs_ = node_ptr_vector_->back ();
node_ptr_vector_->push_back
(static_cast<detail::selection_node *>(0));
node_ptr_vector_->back () =
new detail::selection_node (lhs_, rhs_);
lhs_ = node_ptr_vector_->back ();
node_ptr_vector_->push_back
(static_cast<detail::sequence_node *>(0));
node_ptr_vector_->back () =
new detail::sequence_node (lhs_, root_);
root_ = node_ptr_vector_->back ();
}
}
static void minimise_dfa (const std::size_t dfa_alphabet_,
size_t_vector &dfa_, std::size_t size_)
{
const std::size_t *first_ = &dfa_.front ();
const std::size_t *second_ = 0;
const std::size_t *end_ = first_ + size_;
std::size_t index_ = 1;
std::size_t new_index_ = 1;
std::size_t curr_index_ = 0;
index_set index_set_;
size_t_vector lookup_;
std::size_t *lookup_ptr_ = 0;
lookup_.resize (size_ / dfa_alphabet_, null_token);
lookup_ptr_ = &lookup_.front ();
*lookup_ptr_ = 0;
// Only one 'jam' state, so skip it.
first_ += dfa_alphabet_;
for (; first_ < end_; first_ += dfa_alphabet_, ++index_)
{
for (second_ = first_ + dfa_alphabet_, curr_index_ = index_ + 1;
second_ < end_; second_ += dfa_alphabet_, ++curr_index_)
{
if (index_set_.find (curr_index_) != index_set_.end ())
{
continue;
}
// Some systems have memcmp in namespace std.
using namespace std;
if (memcmp (first_, second_, sizeof (std::size_t) *
dfa_alphabet_) == 0)
{
index_set_.insert (curr_index_);
lookup_ptr_[curr_index_] = new_index_;
}
}
if (lookup_ptr_[index_] == null_token)
{
lookup_ptr_[index_] = new_index_;
++new_index_;
}
}
if (!index_set_.empty ())
{
const std::size_t *front_ = &dfa_.front ();
size_t_vector new_dfa_ (front_, front_ + dfa_alphabet_);
typename index_set::iterator set_end_ =
index_set_.end ();
const std::size_t *ptr_ = front_ + dfa_alphabet_;
std::size_t *new_ptr_ = 0;
new_dfa_.resize (size_ - index_set_.size () * dfa_alphabet_, 0);
new_ptr_ = &new_dfa_.front () + dfa_alphabet_;
size_ /= dfa_alphabet_;
for (index_ = 1; index_ < size_; ++index_)
{
if (index_set_.find (index_) != set_end_)
{
ptr_ += dfa_alphabet_;
continue;
}
new_ptr_[end_state_index] = ptr_[end_state_index];
new_ptr_[id_index] = ptr_[id_index];
new_ptr_[unique_id_index] = ptr_[unique_id_index];
new_ptr_[state_index] = ptr_[state_index];
new_ptr_[bol_index] = lookup_ptr_[ptr_[bol_index]];
new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]];
new_ptr_ += dfa_offset;
ptr_ += dfa_offset;
for (std::size_t i_ = dfa_offset; i_ < dfa_alphabet_; ++i_)
{
*new_ptr_++ = lookup_ptr_[*ptr_++];
}
}
dfa_.swap (new_dfa_);
}
}
};
typedef basic_generator<char> generator;
typedef basic_generator<wchar_t> wgenerator;
}
}
#endif
@@ -0,0 +1,529 @@
// input.hpp
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_INPUT
#define BOOST_LEXER_INPUT
#include "char_traits.hpp"
#include <boost/detail/iterator.hpp>
#include "size_t.hpp"
#include "state_machine.hpp"
namespace boost
{
namespace lexer
{
template<typename FwdIter, typename Traits =
char_traits<typename boost::detail::iterator_traits<FwdIter>::value_type> >
class basic_input
{
public:
class iterator
{
public:
friend class basic_input;
struct data
{
std::size_t id;
std::size_t unique_id;
FwdIter start;
FwdIter end;
bool bol;
std::size_t state;
// Construct in end() state.
data () :
id (0),
unique_id (npos),
bol (false),
state (npos)
{
}
bool operator == (const data &rhs_) const
{
return id == rhs_.id && unique_id == rhs_.unique_id &&
start == rhs_.start && end == rhs_.end &&
bol == rhs_.bol && state == rhs_.state;
}
};
iterator () :
_input (0)
{
}
bool operator == (const iterator &rhs_) const
{
return _data == rhs_._data;
}
bool operator != (const iterator &rhs_) const
{
return !(*this == rhs_);
}
data &operator * ()
{
return _data;
}
data *operator -> ()
{
return &_data;
}
// Let compiler generate operator = ().
// prefix version
iterator &operator ++ ()
{
next_token ();
return *this;
}
// postfix version
iterator operator ++ (int)
{
iterator iter_ = *this;
next_token ();
return iter_;
}
private:
// Not owner (obviously!)
const basic_input *_input;
data _data;
void next_token ()
{
const detail::internals &internals_ =
_input->_state_machine->data ();
_data.start = _data.end;
if (internals_._dfa->size () == 1)
{
if (internals_._seen_BOL_assertion ||
internals_._seen_EOL_assertion)
{
_data.id = next
(&internals_._lookup->front ()->front (),
internals_._dfa_alphabet.front (),
&internals_._dfa->front ()->front (),
_data.bol, _data.end, _input->_end, _data.unique_id);
}
else
{
_data.id = next (&internals_._lookup->front ()->front (),
internals_._dfa_alphabet.front (), &internals_.
_dfa->front ()->front (), _data.end, _input->_end,
_data.unique_id);
}
}
else
{
if (internals_._seen_BOL_assertion ||
internals_._seen_EOL_assertion)
{
_data.id = next (internals_, _data.state,
_data.bol, _data.end, _input->_end, _data.unique_id);
}
else
{
_data.id = next (internals_, _data.state,
_data.end, _input->_end, _data.unique_id);
}
}
if (_data.end == _input->_end && _data.start == _data.end)
{
// Ensure current state matches that returned by end().
_data.state = npos;
}
}
std::size_t next (const detail::internals &internals_,
std::size_t &start_state_, bool bol_,
FwdIter &start_token_, const FwdIter &end_,
std::size_t &unique_id_)
{
if (start_token_ == end_)
{
unique_id_ = npos;
return 0;
}
again:
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
front ();
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
FwdIter curr_ = start_token_;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
std::size_t end_start_state_ = start_state_;
bool end_bol_ = bol_;
FwdIter end_token_ = start_token_;
while (curr_ != end_)
{
const std::size_t BOL_state_ = ptr_[bol_index];
const std::size_t EOL_state_ = ptr_[eol_index];
if (BOL_state_ && bol_)
{
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
}
else if (EOL_state_ && *curr_ == '\n')
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
}
else
{
typename Traits::char_type prev_char_ = *curr_++;
bol_ = prev_char_ == '\n';
const std::size_t state_ =
ptr_[lookup_[static_cast<typename Traits::index_type>
(prev_char_)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
}
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_start_state_ = *(ptr_ + state_index);
end_bol_ = bol_;
end_token_ = curr_;
}
}
const std::size_t EOL_state_ = ptr_[eol_index];
if (EOL_state_ && curr_ == end_)
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_start_state_ = *(ptr_ + state_index);
end_bol_ = bol_;
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
start_state_ = end_start_state_;
start_token_ = end_token_;
if (id_ == 0)
{
bol_ = end_bol_;
goto again;
}
else
{
_data.bol = end_bol_;
}
}
else
{
// No match causes char to be skipped
_data.bol = *start_token_ == '\n';
++start_token_;
id_ = npos;
uid_ = npos;
}
unique_id_ = uid_;
return id_;
}
std::size_t next (const detail::internals &internals_,
std::size_t &start_state_, FwdIter &start_token_,
FwdIter const &end_, std::size_t &unique_id_)
{
if (start_token_ == end_)
{
unique_id_ = npos;
return 0;
}
again:
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
front ();
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
FwdIter curr_ = start_token_;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
std::size_t end_start_state_ = start_state_;
FwdIter end_token_ = start_token_;
while (curr_ != end_)
{
const std::size_t state_ = ptr_[lookup_[static_cast
<typename Traits::index_type>(*curr_++)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_start_state_ = *(ptr_ + state_index);
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
start_state_ = end_start_state_;
start_token_ = end_token_;
if (id_ == 0) goto again;
}
else
{
// No match causes char to be skipped
++start_token_;
id_ = npos;
uid_ = npos;
}
unique_id_ = uid_;
return id_;
}
std::size_t next (const std::size_t * const lookup_,
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
bool bol_, FwdIter &start_token_, FwdIter const &end_,
std::size_t &unique_id_)
{
if (start_token_ == end_)
{
unique_id_ = npos;
return 0;
}
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
FwdIter curr_ = start_token_;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
bool end_bol_ = bol_;
FwdIter end_token_ = start_token_;
while (curr_ != end_)
{
const std::size_t BOL_state_ = ptr_[bol_index];
const std::size_t EOL_state_ = ptr_[eol_index];
if (BOL_state_ && bol_)
{
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
}
else if (EOL_state_ && *curr_ == '\n')
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
}
else
{
typename Traits::char_type prev_char_ = *curr_++;
bol_ = prev_char_ == '\n';
const std::size_t state_ =
ptr_[lookup_[static_cast<typename Traits::index_type>
(prev_char_)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
}
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_bol_ = bol_;
end_token_ = curr_;
}
}
const std::size_t EOL_state_ = ptr_[eol_index];
if (EOL_state_ && curr_ == end_)
{
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_bol_ = bol_;
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
_data.bol = end_bol_;
start_token_ = end_token_;
}
else
{
// No match causes char to be skipped
_data.bol = *start_token_ == '\n';
++start_token_;
id_ = npos;
uid_ = npos;
}
unique_id_ = uid_;
return id_;
}
std::size_t next (const std::size_t * const lookup_,
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
FwdIter &start_token_, FwdIter const &end_,
std::size_t &unique_id_)
{
if (start_token_ == end_)
{
unique_id_ = npos;
return 0;
}
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
FwdIter curr_ = start_token_;
bool end_state_ = *ptr_ != 0;
std::size_t id_ = *(ptr_ + id_index);
std::size_t uid_ = *(ptr_ + unique_id_index);
FwdIter end_token_ = start_token_;
while (curr_ != end_)
{
const std::size_t state_ = ptr_[lookup_[static_cast
<typename Traits::index_type>(*curr_++)]];
if (state_ == 0)
{
break;
}
ptr_ = &dfa_[state_ * dfa_alphabet_];
if (*ptr_)
{
end_state_ = true;
id_ = *(ptr_ + id_index);
uid_ = *(ptr_ + unique_id_index);
end_token_ = curr_;
}
}
if (end_state_)
{
// return longest match
start_token_ = end_token_;
}
else
{
// No match causes char to be skipped
++start_token_;
id_ = npos;
uid_ = npos;
}
unique_id_ = uid_;
return id_;
}
};
friend class iterator;
// Make it explict that we are NOT taking a copy of state_machine_!
basic_input (const basic_state_machine<typename Traits::char_type>
*state_machine_, const FwdIter &begin_, const FwdIter &end_) :
_state_machine (state_machine_),
_begin (begin_),
_end (end_)
{
}
iterator begin () const
{
iterator iter_;
iter_._input = this;
// Over-ride default of 0 (EOI)
iter_._data.id = npos;
iter_._data.start = _begin;
iter_._data.end = _begin;
iter_._data.bol = _state_machine->data ()._seen_BOL_assertion;
iter_._data.state = 0;
++iter_;
return iter_;
}
iterator end () const
{
iterator iter_;
iter_._input = this;
iter_._data.start = _end;
iter_._data.end = _end;
return iter_;
}
private:
const basic_state_machine<typename Traits::char_type> *_state_machine;
FwdIter _begin;
FwdIter _end;
};
typedef basic_input<std::string::iterator> iter_input;
typedef basic_input<std::basic_string<wchar_t>::iterator> iter_winput;
typedef basic_input<const char *> ptr_input;
typedef basic_input<const wchar_t *> ptr_winput;
}
}
#endif
@@ -0,0 +1,60 @@
// internals.hpp
// Copyright (c) 2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_INTERNALS_HPP
#define BOOST_LEXER_INTERNALS_HPP
#include "containers/ptr_vector.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
struct internals
{
typedef std::vector<std::size_t> size_t_vector;
typedef ptr_vector<size_t_vector> size_t_vector_vector;
size_t_vector_vector _lookup;
size_t_vector _dfa_alphabet;
size_t_vector_vector _dfa;
bool _seen_BOL_assertion;
bool _seen_EOL_assertion;
internals () :
_seen_BOL_assertion (false),
_seen_EOL_assertion (false)
{
}
void clear ()
{
_lookup.clear ();
_dfa_alphabet.clear ();
_dfa.clear ();
_seen_BOL_assertion = false;
_seen_EOL_assertion = false;
}
void swap (internals &internals_)
{
_lookup->swap (*internals_._lookup);
_dfa_alphabet.swap (internals_._dfa_alphabet);
_dfa->swap (*internals_._dfa);
std::swap (_seen_BOL_assertion, internals_._seen_BOL_assertion);
std::swap (_seen_EOL_assertion, internals_._seen_EOL_assertion);
}
private:
internals (const internals &); // No copy construction.
internals &operator = (const internals &); // No assignment.
};
}
}
}
#endif
@@ -0,0 +1,511 @@
// parser.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_PARSER_HPP
#define BOOST_LEXER_PARSER_HPP
#include <boost/assert.hpp>
#include "tree/end_node.hpp"
#include "tree/iteration_node.hpp"
#include "tree/leaf_node.hpp"
#include "../runtime_error.hpp"
#include "tree/selection_node.hpp"
#include "tree/sequence_node.hpp"
#include "../size_t.hpp"
#include "tokeniser/re_tokeniser.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
class basic_parser
{
public:
typedef basic_re_tokeniser<CharT> tokeniser;
typedef typename tokeniser::string string;
typedef std::map<string, const node *> macro_map;
typedef node::node_ptr_vector node_ptr_vector;
typedef typename tokeniser::num_token token;
/*
General principles of regex parsing:
- Every regex is a sequence of sub-regexes.
- Regexes consist of operands and operators
- All operators decompose to sequence, selection ('|') and iteration ('*')
- Regex tokens are stored on the stack.
- When a complete sequence of regex tokens is on the stack it is processed.
Grammar:
<REGEX> -> <OREXP>
<OREXP> -> <SEQUENCE> | <OREXP>'|'<SEQUENCE>
<SEQUENCE> -> <SUB>
<SUB> -> <EXPRESSION> | <SUB><EXPRESSION>
<EXPRESSION> -> <REPEAT>
<REPEAT> -> charset | macro | '('<REGEX>')' | <REPEAT><DUPLICATE>
<DUPLICATE> -> '?' | '*' | '+' | '{n[,[m]]}'
*/
static node *parse (const CharT *start_, const CharT * const end_,
const std::size_t id_, const std::size_t unique_id_,
const std::size_t dfa_state_, const regex_flags flags_,
const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
const macro_map &macromap_, typename tokeniser::token_map &map_,
bool &seen_BOL_assertion_, bool &seen_EOL_assertion_)
{
node *root_ = 0;
state state_ (start_, end_, flags_, locale_);
token lhs_token_;
token rhs_token_;
token_stack token_stack_;
tree_node_stack tree_node_stack_;
char action_ = 0;
token_stack_.push (rhs_token_);
tokeniser::next (state_, map_, rhs_token_);
do
{
lhs_token_ = token_stack_.top ();
action_ = lhs_token_.precedence (rhs_token_._type);
switch (action_)
{
case '<':
case '=':
token_stack_.push (rhs_token_);
tokeniser::next (state_, map_, rhs_token_);
break;
case '>':
reduce (token_stack_, macromap_, node_ptr_vector_,
tree_node_stack_);
break;
default:
std::ostringstream ss_;
ss_ << "A syntax error occurred: '" <<
lhs_token_.precedence_string () <<
"' against '" << rhs_token_.precedence_string () <<
"' at index " << state_.index () << ".";
throw runtime_error (ss_.str ().c_str ());
break;
}
} while (!token_stack_.empty ());
if (tree_node_stack_.empty ())
{
throw runtime_error ("Empty rules are not allowed.");
}
BOOST_ASSERT(tree_node_stack_.size () == 1);
node *lhs_node_ = tree_node_stack_.top ();
tree_node_stack_.pop ();
if (id_ == 0)
{
// Macros have no end state...
root_ = lhs_node_;
}
else
{
node_ptr_vector_->push_back (static_cast<end_node *>(0));
node *rhs_node_ = new end_node (id_, unique_id_, dfa_state_);
node_ptr_vector_->back () = rhs_node_;
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
node_ptr_vector_->back () = new sequence_node
(lhs_node_, rhs_node_);
root_ = node_ptr_vector_->back ();
}
// Done this way as bug in VC++ 6 prevents |= operator working
// properly!
if (state_._seen_BOL_assertion) seen_BOL_assertion_ = true;
if (state_._seen_EOL_assertion) seen_EOL_assertion_ = true;
return root_;
}
private:
typedef typename tokeniser::state state;
typedef std::stack<token> token_stack;
typedef node::node_stack tree_node_stack;
static void reduce (token_stack &token_stack_,
const macro_map &macromap_, node_ptr_vector &node_vector_ptr_,
tree_node_stack &tree_node_stack_)
{
typename tokeniser::num_token lhs_;
typename tokeniser::num_token rhs_;
token_stack handle_;
char action_ = 0;
do
{
rhs_ = token_stack_.top ();
token_stack_.pop ();
handle_.push (rhs_);
if (!token_stack_.empty ())
{
lhs_ = token_stack_.top ();
action_ = lhs_.precedence (rhs_._type);
}
} while (!token_stack_.empty () && action_ == '=');
BOOST_ASSERT(token_stack_.empty () || action_ == '<');
switch (rhs_._type)
{
case token::BEGIN:
// finished processing so exit
break;
case token::REGEX:
// finished parsing, nothing to do
break;
case token::OREXP:
orexp (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
break;
case token::SEQUENCE:
token_stack_.push (token::OREXP);
break;
case token::SUB:
sub (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
break;
case token::EXPRESSION:
token_stack_.push (token::SUB);
break;
case token::REPEAT:
repeat (handle_, token_stack_);
break;
case token::CHARSET:
charset (handle_, token_stack_, node_vector_ptr_,
tree_node_stack_);
break;
case token::MACRO:
macro (handle_, token_stack_, macromap_, node_vector_ptr_,
tree_node_stack_);
break;
case token::OPENPAREN:
openparen (handle_, token_stack_);
break;
case token::OPT:
case token::AOPT:
optional (rhs_._type == token::OPT, node_vector_ptr_,
tree_node_stack_);
token_stack_.push (token::DUP);
break;
case token::ZEROORMORE:
case token::AZEROORMORE:
zero_or_more (rhs_._type == token::ZEROORMORE, node_vector_ptr_,
tree_node_stack_);
token_stack_.push (token::DUP);
break;
case token::ONEORMORE:
case token::AONEORMORE:
one_or_more (rhs_._type == token::ONEORMORE, node_vector_ptr_,
tree_node_stack_);
token_stack_.push (token::DUP);
break;
case token::REPEATN:
case token::AREPEATN:
repeatn (rhs_._type == token::REPEATN, handle_.top (),
node_vector_ptr_, tree_node_stack_);
token_stack_.push (token::DUP);
break;
default:
throw runtime_error
("Internal error regex_parser::reduce");
break;
}
}
static void orexp (token_stack &handle_, token_stack &token_stack_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
BOOST_ASSERT(handle_.top ()._type == token::OREXP &&
(handle_.size () == 1 || handle_.size () == 3));
if (handle_.size () == 1)
{
token_stack_.push (token::REGEX);
}
else
{
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::OR);
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::SEQUENCE);
perform_or (node_ptr_vector_, tree_node_stack_);
token_stack_.push (token::OREXP);
}
}
static void sub (token_stack &handle_, token_stack &token_stack_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
BOOST_ASSERT(handle_.top ()._type == token::SUB &&
(handle_.size () == 1 || handle_.size () == 2));
if (handle_.size () == 1)
{
token_stack_.push (token::SEQUENCE);
}
else
{
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::EXPRESSION);
// perform join
sequence (node_ptr_vector_, tree_node_stack_);
token_stack_.push (token::SUB);
}
}
static void repeat (token_stack &handle_, token_stack &token_stack_)
{
BOOST_ASSERT(handle_.top ()._type == token::REPEAT &&
handle_.size () >= 1 && handle_.size () <= 3);
if (handle_.size () == 1)
{
token_stack_.push (token::EXPRESSION);
}
else
{
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::DUP);
token_stack_.push (token::REPEAT);
}
}
static void charset (token_stack &handle_, token_stack &token_stack_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
BOOST_ASSERT(handle_.top ()._type == token::CHARSET &&
handle_.size () == 1);
// store charset
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
const size_t id_ = handle_.top ()._id;
node_ptr_vector_->back () = new leaf_node (id_, true);
tree_node_stack_.push (node_ptr_vector_->back ());
token_stack_.push (token::REPEAT);
}
static void macro (token_stack &handle_, token_stack &token_stack_,
const macro_map &macromap_, node_ptr_vector &node_ptr_vector_,
tree_node_stack &tree_node_stack_)
{
token &top_ = handle_.top ();
BOOST_ASSERT(top_._type == token::MACRO && handle_.size () == 1);
typename macro_map::const_iterator iter_ =
macromap_.find (top_._macro);
if (iter_ == macromap_.end ())
{
const CharT *name_ = top_._macro;
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Unknown MACRO name '";
while (*name_)
{
os_ << ss_.narrow (*name_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
tree_node_stack_.push (iter_->second->copy (node_ptr_vector_));
token_stack_.push (token::REPEAT);
}
static void openparen (token_stack &handle_, token_stack &token_stack_)
{
BOOST_ASSERT(handle_.top ()._type == token::OPENPAREN &&
handle_.size () == 3);
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::REGEX);
handle_.pop ();
BOOST_ASSERT(handle_.top ()._type == token::CLOSEPAREN);
token_stack_.push (token::REPEAT);
}
static void perform_or (node_ptr_vector &node_ptr_vector_,
tree_node_stack &tree_node_stack_)
{
// perform or
node *rhs_ = tree_node_stack_.top ();
tree_node_stack_.pop ();
node *lhs_ = tree_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
tree_node_stack_.top () = node_ptr_vector_->back ();
}
static void sequence (node_ptr_vector &node_ptr_vector_,
tree_node_stack &tree_node_stack_)
{
node *rhs_ = tree_node_stack_.top ();
tree_node_stack_.pop ();
node *lhs_ = tree_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
tree_node_stack_.top () = node_ptr_vector_->back ();
}
static void optional (const bool greedy_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
// perform ?
node *lhs_ = tree_node_stack_.top ();
// You don't know if lhs_ is a leaf_node, so get firstpos.
node::node_vector &firstpos_ = lhs_->firstpos ();
for (node::node_vector::iterator iter_ = firstpos_.begin (),
end_ = firstpos_.end (); iter_ != end_; ++iter_)
{
// These are leaf_nodes!
(*iter_)->greedy (greedy_);
}
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
node *rhs_ = new leaf_node (null_token, greedy_);
node_ptr_vector_->back () = rhs_;
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
tree_node_stack_.top () = node_ptr_vector_->back ();
}
static void zero_or_more (const bool greedy_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
// perform *
node *ptr_ = tree_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
node_ptr_vector_->back () = new iteration_node (ptr_, greedy_);
tree_node_stack_.top () = node_ptr_vector_->back ();
}
static void one_or_more (const bool greedy_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
// perform +
node *lhs_ = tree_node_stack_.top ();
node *copy_ = lhs_->copy (node_ptr_vector_);
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
node *rhs_ = new iteration_node (copy_, greedy_);
node_ptr_vector_->back () = rhs_;
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
tree_node_stack_.top () = node_ptr_vector_->back ();
}
// This is one of the most mind bending routines in this code...
static void repeatn (const bool greedy_, const token &token_,
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
{
// perform {n[,[m]]}
// Semantic checks have already been performed.
// {0,} = *
// {0,1} = ?
// {1,} = +
// therefore we do not check for these cases.
if (!(token_._min == 1 && !token_._comma))
{
const std::size_t top_ = token_._min > 0 ?
token_._min : token_._max;
if (token_._min == 0)
{
optional (greedy_, node_ptr_vector_, tree_node_stack_);
}
node *prev_ = tree_node_stack_.top ()->copy (node_ptr_vector_);
node *curr_ = 0;
for (std::size_t i_ = 2; i_ < top_; ++i_)
{
curr_ = prev_->copy (node_ptr_vector_);
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
sequence (node_ptr_vector_, tree_node_stack_);
prev_ = curr_;
}
if (token_._comma && token_._min > 0)
{
if (token_._min > 1)
{
curr_ = prev_->copy (node_ptr_vector_);
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
sequence (node_ptr_vector_, tree_node_stack_);
prev_ = curr_;
}
if (token_._comma && token_._max)
{
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
optional (greedy_, node_ptr_vector_, tree_node_stack_);
prev_ = tree_node_stack_.top ();
tree_node_stack_.pop ();
const std::size_t count_ = token_._max - token_._min;
for (std::size_t i_ = 1; i_ < count_; ++i_)
{
curr_ = prev_->copy (node_ptr_vector_);
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
sequence (node_ptr_vector_, tree_node_stack_);
prev_ = curr_;
}
}
else
{
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
zero_or_more (greedy_, node_ptr_vector_, tree_node_stack_);
prev_ = tree_node_stack_.top ();
tree_node_stack_.pop ();
}
}
tree_node_stack_.push (static_cast<node *>(0));
tree_node_stack_.top () = prev_;
sequence (node_ptr_vector_, tree_node_stack_);
}
}
};
}
}
}
#endif
@@ -0,0 +1,146 @@
// num_token.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_NUM_TOKEN_HPP
#define BOOST_LEXER_NUM_TOKEN_HPP
#include <boost/config.hpp>
#include "../../consts.hpp" // null_token
#include "../../size_t.hpp"
#include <boost/detail/workaround.hpp>
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
struct basic_num_token
{
enum type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT,
DUP, OR, CHARSET, MACRO, OPENPAREN, CLOSEPAREN, OPT, AOPT,
ZEROORMORE, AZEROORMORE, ONEORMORE, AONEORMORE, REPEATN, AREPEATN,
END};
type _type;
std::size_t _id;
std::size_t _min;
bool _comma;
std::size_t _max;
CharT _macro[max_macro_len + 1];
static const char _precedence_table[END + 1][END + 1];
static const char *_precedence_strings[END + 1];
basic_num_token (const type type_ = BEGIN,
const std::size_t id_ = null_token) :
_type (type_),
_id (id_),
_min (0),
_comma (false),
_max (0)
{
*_macro = 0;
}
basic_num_token &operator = (const basic_num_token &rhs_)
{
_type = rhs_._type;
_id = rhs_._id;
_min = rhs_._min;
_comma = rhs_._comma;
_max = rhs_._max;
if (_type == MACRO)
{
const CharT *read_ = rhs_._macro;
CharT *write_ = _macro;
while (*read_)
{
*write_++ = *read_++;
}
*write_ = 0;
}
return *this;
}
void set (const type type_)
{
_type = type_;
_id = null_token;
}
void set (const type type_, const std::size_t id_)
{
_type = type_;
_id = id_;
}
void min_max (const std::size_t min_, const bool comma_,
const std::size_t max_)
{
_min = min_;
_comma = comma_;
_max = max_;
}
char precedence (const type type_) const
{
return _precedence_table[_type][type_];
}
const char *precedence_string () const
{
return _precedence_strings[_type];
}
};
template<typename CharT>
const char basic_num_token<CharT>::_precedence_table[END + 1][END + 1] = {
// BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP, | , CHR, MCR, ( , ) , ? , ?? , * , *? , + , +?, {n}?, {n}, END
/*BEGIN*/{' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/*REGEX*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/*OREXP*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* SEQ */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* SUB */{' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/*EXPRE*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* RPT */{' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '<', '<', '<', '<', '<', '<', '<', '<', '>'},
/*DUPLI*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* | */{' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
/*CHARA*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
/*MACRO*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
/* ( */{' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
/* ) */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
/* ? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* ?? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* * */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* *? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* + */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* +? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/*{n,m}*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/*{nm}?*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
/* END */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
};
template<typename CharT>
const char *basic_num_token<CharT>::_precedence_strings[END + 1] =
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(910))
{{"BEGIN"}, {"REGEX"}, {"OREXP"}, {"SEQUENCE"}, {"SUB"}, {"EXPRESSION"},
{"REPEAT"}, {"DUPLICATE"}, {"|"}, {"CHARSET"}, {"MACRO"},
{"("}, {")"}, {"?"}, {"??"}, {"*"}, {"*?"}, {"+"}, {"+?"}, {"{n[,[m]]}"},
{"{n[,[m]]}?"}, {"END"}};
#else
{"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", "REPEAT",
"DUPLICATE", "|", "CHARSET", "MACRO", "(", ")", "?", "??", "*", "*?",
"+", "+?", "{n[,[m]]}", "{n[,[m]]}?", "END"};
#endif
}
}
}
#endif
@@ -0,0 +1,574 @@
// tokeniser.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_RE_TOKENISER_HPP
#define BOOST_LEXER_RE_TOKENISER_HPP
// memcpy()
#include <cstring>
#include <map>
#include "num_token.hpp"
#include "../../runtime_error.hpp"
#include "../../size_t.hpp"
#include <sstream>
#include "../../string_token.hpp"
#include "re_tokeniser_helper.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
class basic_re_tokeniser
{
public:
typedef basic_num_token<CharT> num_token;
typedef basic_re_tokeniser_state<CharT> state;
typedef basic_string_token<CharT> string_token;
typedef typename string_token::string string;
typedef std::map<string_token, std::size_t> token_map;
typedef std::pair<string_token, std::size_t> token_pair;
static void next (state &state_, token_map &map_, num_token &token_)
{
CharT ch_ = 0;
bool eos_ = state_.next (ch_);
token_.min_max (0, false, 0);
while (!eos_ && ch_ == '"')
{
state_._in_string ^= 1;
eos_ = state_.next (ch_);
}
if (eos_)
{
if (state_._in_string)
{
throw runtime_error ("Unexpected end of regex "
"(missing '\"').");
}
if (state_._paren_count)
{
throw runtime_error ("Unexpected end of regex "
"(missing ')').");
}
token_.set (num_token::END, null_token);
}
else
{
if (ch_ == '\\')
{
// Even if we are in a string, respect escape sequences...
escape (state_, map_, token_);
}
else if (state_._in_string)
{
// All other meta characters lose their special meaning
// inside a string.
create_charset_token (string (1, ch_), false, map_, token_);
}
else
{
// Not an escape sequence and not inside a string, so
// check for meta characters.
switch (ch_)
{
case '(':
token_.set (num_token::OPENPAREN, null_token);
++state_._paren_count;
read_options (state_);
break;
case ')':
--state_._paren_count;
if (state_._paren_count < 0)
{
std::ostringstream ss_;
ss_ << "Number of open parenthesis < 0 at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
token_.set (num_token::CLOSEPAREN, null_token);
if (!state_._flags_stack.empty ())
{
state_._flags = state_._flags_stack.top ();
state_._flags_stack.pop ();
}
break;
case '?':
if (!state_.eos () && *state_._curr == '?')
{
token_.set (num_token::AOPT, null_token);
state_.increment ();
}
else
{
token_.set (num_token::OPT, null_token);
}
break;
case '*':
if (!state_.eos () && *state_._curr == '?')
{
token_.set (num_token::AZEROORMORE, null_token);
state_.increment ();
}
else
{
token_.set (num_token::ZEROORMORE, null_token);
}
break;
case '+':
if (!state_.eos () && *state_._curr == '?')
{
token_.set (num_token::AONEORMORE, null_token);
state_.increment ();
}
else
{
token_.set (num_token::ONEORMORE, null_token);
}
break;
case '{':
open_curly (state_, token_);
break;
case '|':
token_.set (num_token::OR, null_token);
break;
case '^':
if (state_._curr - 1 == state_._start)
{
token_.set (num_token::CHARSET, bol_token);
state_._seen_BOL_assertion = true;
}
else
{
create_charset_token (string (1, ch_), false,
map_, token_);
}
break;
case '$':
if (state_._curr == state_._end)
{
token_.set (num_token::CHARSET, eol_token);
state_._seen_EOL_assertion = true;
}
else
{
create_charset_token (string (1, ch_), false,
map_, token_);
}
break;
case '.':
{
string dot_;
if (state_._flags & dot_not_newline)
{
dot_ = '\n';
}
create_charset_token (dot_, true, map_, token_);
break;
}
case '[':
{
charset (state_, map_, token_);
break;
}
case '/':
throw runtime_error("Lookahead ('/') is not supported yet.");
break;
default:
if ((state_._flags & icase) &&
(std::isupper (ch_, state_._locale) ||
std::islower (ch_, state_._locale)))
{
CharT upper_ = std::toupper (ch_, state_._locale);
CharT lower_ = std::tolower (ch_, state_._locale);
string str_ (1, upper_);
str_ += lower_;
create_charset_token (str_, false, map_, token_);
}
else
{
create_charset_token (string (1, ch_), false,
map_, token_);
}
break;
}
}
}
}
private:
typedef basic_re_tokeniser_helper<CharT> tokeniser_helper;
static void read_options (state &state_)
{
if (!state_.eos () && *state_._curr == '?')
{
CharT ch_ = 0;
bool eos_ = false;
bool negate_ = false;
state_.increment ();
eos_ = state_.next (ch_);
state_._flags_stack.push (state_._flags);
while (!eos_ && ch_ != ':')
{
switch (ch_)
{
case '-':
negate_ ^= 1;
break;
case 'i':
if (negate_)
{
state_._flags = static_cast<regex_flags>
(state_._flags & ~icase);
}
else
{
state_._flags = static_cast<regex_flags>
(state_._flags | icase);
}
negate_ = false;
break;
case 's':
if (negate_)
{
state_._flags = static_cast<regex_flags>
(state_._flags | dot_not_newline);
}
else
{
state_._flags = static_cast<regex_flags>
(state_._flags & ~dot_not_newline);
}
negate_ = false;
break;
default:
{
std::ostringstream ss_;
ss_ << "Unknown option at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
}
eos_ = state_.next (ch_);
}
// End of string handler will handle early termination
}
else if (!state_._flags_stack.empty ())
{
state_._flags_stack.push (state_._flags);
}
}
static void escape (state &state_, token_map &map_, num_token &token_)
{
CharT ch_ = 0;
std::size_t str_len_ = 0;
const CharT *str_ = tokeniser_helper::escape_sequence (state_,
ch_, str_len_);
if (str_)
{
state state2_ (str_ + 1, str_ + str_len_, state_._flags,
state_._locale);
charset (state2_, map_, token_);
}
else
{
create_charset_token (string (1, ch_), false, map_, token_);
}
}
static void charset (state &state_, token_map &map_, num_token &token_)
{
string chars_;
bool negated_ = false;
tokeniser_helper::charset (state_, chars_, negated_);
create_charset_token (chars_, negated_, map_, token_);
}
static void create_charset_token (const string &charset_,
const bool negated_, token_map &map_, num_token &token_)
{
std::size_t id_ = null_token;
string_token stok_ (negated_, charset_);
stok_.remove_duplicates ();
stok_.normalise ();
typename token_map::const_iterator iter_ = map_.find (stok_);
if (iter_ == map_.end ())
{
id_ = map_.size ();
map_.insert (token_pair (stok_, id_));
}
else
{
id_ = iter_->second;
}
token_.set (num_token::CHARSET, id_);
}
static void open_curly (state &state_, num_token &token_)
{
if (state_.eos ())
{
throw runtime_error ("Unexpected end of regex "
"(missing '}').");
}
else if (*state_._curr >= '0' && *state_._curr <= '9')
{
repeat_n (state_, token_);
if (!state_.eos () && *state_._curr == '?')
{
token_._type = num_token::AREPEATN;
state_.increment ();
}
}
else
{
macro (state_, token_);
}
}
// SYNTAX:
// {n[,[n]]}
// SEMANTIC RULES:
// {0} - INVALID (throw exception)
// {0,} = *
// {0,0} - INVALID (throw exception)
// {0,1} = ?
// {1,} = +
// {min,max} where min == max - {min}
// {min,max} where max < min - INVALID (throw exception)
static void repeat_n (state &state_, num_token &token_)
{
CharT ch_ = 0;
bool eos_ = state_.next (ch_);
while (!eos_ && ch_ >= '0' && ch_ <= '9')
{
token_._min *= 10;
token_._min += ch_ - '0';
eos_ = state_.next (ch_);
}
if (eos_)
{
throw runtime_error ("Unexpected end of regex "
"(missing '}').");
}
bool min_max_ = false;
bool repeatn_ = true;
token_._comma = ch_ == ',';
if (token_._comma)
{
eos_ = state_.next (ch_);
if (eos_)
{
throw runtime_error ("Unexpected end of regex "
"(missing '}').");
}
if (ch_ == '}')
{
// Small optimisation: Check for '*' equivalency.
if (token_._min == 0)
{
token_.set (num_token::ZEROORMORE, null_token);
repeatn_ = false;
}
// Small optimisation: Check for '+' equivalency.
else if (token_._min == 1)
{
token_.set (num_token::ONEORMORE, null_token);
repeatn_ = false;
}
}
else
{
if (ch_ < '0' || ch_ > '9')
{
std::ostringstream ss_;
ss_ << "Missing '}' at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
min_max_ = true;
do
{
token_._max *= 10;
token_._max += ch_ - '0';
eos_ = state_.next (ch_);
} while (!eos_ && ch_ >= '0' && ch_ <= '9');
if (eos_)
{
throw runtime_error ("Unexpected end of regex "
"(missing '}').");
}
// Small optimisation: Check for '?' equivalency.
if (token_._min == 0 && token_._max == 1)
{
token_.set (num_token::OPT, null_token);
repeatn_ = false;
}
// Small optimisation: if min == max, then min.
else if (token_._min == token_._max)
{
token_._comma = false;
min_max_ = false;
token_._max = 0;
}
}
}
if (ch_ != '}')
{
std::ostringstream ss_;
ss_ << "Missing '}' at index " << state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
if (repeatn_)
{
// SEMANTIC VALIDATION follows:
// NOTE: {0,} has already become *
// therefore we don't check for a comma.
if (token_._min == 0 && token_._max == 0)
{
std::ostringstream ss_;
ss_ << "Cannot have exactly zero repeats preceding index " <<
state_.index () << '.';
throw runtime_error (ss_.str ().c_str ());
}
if (min_max_ && token_._max < token_._min)
{
std::ostringstream ss_;
ss_ << "Max less than min preceding index " <<
state_.index () << '.';
throw runtime_error (ss_.str ().c_str ());
}
token_.set (num_token::REPEATN, null_token);
}
}
static void macro (state &state_, num_token &token_)
{
CharT ch_ = 0;
bool eos_ = false;
const CharT *start_ = state_._curr;
state_.next (ch_);
if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') &&
!(ch_ >= 'a' && ch_ <= 'z'))
{
std::ostringstream ss_;
ss_ << "Invalid MACRO name at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
do
{
eos_ = state_.next (ch_);
if (eos_)
{
throw runtime_error ("Unexpected end of regex "
"(missing '}').");
}
} while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') ||
(ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9'));
if (ch_ != '}')
{
std::ostringstream ss_;
ss_ << "Missing '}' at index " << state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
std::size_t len_ = state_._curr - 1 - start_;
if (len_ > max_macro_len)
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "MACRO name '";
while (len_)
{
os_ << ss_.narrow (*start_++, ' ');
--len_;
}
os_ << "' too long.";
throw runtime_error (os_.str ());
}
token_.set (num_token::MACRO, null_token);
// Some systems have memcpy in namespace std.
using namespace std;
memcpy (token_._macro, start_, len_ * sizeof (CharT));
token_._macro[len_] = 0;
}
};
}
}
}
#endif
@@ -0,0 +1,549 @@
// tokeniser_helper.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_RE_TOKENISER_HELPER_H
#define BOOST_LEXER_RE_TOKENISER_HELPER_H
#include "../../char_traits.hpp"
// strlen()
#include <cstring>
#include "../../size_t.hpp"
#include "re_tokeniser_state.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT, typename Traits = char_traits<CharT> >
class basic_re_tokeniser_helper
{
public:
typedef basic_re_tokeniser_state<CharT> state;
typedef std::basic_string<CharT> string;
static const CharT *escape_sequence (state &state_, CharT &ch_,
std::size_t &str_len_)
{
bool eos_ = state_.eos ();
if (eos_)
{
throw runtime_error ("Unexpected end of regex "
"following '\\'.");
}
const CharT *str_ = charset_shortcut (*state_._curr, str_len_);
if (str_)
{
state_.increment ();
}
else
{
ch_ = chr (state_);
}
return str_;
}
// This function can call itself.
static void charset (state &state_, string &chars_, bool &negated_)
{
CharT ch_ = 0;
bool eos_ = state_.next (ch_);
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex "
"following '['.");
}
negated_ = ch_ == '^';
if (negated_)
{
eos_ = state_.next (ch_);
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex "
"following '^'.");
}
}
bool chset_ = false;
CharT prev_ = 0;
while (ch_ != ']')
{
if (ch_ == '\\')
{
std::size_t str_len_ = 0;
const CharT *str_ = escape_sequence (state_, prev_, str_len_);
chset_ = str_ != 0;
if (chset_)
{
state temp_state_ (str_ + 1, str_ + str_len_,
state_._flags, state_._locale);
string temp_chars_;
bool temp_negated_ = false;
charset (temp_state_, temp_chars_, temp_negated_);
if (negated_ != temp_negated_)
{
std::ostringstream ss_;
ss_ << "Mismatch in charset negation preceding "
"index " << state_.index () << '.';
throw runtime_error (ss_.str ().c_str ());
}
chars_ += temp_chars_;
}
}
/*
else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
{
// TODO: POSIX charsets
}
*/
else
{
chset_ = false;
prev_ = ch_;
}
eos_ = state_.next (ch_);
// Covers preceding if, else if and else
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex "
"(missing ']').");
}
if (ch_ == '-')
{
charset_range (chset_, state_, eos_, ch_, prev_, chars_);
}
else if (!chset_)
{
if ((state_._flags & icase) &&
(std::isupper (prev_, state_._locale) ||
std::islower (prev_, state_._locale)))
{
CharT upper_ = std::toupper (prev_, state_._locale);
CharT lower_ = std::tolower (prev_, state_._locale);
chars_ += upper_;
chars_ += lower_;
}
else
{
chars_ += prev_;
}
}
}
if (!negated_ && chars_.empty ())
{
throw runtime_error ("Empty charsets not allowed.");
}
}
static CharT chr (state &state_)
{
CharT ch_ = 0;
// eos_ has already been checked for.
switch (*state_._curr)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
ch_ = decode_octal (state_);
break;
case 'a':
ch_ = '\a';
state_.increment ();
break;
case 'b':
ch_ = '\b';
state_.increment ();
break;
case 'c':
ch_ = decode_control_char (state_);
break;
case 'e':
ch_ = 27; // '\e' not recognised by compiler
state_.increment ();
break;
case 'f':
ch_ = '\f';
state_.increment ();
break;
case 'n':
ch_ = '\n';
state_.increment ();
break;
case 'r':
ch_ = '\r';
state_.increment ();
break;
case 't':
ch_ = '\t';
state_.increment ();
break;
case 'v':
ch_ = '\v';
state_.increment ();
break;
case 'x':
ch_ = decode_hex (state_);
break;
default:
ch_ = *state_._curr;
state_.increment ();
break;
}
return ch_;
}
private:
static const char *charset_shortcut (const char ch_,
std::size_t &str_len_)
{
const char *str_ = 0;
switch (ch_)
{
case 'd':
str_ = "[0-9]";
break;
case 'D':
str_ = "[^0-9]";
break;
case 's':
str_ = "[ \t\n\r\f\v]";
break;
case 'S':
str_ = "[^ \t\n\r\f\v]";
break;
case 'w':
str_ = "[_0-9A-Za-z]";
break;
case 'W':
str_ = "[^_0-9A-Za-z]";
break;
}
if (str_)
{
// Some systems have strlen in namespace std.
using namespace std;
str_len_ = strlen (str_);
}
else
{
str_len_ = 0;
}
return str_;
}
static const wchar_t *charset_shortcut (const wchar_t ch_,
std::size_t &str_len_)
{
const wchar_t *str_ = 0;
switch (ch_)
{
case 'd':
str_ = L"[0-9]";
break;
case 'D':
str_ = L"[^0-9]";
break;
case 's':
str_ = L"[ \t\n\r\f\v]";
break;
case 'S':
str_ = L"[^ \t\n\r\f\v]";
break;
case 'w':
str_ = L"[_0-9A-Za-z]";
break;
case 'W':
str_ = L"[^_0-9A-Za-z]";
break;
}
if (str_)
{
// Some systems have wcslen in namespace std.
using namespace std;
str_len_ = wcslen (str_);
}
else
{
str_len_ = 0;
}
return str_;
}
static CharT decode_octal (state &state_)
{
std::size_t accumulator_ = 0;
CharT ch_ = *state_._curr;
unsigned short count_ = 3;
bool eos_ = false;
for (;;)
{
accumulator_ *= 8;
accumulator_ += ch_ - '0';
--count_;
state_.increment ();
eos_ = state_.eos ();
if (!count_ || eos_) break;
ch_ = *state_._curr;
// Don't consume invalid chars!
if (ch_ < '0' || ch_ > '7')
{
break;
}
}
return static_cast<CharT> (accumulator_);
}
static CharT decode_control_char (state &state_)
{
// Skip over 'c'
state_.increment ();
CharT ch_ = 0;
bool eos_ = state_.next (ch_);
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex following \\c.");
}
else
{
if (ch_ >= 'a' && ch_ <= 'z')
{
ch_ -= 'a' - 1;
}
else if (ch_ >= 'A' && ch_ <= 'Z')
{
ch_ -= 'A' - 1;
}
else if (ch_ == '@')
{
// Apparently...
ch_ = 0;
}
else
{
std::ostringstream ss_;
ss_ << "Invalid control char at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
}
return ch_;
}
static CharT decode_hex (state &state_)
{
// Skip over 'x'
state_.increment ();
CharT ch_ = 0;
bool eos_ = state_.next (ch_);
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex following \\x.");
}
if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') ||
(ch_ >= 'A' && ch_ <= 'F')))
{
std::ostringstream ss_;
ss_ << "Illegal char following \\x at index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
std::size_t hex_ = 0;
do
{
hex_ *= 16;
if (ch_ >= '0' && ch_ <= '9')
{
hex_ += ch_ - '0';
}
else if (ch_ >= 'a' && ch_ <= 'f')
{
hex_ += 10 + (ch_ - 'a');
}
else
{
hex_ += 10 + (ch_ - 'A');
}
eos_ = state_.eos ();
if (!eos_)
{
ch_ = *state_._curr;
// Don't consume invalid chars!
if (((ch_ >= '0' && ch_ <= '9') ||
(ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F')))
{
state_.increment ();
}
else
{
eos_ = true;
}
}
} while (!eos_);
return static_cast<CharT> (hex_);
}
static void charset_range (const bool chset_, state &state_, bool &eos_,
CharT &ch_, const CharT prev_, string &chars_)
{
if (chset_)
{
std::ostringstream ss_;
ss_ << "Charset cannot form start of range preceding "
"index " << state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
eos_ = state_.next (ch_);
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex "
"following '-'.");
}
CharT curr_ = 0;
if (ch_ == '\\')
{
std::size_t str_len_ = 0;
if (escape_sequence (state_, curr_, str_len_))
{
std::ostringstream ss_;
ss_ << "Charset cannot form end of range preceding index "
<< state_.index () << '.';
throw runtime_error (ss_.str ().c_str ());
}
}
/*
else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
{
std::ostringstream ss_;
ss_ << "POSIX char class cannot form end of range at "
"index " << state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
*/
else
{
curr_ = ch_;
}
eos_ = state_.next (ch_);
// Covers preceding if and else
if (eos_)
{
// Pointless returning index if at end of string
throw runtime_error ("Unexpected end of regex "
"(missing ']').");
}
std::size_t start_ = static_cast<typename Traits::index_type> (prev_);
std::size_t end_ = static_cast<typename Traits::index_type> (curr_);
// Semanic check
if (end_ < start_)
{
std::ostringstream ss_;
ss_ << "Invalid range in charset preceding index " <<
state_.index () - 1 << '.';
throw runtime_error (ss_.str ().c_str ());
}
chars_.reserve (chars_.size () + (end_ + 1 - start_));
for (; start_ <= end_; ++start_)
{
CharT ch_ = static_cast<CharT> (start_);
if ((state_._flags & icase) &&
(std::isupper (ch_, state_._locale) ||
std::islower (ch_, state_._locale)))
{
CharT upper_ = std::toupper (ch_, state_._locale);
CharT lower_ = std::tolower (ch_, state_._locale);
chars_ += (upper_);
chars_ += (lower_);
}
else
{
chars_ += (ch_);
}
}
}
};
}
}
}
#endif
@@ -0,0 +1,98 @@
// tokeniser_state.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_RE_TOKENISER_STATE_HPP
#define BOOST_LEXER_RE_TOKENISER_STATE_HPP
#include "../../consts.hpp"
#include <locale>
#include "../../size_t.hpp"
#include <stack>
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
struct basic_re_tokeniser_state
{
const CharT * const _start;
const CharT * const _end;
const CharT *_curr;
regex_flags _flags;
std::stack<regex_flags> _flags_stack;
std::locale _locale;
long _paren_count;
bool _in_string;
bool _seen_BOL_assertion;
bool _seen_EOL_assertion;
basic_re_tokeniser_state (const CharT *start_, const CharT * const end_,
const regex_flags flags_, const std::locale locale_) :
_start (start_),
_end (end_),
_curr (start_),
_flags (flags_),
_locale (locale_),
_paren_count (0),
_in_string (false),
_seen_BOL_assertion (false),
_seen_EOL_assertion (false)
{
}
// prevent VC++ 7.1 warning:
const basic_re_tokeniser_state &operator =
(const basic_re_tokeniser_state &rhs_)
{
_start = rhs_._start;
_end = rhs_._end;
_curr = rhs_._curr;
_flags = rhs_._flags;
_locale = rhs_._locale;
_paren_count = rhs_._paren_count;
_in_string = rhs_._in_string;
_seen_BOL_assertion = rhs_._seen_BOL_assertion;
_seen_EOL_assertion = rhs_._seen_EOL_assertion;
return this;
}
inline bool next (CharT &ch_)
{
if (_curr >= _end)
{
ch_ = 0;
return true;
}
else
{
ch_ = *_curr;
increment ();
return false;
}
}
inline void increment ()
{
++_curr;
}
inline std::size_t index ()
{
return _curr - _start;
}
inline bool eos ()
{
return _curr >= _end;
}
};
}
}
}
#endif
@@ -0,0 +1,90 @@
// end_node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_END_NODE_HPP
#define BOOST_LEXER_END_NODE_HPP
#include "node.hpp"
#include "../../size_t.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
class end_node : public node
{
public:
end_node (const std::size_t id_, const std::size_t unique_id_,
const std::size_t lexer_state_) :
node (false),
_id (id_),
_unique_id (unique_id_),
_lexer_state (lexer_state_)
{
node::_firstpos.push_back (this);
node::_lastpos.push_back (this);
}
virtual ~end_node ()
{
}
virtual type what_type () const
{
return END;
}
virtual bool traverse (const_node_stack &/*node_stack_*/,
bool_stack &/*perform_op_stack_*/) const
{
return false;
}
virtual const node_vector &followpos () const
{
// _followpos is always empty..!
return _followpos;
}
virtual bool end_state () const
{
return true;
}
virtual std::size_t id () const
{
return _id;
}
virtual std::size_t unique_id () const
{
return _unique_id;
}
virtual std::size_t lexer_state () const
{
return _lexer_state;
}
private:
std::size_t _id;
std::size_t _unique_id;
std::size_t _lexer_state;
node_vector _followpos;
virtual void copy_node (node_ptr_vector &/*node_ptr_vector_*/,
node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/,
bool &/*down_*/) const
{
// Nothing to do, as end_nodes are not copied.
}
};
}
}
}
#endif
@@ -0,0 +1,90 @@
// iteration_node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_ITERATION_NODE_HPP
#define BOOST_LEXER_ITERATION_NODE_HPP
#include "node.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
class iteration_node : public node
{
public:
iteration_node (node *next_, const bool greedy_) :
node (true),
_next (next_),
_greedy (greedy_)
{
node_vector::iterator iter_;
node_vector::iterator end_;
_next->append_firstpos (_firstpos);
_next->append_lastpos (_lastpos);
for (iter_ = _lastpos.begin (), end_ = _lastpos.end ();
iter_ != end_; ++iter_)
{
(*iter_)->append_followpos (_firstpos);
}
for (iter_ = _firstpos.begin (), end_ = _firstpos.end ();
iter_ != end_; ++iter_)
{
(*iter_)->greedy (greedy_);
}
}
virtual ~iteration_node ()
{
}
virtual type what_type () const
{
return ITERATION;
}
virtual bool traverse (const_node_stack &node_stack_,
bool_stack &perform_op_stack_) const
{
perform_op_stack_.push (true);
node_stack_.push (_next);
return true;
}
private:
// Not owner of this pointer...
node *_next;
bool _greedy;
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
bool &down_) const
{
if (perform_op_stack_.top ())
{
node *ptr_ = new_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
node_ptr_vector_->back () = new iteration_node (ptr_, _greedy);
new_node_stack_.top () = node_ptr_vector_->back ();
}
else
{
down_ = true;
}
perform_op_stack_.pop ();
}
};
}
}
}
#endif
@@ -0,0 +1,107 @@
// leaf_node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_LEAF_NODE_HPP
#define BOOST_LEXER_LEAF_NODE_HPP
#include "../../consts.hpp" // null_token
#include "node.hpp"
#include "../../size_t.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
class leaf_node : public node
{
public:
leaf_node (const std::size_t token_, const bool greedy_) :
node (token_ == null_token),
_token (token_),
_set_greedy (!greedy_),
_greedy (greedy_)
{
if (!_nullable)
{
_firstpos.push_back (this);
_lastpos.push_back (this);
}
}
virtual ~leaf_node ()
{
}
virtual void append_followpos (const node_vector &followpos_)
{
for (node_vector::const_iterator iter_ = followpos_.begin (),
end_ = followpos_.end (); iter_ != end_; ++iter_)
{
_followpos.push_back (*iter_);
}
}
virtual type what_type () const
{
return LEAF;
}
virtual bool traverse (const_node_stack &/*node_stack_*/,
bool_stack &/*perform_op_stack_*/) const
{
return false;
}
virtual std::size_t token () const
{
return _token;
}
virtual void greedy (const bool greedy_)
{
if (!_set_greedy)
{
_greedy = greedy_;
_set_greedy = true;
}
}
virtual bool greedy () const
{
return _greedy;
}
virtual const node_vector &followpos () const
{
return _followpos;
}
virtual node_vector &followpos ()
{
return _followpos;
}
private:
std::size_t _token;
bool _set_greedy;
bool _greedy;
node_vector _followpos;
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/,
bool &/*down_*/) const
{
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
node_ptr_vector_->back () = new leaf_node (_token, _greedy);
new_node_stack_.push (node_ptr_vector_->back ());
}
};
}
}
}
#endif
@@ -0,0 +1,188 @@
// node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_NODE_HPP
#define BOOST_LEXER_NODE_HPP
#include <boost/assert.hpp>
#include "../../containers/ptr_vector.hpp"
#include "../../runtime_error.hpp"
#include "../../size_t.hpp"
#include <stack>
#include <vector>
namespace boost
{
namespace lexer
{
namespace detail
{
class node
{
public:
enum type {LEAF, SEQUENCE, SELECTION, ITERATION, END};
typedef std::stack<bool> bool_stack;
typedef std::stack<node *> node_stack;
// stack and vector not owner of node pointers
typedef std::stack<const node *> const_node_stack;
typedef std::vector<node *> node_vector;
typedef ptr_vector<node> node_ptr_vector;
node () :
_nullable (false)
{
}
node (const bool nullable_) :
_nullable (nullable_)
{
}
virtual ~node ()
{
}
bool nullable () const
{
return _nullable;
}
void append_firstpos (node_vector &firstpos_) const
{
firstpos_.insert (firstpos_.end (),
_firstpos.begin (), _firstpos.end ());
}
void append_lastpos (node_vector &lastpos_) const
{
lastpos_.insert (lastpos_.end (),
_lastpos.begin (), _lastpos.end ());
}
virtual void append_followpos (const node_vector &/*followpos_*/)
{
throw runtime_error ("Internal error node::append_followpos()");
}
node *copy (node_ptr_vector &node_ptr_vector_) const
{
node *new_root_ = 0;
const_node_stack node_stack_;
bool_stack perform_op_stack_;
bool down_ = true;
node_stack new_node_stack_;
node_stack_.push (this);
while (!node_stack_.empty ())
{
while (down_)
{
down_ = node_stack_.top ()->traverse (node_stack_,
perform_op_stack_);
}
while (!down_ && !node_stack_.empty ())
{
const node *top_ = node_stack_.top ();
top_->copy_node (node_ptr_vector_, new_node_stack_,
perform_op_stack_, down_);
if (!down_) node_stack_.pop ();
}
}
BOOST_ASSERT(new_node_stack_.size () == 1);
new_root_ = new_node_stack_.top ();
new_node_stack_.pop ();
return new_root_;
}
virtual type what_type () const = 0;
virtual bool traverse (const_node_stack &node_stack_,
bool_stack &perform_op_stack_) const = 0;
node_vector &firstpos ()
{
return _firstpos;
}
const node_vector &firstpos () const
{
return _firstpos;
}
// _lastpos modified externally, so not const &
node_vector &lastpos ()
{
return _lastpos;
}
virtual bool end_state () const
{
return false;
}
virtual std::size_t id () const
{
throw runtime_error ("Internal error node::id()");
}
virtual std::size_t unique_id () const
{
throw runtime_error ("Internal error node::unique_id()");
}
virtual std::size_t lexer_state () const
{
throw runtime_error ("Internal error node::state()");
}
virtual std::size_t token () const
{
throw runtime_error ("Internal error node::token()");
}
virtual void greedy (const bool /*greedy_*/)
{
throw runtime_error ("Internal error node::token(bool)");
}
virtual bool greedy () const
{
throw runtime_error ("Internal error node::token()");
}
virtual const node_vector &followpos () const
{
throw runtime_error ("Internal error node::followpos()");
}
virtual node_vector &followpos ()
{
throw runtime_error ("Internal error node::followpos()");
}
protected:
const bool _nullable;
node_vector _firstpos;
node_vector _lastpos;
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
bool &down_) const = 0;
private:
node (node const &); // No copy construction.
node &operator = (node const &); // No assignment.
};
}
}
}
#endif
@@ -0,0 +1,94 @@
// selection_node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_SELECTION_NODE_HPP
#define BOOST_LEXER_SELECTION_NODE_HPP
#include "node.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
class selection_node : public node
{
public:
selection_node (node *left_, node *right_) :
node (left_->nullable () || right_->nullable ()),
_left (left_),
_right (right_)
{
_left->append_firstpos (_firstpos);
_right->append_firstpos (_firstpos);
_left->append_lastpos (_lastpos);
_right->append_lastpos (_lastpos);
}
virtual ~selection_node ()
{
}
virtual type what_type () const
{
return SELECTION;
}
virtual bool traverse (const_node_stack &node_stack_,
bool_stack &perform_op_stack_) const
{
perform_op_stack_.push (true);
switch (_right->what_type ())
{
case SEQUENCE:
case SELECTION:
case ITERATION:
perform_op_stack_.push (false);
break;
default:
break;
}
node_stack_.push (_right);
node_stack_.push (_left);
return true;
}
private:
// Not owner of these pointers...
node *_left;
node *_right;
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
bool &down_) const
{
if (perform_op_stack_.top ())
{
node *rhs_ = new_node_stack_.top ();
new_node_stack_.pop ();
node *lhs_ = new_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
new_node_stack_.top () = node_ptr_vector_->back ();
}
else
{
down_ = true;
}
perform_op_stack_.pop ();
}
};
}
}
}
#endif
@@ -0,0 +1,112 @@
// sequence_node.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_SEQUENCE_NODE_HPP
#define BOOST_LEXER_SEQUENCE_NODE_HPP
#include "node.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
class sequence_node : public node
{
public:
sequence_node (node *left_, node *right_) :
node (left_->nullable () && right_->nullable ()),
_left (left_),
_right (right_)
{
_left->append_firstpos (_firstpos);
if (_left->nullable ())
{
_right->append_firstpos (_firstpos);
}
if (_right->nullable ())
{
_left->append_lastpos (_lastpos);
}
_right->append_lastpos (_lastpos);
node_vector &lastpos_ = _left->lastpos ();
const node_vector &firstpos_ = _right->firstpos ();
for (node_vector::iterator iter_ = lastpos_.begin (),
end_ = lastpos_.end (); iter_ != end_; ++iter_)
{
(*iter_)->append_followpos (firstpos_);
}
}
virtual ~sequence_node ()
{
}
virtual type what_type () const
{
return SEQUENCE;
}
virtual bool traverse (const_node_stack &node_stack_,
bool_stack &perform_op_stack_) const
{
perform_op_stack_.push (true);
switch (_right->what_type ())
{
case SEQUENCE:
case SELECTION:
case ITERATION:
perform_op_stack_.push (false);
break;
default:
break;
}
node_stack_.push (_right);
node_stack_.push (_left);
return true;
}
private:
// Not owner of these pointers...
node *_left;
node *_right;
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
bool &down_) const
{
if (perform_op_stack_.top ())
{
node *rhs_ = new_node_stack_.top ();
new_node_stack_.pop ();
node *lhs_ = new_node_stack_.top ();
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
new_node_stack_.top () = node_ptr_vector_->back ();
}
else
{
down_ = true;
}
perform_op_stack_.pop ();
}
};
}
}
}
#endif
@@ -0,0 +1,81 @@
// charset.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_CHARSET_HPP
#define BOOST_LEXER_CHARSET_HPP
#include <set>
#include "../size_t.hpp"
#include "../string_token.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
template<typename CharT>
struct basic_charset
{
typedef basic_string_token<CharT> token;
typedef std::set<std::size_t> index_set;
token _token;
index_set _index_set;
basic_charset ()
{
}
basic_charset (const token &token_, const std::size_t index_) :
_token (token_)
{
_index_set.insert (index_);
}
bool empty () const
{
return _token.empty () && _index_set.empty ();
}
void intersect (basic_charset &rhs_, basic_charset &overlap_)
{
_token.intersect (rhs_._token, overlap_._token);
if (!overlap_._token.empty ())
{
typename index_set::const_iterator iter_ = _index_set.begin ();
typename index_set::const_iterator end_ = _index_set.end ();
for (; iter_ != end_; ++iter_)
{
overlap_._index_set.insert (*iter_);
}
iter_ = rhs_._index_set.begin ();
end_ = rhs_._index_set.end ();
for (; iter_ != end_; ++iter_)
{
overlap_._index_set.insert (*iter_);
}
if (_token.empty ())
{
_index_set.clear ();
}
if (rhs_._token.empty ())
{
rhs_._index_set.clear ();
}
}
}
};
}
}
}
#endif
@@ -0,0 +1,140 @@
// equivset.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_EQUIVSET_HPP
#define BOOST_LEXER_EQUIVSET_HPP
#include <algorithm>
#include "../parser/tree/node.hpp"
#include <set>
#include "../size_t.hpp"
namespace boost
{
namespace lexer
{
namespace detail
{
struct equivset
{
typedef std::set<std::size_t> index_set;
typedef std::vector<std::size_t> index_vector;
// Not owner of nodes:
typedef std::vector<node *> node_vector;
index_vector _index_vector;
bool _greedy;
std::size_t _id;
node_vector _followpos;
equivset () :
_greedy (true),
_id (0)
{
}
equivset (const index_set &index_set_, const bool greedy_,
const std::size_t id_, const node_vector &followpos_) :
_greedy (greedy_),
_id (id_),
_followpos (followpos_)
{
index_set::const_iterator iter_ = index_set_.begin ();
index_set::const_iterator end_ = index_set_.end ();
for (; iter_ != end_; ++iter_)
{
_index_vector.push_back (*iter_);
}
}
bool empty () const
{
return _index_vector.empty () && _followpos.empty ();
}
void intersect (equivset &rhs_, equivset &overlap_)
{
intersect_indexes (rhs_._index_vector, overlap_._index_vector);
if (!overlap_._index_vector.empty ())
{
// Note that the LHS takes priority in order to
// respect rule ordering priority in the lex spec.
overlap_._id = _id;
overlap_._greedy = _greedy;
overlap_._followpos = _followpos;
node_vector::const_iterator overlap_begin_ =
overlap_._followpos.begin ();
node_vector::const_iterator overlap_end_ =
overlap_._followpos.end ();
node_vector::const_iterator rhs_iter_ =
rhs_._followpos.begin ();
node_vector::const_iterator rhs_end_ =
rhs_._followpos.end ();
for (; rhs_iter_ != rhs_end_; ++rhs_iter_)
{
node *node_ = *rhs_iter_;
if (std::find (overlap_begin_, overlap_end_, node_) ==
overlap_end_)
{
overlap_._followpos.push_back (node_);
overlap_begin_ = overlap_._followpos.begin ();
overlap_end_ = overlap_._followpos.end ();
}
}
if (_index_vector.empty ())
{
_followpos.clear ();
}
if (rhs_._index_vector.empty ())
{
rhs_._followpos.clear ();
}
}
}
private:
void intersect_indexes (index_vector &rhs_, index_vector &overlap_)
{
index_vector::iterator iter_ = _index_vector.begin ();
index_vector::iterator end_ = _index_vector.end ();
index_vector::iterator rhs_iter_ = rhs_.begin ();
index_vector::iterator rhs_end_ = rhs_.end ();
while (iter_ != end_ && rhs_iter_ != rhs_end_)
{
const std::size_t index_ = *iter_;
const std::size_t rhs_index_ = *rhs_iter_;
if (index_ < rhs_index_)
{
++iter_;
}
else if (index_ > rhs_index_)
{
++rhs_iter_;
}
else
{
overlap_.push_back (index_);
iter_ = _index_vector.erase (iter_);
end_ = _index_vector.end ();
rhs_iter_ = rhs_.erase (rhs_iter_);
rhs_end_ = rhs_.end ();
}
}
}
};
}
}
}
#endif
@@ -0,0 +1,806 @@
// rules.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_RULES_HPP
#define BOOST_LEXER_RULES_HPP
#include "consts.hpp"
#include <deque>
#include <locale>
#include <map>
#include "runtime_error.hpp"
#include <set>
#include "size_t.hpp"
#include <sstream>
#include <string>
#include <vector>
namespace boost
{
namespace lexer
{
namespace detail
{
// return name of initial state
template <typename CharT>
struct strings;
template <>
struct strings<char>
{
static const char *initial ()
{
return "INITIAL";
}
static const char *dot ()
{
return ".";
}
static const char *all_states ()
{
return "*";
}
static const char *char_name ()
{
return "char";
}
static const char *char_prefix ()
{
return "";
}
};
template <>
struct strings<wchar_t>
{
static const wchar_t *initial ()
{
return L"INITIAL";
}
static const wchar_t *dot ()
{
return L".";
}
static const wchar_t *all_states ()
{
return L"*";
}
static const char *char_name ()
{
return "wchar_t";
}
static const char *char_prefix ()
{
return "L";
}
};
}
template<typename CharT>
class basic_rules
{
public:
typedef std::vector<std::size_t> id_vector;
typedef std::deque<id_vector> id_vector_deque;
typedef std::basic_string<CharT> string;
typedef std::deque<string> string_deque;
typedef std::deque<string_deque> string_deque_deque;
typedef std::set<string> string_set;
typedef std::pair<string, string> string_pair;
typedef std::deque<string_pair> string_pair_deque;
typedef std::map<string, std::size_t> string_size_t_map;
typedef std::pair<string, std::size_t> string_size_t_pair;
basic_rules (const regex_flags flags_ = dot_not_newline,
std::size_t (*counter_ptr_) () = 0) :
_flags (flags_),
_counter (0),
_counter_ptr (counter_ptr_)
{
add_state (initial ());
}
void clear ()
{
_statemap.clear ();
_macrodeque.clear ();
_macroset.clear ();
_regexes.clear ();
_ids.clear ();
_unique_ids.clear ();
_states.clear ();
_flags = dot_not_newline;
_locale = std::locale ();
add_state (initial ());
}
void clear (const CharT *state_name_)
{
std::size_t state_ = state (state_name_);
if (state_ != npos)
{
_regexes[state_].clear ();
_ids[state_].clear ();
_unique_ids[state_].clear ();
_states[state_].clear ();
}
}
void flags (const regex_flags flags_)
{
_flags = flags_;
}
regex_flags flags () const
{
return _flags;
}
std::size_t next_unique_id ()
{
return _counter_ptr ? _counter_ptr () : _counter++;
}
std::locale imbue (std::locale &locale_)
{
std::locale loc_ = _locale;
_locale = locale_;
return loc_;
}
const std::locale &locale () const
{
return _locale;
}
std::size_t state (const CharT *name_) const
{
std::size_t state_ = npos;
typename string_size_t_map::const_iterator iter_ =
_statemap.find (name_);
if (iter_ != _statemap.end ())
{
state_ = iter_->second;
}
return state_;
}
const CharT *state (const std::size_t index_) const
{
if (index_ == 0)
{
return initial ();
}
else
{
const std::size_t vec_index_ = index_ - 1;
if (vec_index_ > _lexer_state_names.size () - 1)
{
return 0;
}
else
{
return _lexer_state_names[vec_index_].c_str ();
}
}
}
std::size_t add_state (const CharT *name_)
{
validate (name_);
if (_statemap.insert (string_size_t_pair (name_,
_statemap.size ())).second)
{
_regexes.push_back (string_deque ());
_ids.push_back (id_vector ());
_unique_ids.push_back (id_vector ());
_states.push_back (id_vector ());
if (string (name_) != initial ())
{
_lexer_state_names.push_back (name_);
}
}
// Initial is not stored, so no need to - 1.
return _lexer_state_names.size ();
}
void add_macro (const CharT *name_, const CharT *regex_)
{
add_macro (name_, string (regex_));
}
void add_macro (const CharT *name_, const CharT *regex_start_,
const CharT *regex_end_)
{
add_macro (name_, string (regex_start_, regex_end_));
}
void add_macro (const CharT *name_, const string &regex_)
{
validate (name_);
typename string_set::const_iterator iter_ = _macroset.find (name_);
if (iter_ == _macroset.end ())
{
_macrodeque.push_back (string_pair (name_, regex_));
_macroset.insert (name_);
}
else
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Attempt to redefine MACRO '";
while (*name_)
{
os_ << ss_.narrow (*name_++, static_cast<CharT> (' '));
}
os_ << "'.";
throw runtime_error (os_.str ());
}
}
void add_macros (const basic_rules<CharT> &rules_)
{
const string_pair_deque &macros_ = rules_.macrodeque ();
typename string_pair_deque::const_iterator macro_iter_ =
macros_.begin ();
typename string_pair_deque::const_iterator macro_end_ =
macros_.end ();
for (; macro_iter_ != macro_end_; ++macro_iter_)
{
add_macro (macro_iter_->first.c_str (),
macro_iter_->second.c_str ());
}
}
void merge_macros (const basic_rules<CharT> &rules_)
{
const string_pair_deque &macros_ = rules_.macrodeque ();
typename string_pair_deque::const_iterator macro_iter_ =
macros_.begin ();
typename string_pair_deque::const_iterator macro_end_ =
macros_.end ();
typename string_set::const_iterator macro_dest_iter_;
typename string_set::const_iterator macro_dest_end_ = _macroset.end ();
for (; macro_iter_ != macro_end_; ++macro_iter_)
{
macro_dest_iter_ = _macroset.find (macro_iter_->first);
if (macro_dest_iter_ == macro_dest_end_)
{
add_macro (macro_iter_->first.c_str (),
macro_iter_->second.c_str ());
}
}
}
std::size_t add (const CharT *regex_, const std::size_t id_)
{
return add (string (regex_), id_);
}
std::size_t add (const CharT *regex_start_, const CharT *regex_end_,
const std::size_t id_)
{
return add (string (regex_start_, regex_end_), id_);
}
std::size_t add (const string &regex_, const std::size_t id_)
{
const std::size_t counter_ = next_unique_id ();
check_for_invalid_id (id_);
_regexes.front ().push_back (regex_);
_ids.front ().push_back (id_);
_unique_ids.front ().push_back (counter_);
_states.front ().push_back (0);
return counter_;
}
std::size_t add (const CharT *curr_state_, const CharT *regex_,
const CharT *new_state_)
{
return add (curr_state_, string (regex_), new_state_);
}
std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
const CharT *regex_end_, const CharT *new_state_)
{
return add (curr_state_, string (regex_start_, regex_end_),
new_state_);
}
std::size_t add (const CharT *curr_state_, const string &regex_,
const CharT *new_state_)
{
return add (curr_state_, regex_, 0, new_state_, false);
}
std::size_t add (const CharT *curr_state_, const CharT *regex_,
const std::size_t id_, const CharT *new_state_)
{
return add (curr_state_, string (regex_), id_, new_state_);
}
std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
const CharT *regex_end_, const std::size_t id_,
const CharT *new_state_)
{
return add (curr_state_, string (regex_start_, regex_end_), id_,
new_state_);
}
std::size_t add (const CharT *curr_state_, const string &regex_,
const std::size_t id_, const CharT *new_state_)
{
return add (curr_state_, regex_, id_, new_state_, true);
}
void add (const CharT *source_, const basic_rules<CharT> &rules_,
const CharT *dest_, const CharT *to_ = detail::strings<CharT>::dot ())
{
const bool star_ = *source_ == '*' && *(source_ + 1) == 0;
const bool dest_dot_ = *dest_ == '.' && *(dest_ + 1) == 0;
const bool to_dot_ = *to_ == '.' && *(to_ + 1) == 0;
std::size_t state_ = 0;
const string_deque_deque &all_regexes_ = rules_.regexes ();
const id_vector_deque &all_ids_ = rules_.ids ();
const id_vector_deque &all_unique_ids_ = rules_.unique_ids ();
const id_vector_deque &all_states_ = rules_.states ();
typename string_deque::const_iterator regex_iter_;
typename string_deque::const_iterator regex_end_;
typename id_vector::const_iterator id_iter_;
typename id_vector::const_iterator uid_iter_;
typename id_vector::const_iterator state_iter_;
if (star_)
{
typename string_deque_deque::const_iterator all_regexes_iter_ =
all_regexes_.begin ();
typename string_deque_deque::const_iterator all_regexes_end_ =
all_regexes_.end ();
typename id_vector_deque::const_iterator all_ids_iter_ =
all_ids_.begin ();
typename id_vector_deque::const_iterator all_uids_iter_ =
all_unique_ids_.begin ();
typename id_vector_deque::const_iterator all_states_iter_ =
all_states_.begin ();
for (; all_regexes_iter_ != all_regexes_end_;
++state_, ++all_regexes_iter_, ++all_ids_iter_,
++all_uids_iter_, ++all_states_iter_)
{
regex_iter_ = all_regexes_iter_->begin ();
regex_end_ = all_regexes_iter_->end ();
id_iter_ = all_ids_iter_->begin ();
uid_iter_ = all_uids_iter_->begin ();
state_iter_ = all_states_iter_->begin ();
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
++uid_iter_, ++state_iter_)
{
// If ..._dot_ then lookup state name from rules_; otherwise
// pass name through.
add (dest_dot_ ? rules_.state (state_) : dest_, *regex_iter_,
*id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
*uid_iter_);
}
}
}
else
{
const CharT *start_ = source_;
string state_name_;
while (*source_)
{
while (*source_ && *source_ != ',')
{
++source_;
}
state_name_.assign (start_, source_);
if (*source_)
{
++source_;
start_ = source_;
}
state_ = rules_.state (state_name_.c_str ());
if (state_ == npos)
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Unknown state name '";
source_ = state_name_.c_str ();
while (*source_)
{
os_ << ss_.narrow (*source_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
regex_iter_ = all_regexes_[state_].begin ();
regex_end_ = all_regexes_[state_].end ();
id_iter_ = all_ids_[state_].begin ();
uid_iter_ = all_unique_ids_[state_].begin ();
state_iter_ = all_states_[state_].begin ();
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
++uid_iter_, ++state_iter_)
{
// If ..._dot_ then lookup state name from rules_; otherwise
// pass name through.
add (dest_dot_ ? state_name_.c_str () : dest_, *regex_iter_,
*id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
*uid_iter_);
}
}
}
}
/*
void add (const CharT *curr_state_, const basic_rules<CharT> &rules_)
{
const string_deque_deque &regexes_ = rules_.regexes ();
const id_vector_deque &ids_ = rules_.ids ();
const id_vector_deque &unique_ids_ = rules_.unique_ids ();
typename string_deque_deque::const_iterator state_regex_iter_ =
regexes_.begin ();
typename string_deque_deque::const_iterator state_regex_end_ =
regexes_.end ();
typename id_vector_deque::const_iterator state_id_iter_ =
ids_.begin ();
typename id_vector_deque::const_iterator state_uid_iter_ =
unique_ids_.begin ();
typename string_deque::const_iterator regex_iter_;
typename string_deque::const_iterator regex_end_;
typename id_vector::const_iterator id_iter_;
typename id_vector::const_iterator uid_iter_;
for (; state_regex_iter_ != state_regex_end_; ++state_regex_iter_)
{
regex_iter_ = state_regex_iter_->begin ();
regex_end_ = state_regex_iter_->end ();
id_iter_ = state_id_iter_->begin ();
uid_iter_ = state_uid_iter_->begin ();
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
++uid_iter_)
{
add (curr_state_, *regex_iter_, *id_iter_, curr_state_, true,
*uid_iter_);
}
}
}
*/
const string_size_t_map &statemap () const
{
return _statemap;
}
const string_pair_deque &macrodeque () const
{
return _macrodeque;
}
const string_deque_deque &regexes () const
{
return _regexes;
}
const id_vector_deque &ids () const
{
return _ids;
}
const id_vector_deque &unique_ids () const
{
return _unique_ids;
}
const id_vector_deque &states () const
{
return _states;
}
bool empty () const
{
typename string_deque_deque::const_iterator iter_ = _regexes.begin ();
typename string_deque_deque::const_iterator end_ = _regexes.end ();
bool empty_ = true;
for (; iter_ != end_; ++iter_)
{
if (!iter_->empty ())
{
empty_ = false;
break;
}
}
return empty_;
}
static const CharT *initial ()
{
return detail::strings<CharT>::initial ();
}
static const CharT *all_states ()
{
return detail::strings<CharT>::all_states ();
}
static const CharT *dot ()
{
return detail::strings<CharT>::dot ();
}
private:
string_size_t_map _statemap;
string_pair_deque _macrodeque;
string_set _macroset;
string_deque_deque _regexes;
id_vector_deque _ids;
id_vector_deque _unique_ids;
id_vector_deque _states;
regex_flags _flags;
std::size_t _counter;
std::size_t (*_counter_ptr) ();
std::locale _locale;
string_deque _lexer_state_names;
std::size_t add (const CharT *curr_state_, const string &regex_,
const std::size_t id_, const CharT *new_state_, const bool check_,
const std::size_t uid_ = npos)
{
const bool star_ = *curr_state_ == '*' && *(curr_state_ + 1) == 0;
const bool dot_ = *new_state_ == '.' && *(new_state_ + 1) == 0;
if (check_)
{
check_for_invalid_id (id_);
}
if (!dot_)
{
validate (new_state_);
}
std::size_t new_ = string::npos;
typename string_size_t_map::const_iterator iter_;
typename string_size_t_map::const_iterator end_ = _statemap.end ();
id_vector states_;
if (!dot_)
{
iter_ = _statemap.find (new_state_);
if (iter_ == end_)
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Unknown state name '";
while (*new_state_)
{
os_ << ss_.narrow (*new_state_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
new_ = iter_->second;
}
if (star_)
{
const std::size_t size_ = _statemap.size ();
for (std::size_t i_ = 0; i_ < size_; ++i_)
{
states_.push_back (i_);
}
}
else
{
const CharT *start_ = curr_state_;
string state_;
while (*curr_state_)
{
while (*curr_state_ && *curr_state_ != ',')
{
++curr_state_;
}
state_.assign (start_, curr_state_);
if (*curr_state_)
{
++curr_state_;
start_ = curr_state_;
}
validate (state_.c_str ());
iter_ = _statemap.find (state_.c_str ());
if (iter_ == end_)
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Unknown state name '";
curr_state_ = state_.c_str ();
while (*curr_state_)
{
os_ << ss_.narrow (*curr_state_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
states_.push_back (iter_->second);
}
}
std::size_t first_counter_ = npos;
for (std::size_t i_ = 0, size_ = states_.size (); i_ < size_; ++i_)
{
const std::size_t curr_ = states_[i_];
_regexes[curr_].push_back (regex_);
_ids[curr_].push_back (id_);
if (uid_ == npos)
{
const std::size_t counter_ = next_unique_id ();
if (first_counter_ == npos)
{
first_counter_ = counter_;
}
_unique_ids[curr_].push_back (counter_);
}
else
{
if (first_counter_ == npos)
{
first_counter_ = uid_;
}
_unique_ids[curr_].push_back (uid_);
}
_states[curr_].push_back (dot_ ? curr_ : new_);
}
return first_counter_;
}
void validate (const CharT *name_) const
{
const CharT *start_ = name_;
if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') &&
!(*name_ >= 'a' && *name_ <= 'z'))
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Invalid name '";
while (*name_)
{
os_ << ss_.narrow (*name_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
else if (*name_)
{
++name_;
}
while (*name_)
{
if (*name_ != '_' && *name_ != '-' &&
!(*name_ >= 'A' && *name_ <= 'Z') &&
!(*name_ >= 'a' && *name_ <= 'z') &&
!(*name_ >= '0' && *name_ <= '9'))
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Invalid name '";
name_ = start_;
while (*name_)
{
os_ << ss_.narrow (*name_++, ' ');
}
os_ << "'.";
throw runtime_error (os_.str ());
}
++name_;
}
if (name_ - start_ > static_cast<std::ptrdiff_t>(max_macro_len))
{
std::basic_stringstream<CharT> ss_;
std::ostringstream os_;
os_ << "Name '";
name_ = start_;
while (*name_)
{
os_ << ss_.narrow (*name_++, ' ');
}
os_ << "' too long.";
throw runtime_error (os_.str ());
}
}
void check_for_invalid_id (const std::size_t id_) const
{
switch (id_)
{
case 0:
throw runtime_error ("id 0 is reserved for EOF.");
case npos:
throw runtime_error ("id npos is reserved for the "
"UNKNOWN token.");
default:
// OK
break;
}
}
};
typedef basic_rules<char> rules;
typedef basic_rules<wchar_t> wrules;
}
}
#endif
@@ -0,0 +1,26 @@
// runtime_error.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_RUNTIME_ERROR_HPP
#define BOOST_LEXER_RUNTIME_ERROR_HPP
#include <stdexcept>
namespace boost
{
namespace lexer
{
class runtime_error : public std::runtime_error
{
public:
runtime_error (const std::string &what_arg_) :
std::runtime_error (what_arg_)
{
}
};
}
}
#endif
@@ -0,0 +1,35 @@
// examples/serialise.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_SERIALISE_HPP
#define BOOST_LEXER_SERIALISE_HPP
#include "internals.hpp"
#include "state_machine.hpp"
#include <boost/serialization/vector.hpp>
namespace boost
{
namespace lexer
{
// IMPORTANT! This won't work if you don't enable RTTI!
template<typename CharT, class Archive>
void serialise (basic_state_machine<CharT> &sm_, Archive &ar_,
unsigned int version_ = 1)
{
detail::internals &internals_ = const_cast<detail::internals &>
(sm_.data ());
ar_ & version_;
ar_ & *internals_._lookup;
ar_ & internals_._dfa_alphabet;
ar_ & *internals_._dfa;
ar_ & internals_._seen_BOL_assertion;
ar_ & internals_._seen_EOL_assertion;
}
}
}
#endif
@@ -0,0 +1,13 @@
// size_t.h
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_SIZE_T_H
#define BOOST_LEXER_SIZE_T_H
#include <stddef.h> // ptrdiff_t
#include <string>
#endif
@@ -0,0 +1,431 @@
// state_machine.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_STATE_MACHINE_HPP
#define BOOST_LEXER_STATE_MACHINE_HPP
#include <algorithm>
#include "conversion/char_state_machine.hpp"
#include "consts.hpp"
#include <deque>
#include "internals.hpp"
#include <map>
#include "containers/ptr_vector.hpp"
#include "size_t.hpp"
#include <string>
namespace boost
{
namespace lexer
{
template<typename CharT>
class basic_state_machine
{
public:
typedef CharT char_type;
class iterator
{
public:
friend class basic_state_machine;
struct data
{
// Current iterator info
std::size_t dfa;
std::size_t states;
std::size_t state;
std::size_t transitions;
std::size_t transition;
// Current state info
bool end_state;
std::size_t id;
std::size_t unique_id;
std::size_t goto_dfa;
std::size_t bol_index;
std::size_t eol_index;
// Current transition info
basic_string_token<CharT> token;
std::size_t goto_state;
data () :
dfa (npos),
states (0),
state (npos),
transitions (0),
transition (npos),
end_state (false),
id (npos),
unique_id (npos),
goto_dfa (npos),
bol_index (npos),
eol_index (npos),
goto_state (npos)
{
}
bool operator == (const data &rhs_) const
{
return dfa == rhs_.dfa &&
states == rhs_.states &&
state == rhs_.state &&
transitions == rhs_.transitions &&
transition == rhs_.transition &&
end_state == rhs_.end_state &&
id == rhs_.id &&
unique_id == rhs_.unique_id &&
goto_dfa == rhs_.goto_dfa &&
bol_index == rhs_.bol_index &&
eol_index == rhs_.eol_index &&
token == rhs_.token &&
goto_state == rhs_.goto_state;
}
};
iterator () :
_sm (0),
_dfas (0),
_dfa (npos),
_states (0),
_state (npos),
_transitions (0),
_transition (npos)
{
}
bool operator == (const iterator &rhs_) const
{
return _dfas == rhs_._dfas && _dfa == rhs_._dfa &&
_states == rhs_._states && _state == rhs_._state &&
_transitions == rhs_._transitions &&
_transition == rhs_._transition;
}
bool operator != (const iterator &rhs_) const
{
return !(*this == rhs_);
}
data &operator * ()
{
return _data;
}
data *operator -> ()
{
return &_data;
}
// Let compiler generate operator = ().
// prefix version
iterator &operator ++ ()
{
next ();
return *this;
}
// postfix version
iterator operator ++ (int)
{
iterator iter_ = *this;
next ();
return iter_;
}
void clear ()
{
_dfas = _states = _transitions = 0;
_dfa = _state = _transition = npos;
}
private:
basic_state_machine *_sm;
data _data;
std::size_t _dfas;
std::size_t _dfa;
std::size_t _states;
std::size_t _state;
std::size_t _transitions;
std::size_t _transition;
typename detail::basic_char_state_machine<CharT>::state::
size_t_string_token_map::const_iterator _token_iter;
typename detail::basic_char_state_machine<CharT>::state::
size_t_string_token_map::const_iterator _token_end;
void next ()
{
bool reset_state_ = false;
if (_transition >= _transitions)
{
_transition = _data.transition = 0;
_data.state = ++_state;
reset_state_ = true;
if (_state >= _states)
{
++_dfa;
if (_dfa >= _dfas)
{
clear ();
reset_state_ = false;
}
else
{
_states = _data.states =
_sm->_csm._sm_vector[_dfa].size ();
_state = _data.state = 0;
}
}
}
else
{
_data.transition = _transition;
}
if (reset_state_)
{
const typename detail::basic_char_state_machine<CharT>::
state *ptr_ = &_sm->_csm._sm_vector[_dfa][_state];
_transitions = _data.transitions = ptr_->_transitions.size ();
_data.end_state = ptr_->_end_state;
_data.id = ptr_->_id;
_data.unique_id = ptr_->_unique_id;
_data.goto_dfa = ptr_->_state;
_data.bol_index = ptr_->_bol_index;
_data.eol_index = ptr_->_eol_index;
_token_iter = ptr_->_transitions.begin ();
_token_end = ptr_->_transitions.end ();
}
if (_token_iter != _token_end)
{
_data.token = _token_iter->second;
_data.goto_state = _token_iter->first;
++_token_iter;
++_transition;
}
else
{
_data.token.clear ();
_data.goto_state = npos;
}
}
};
friend class iterator;
basic_state_machine ()
{
}
void clear ()
{
_internals.clear ();
_csm.clear ();
}
bool empty () const
{
// Don't include _csm in this test, as irrelevant to state.
return _internals._lookup->empty () &&
_internals._dfa_alphabet.empty () &&
_internals._dfa->empty ();
}
std::size_t size () const
{
return _internals._dfa->size ();
}
bool operator == (const basic_state_machine &rhs_) const
{
// Don't include _csm in this test, as irrelevant to state.
return _internals._lookup == rhs_._internals._lookup &&
_internals._dfa_alphabet == rhs_._internals._dfa_alphabet &&
_internals._dfa == rhs_._internals._dfa &&
_internals._seen_BOL_assertion ==
rhs_._internals._seen_BOL_assertion &&
_internals._seen_EOL_assertion ==
rhs_._internals._seen_EOL_assertion;
}
iterator begin () const
{
iterator iter_;
iter_._sm = const_cast<basic_state_machine *>(this);
check_for_csm ();
if (!_csm.empty ())
{
const typename detail::basic_char_state_machine<CharT>::
state_vector *ptr_ = &_csm._sm_vector.front ();
iter_._dfas = _csm._sm_vector.size ();
iter_._states = iter_._data.states = ptr_->size ();
iter_._transitions = iter_._data.transitions =
ptr_->front ()._transitions.size ();
iter_._dfa = iter_._data.dfa = 0;
iter_._state = iter_._data.state = 0;
iter_._transition = 0;
iter_._data.end_state = ptr_->front ()._end_state;
iter_._data.id = ptr_->front ()._id;
iter_._data.unique_id = ptr_->front ()._unique_id;
iter_._data.goto_dfa = ptr_->front ()._state;
iter_._data.bol_index = ptr_->front ()._bol_index;
iter_._data.eol_index = ptr_->front ()._eol_index;
iter_._token_iter = ptr_->front ()._transitions.begin ();
iter_._token_end = ptr_->front ()._transitions.end ();
// Deal with case where there is only a bol or eol
// but no other transitions.
if (iter_._transitions)
{
++iter_;
}
}
return iter_;
}
iterator end () const
{
iterator iter_;
iter_._sm = const_cast<basic_state_machine *>(this);
return iter_;
}
void swap (basic_state_machine &sm_)
{
_internals.swap (sm_._internals);
_csm.swap (sm_._csm);
}
const detail::internals &data () const
{
return _internals;
}
private:
detail::internals _internals;
mutable detail::basic_char_state_machine<CharT> _csm;
void check_for_csm () const
{
if (_csm.empty ())
{
human_readable (_csm);
}
}
void human_readable (detail::basic_char_state_machine<CharT> &sm_) const
{
const std::size_t max_ = sizeof (CharT) == 1 ?
num_chars : num_wchar_ts;
const std::size_t start_states_ = _internals._dfa->size ();
sm_.clear ();
sm_._sm_vector.resize (start_states_);
for (std::size_t start_state_index_ = 0;
start_state_index_ < start_states_; ++start_state_index_)
{
const detail::internals::size_t_vector *lu_ =
_internals._lookup[start_state_index_];
const std::size_t alphabet_ =
_internals._dfa_alphabet[start_state_index_] - dfa_offset;
std::vector<std::basic_string<CharT> > chars_ (alphabet_);
const std::size_t states_ = _internals._dfa[start_state_index_]->
size () / (alphabet_ + dfa_offset);
const std::size_t *read_ptr_ = &_internals.
_dfa[start_state_index_]->front () + alphabet_ + dfa_offset;
sm_._sm_vector[start_state_index_].resize (states_ - 1);
for (std::size_t alpha_index_ = 0; alpha_index_ < max_;
++alpha_index_)
{
const std::size_t col_ = lu_->at (alpha_index_);
if (col_ != static_cast<std::size_t>(dead_state_index))
{
chars_[col_ - dfa_offset] += static_cast<CharT>
(alpha_index_);
}
}
for (std::size_t state_index_ = 1; state_index_ < states_;
++state_index_)
{
typename detail::basic_char_state_machine<CharT>::state
*state_ = &sm_._sm_vector[start_state_index_]
[state_index_ - 1];
state_->_end_state = *read_ptr_ != 0;
state_->_id = *(read_ptr_ + id_index);
state_->_unique_id = *(read_ptr_ + unique_id_index);
state_->_state = *(read_ptr_ + state_index);
state_->_bol_index = *(read_ptr_ + bol_index) - 1;
state_->_eol_index = *(read_ptr_ + eol_index) - 1;
read_ptr_ += dfa_offset;
for (std::size_t col_index_ = 0; col_index_ < alphabet_;
++col_index_, ++read_ptr_)
{
const std::size_t transition_ = *read_ptr_;
if (transition_ != 0)
{
const std::size_t i_ = transition_ - 1;
typename detail::basic_char_state_machine<CharT>::
state::size_t_string_token_map::iterator iter_ =
state_->_transitions.find (i_);
if (iter_ == state_->_transitions.end ())
{
basic_string_token<CharT> token_
(false, chars_[col_index_]);
typename detail::basic_char_state_machine<CharT>::
state::size_t_string_token_pair pair_
(i_, token_);
state_->_transitions.insert (pair_);
}
else
{
iter_->second._charset += chars_[col_index_];
}
}
}
for (typename detail::basic_char_state_machine<CharT>::state::
size_t_string_token_map::iterator iter_ =
state_->_transitions.begin (),
end_ = state_->_transitions.end ();
iter_ != end_; ++iter_)
{
std::sort (iter_->second._charset.begin (),
iter_->second._charset.end ());
iter_->second.normalise ();
}
}
}
}
};
typedef basic_state_machine<char> state_machine;
typedef basic_state_machine<wchar_t> wstate_machine;
}
}
#endif
@@ -0,0 +1,406 @@
// string_token.hpp
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_LEXER_STRING_TOKEN_HPP
#define BOOST_LEXER_STRING_TOKEN_HPP
#include <algorithm>
#include "size_t.hpp"
#include "consts.hpp" // num_chars, num_wchar_ts
#include <string>
#include <limits>
namespace boost
{
namespace lexer
{
template<typename CharT>
struct basic_string_token
{
typedef std::basic_string<CharT> string;
bool _negated;
string _charset;
basic_string_token () :
_negated (false)
{
}
basic_string_token (const bool negated_, const string &charset_) :
_negated (negated_),
_charset (charset_)
{
}
void remove_duplicates ()
{
const CharT *start_ = _charset.c_str ();
const CharT *end_ = start_ + _charset.size ();
// Optimisation for very large charsets:
// sorting via pointers is much quicker than
// via iterators...
std::sort (const_cast<CharT *> (start_), const_cast<CharT *> (end_));
_charset.erase (std::unique (_charset.begin (), _charset.end ()),
_charset.end ());
}
void normalise ()
{
const std::size_t max_chars_ = sizeof (CharT) == 1 ?
num_chars : num_wchar_ts;
if (_charset.length () == max_chars_)
{
_negated = !_negated;
_charset.clear ();
}
else if (_charset.length () > max_chars_ / 2)
{
negate ();
}
}
void negate ()
{
const std::size_t max_chars_ = sizeof (CharT) == 1 ?
num_chars : num_wchar_ts;
CharT curr_char_ = (std::numeric_limits<CharT>::min)();
string temp_;
const CharT *curr_ = _charset.c_str ();
const CharT *chars_end_ = curr_ + _charset.size ();
_negated = !_negated;
temp_.resize (max_chars_ - _charset.size ());
CharT *ptr_ = const_cast<CharT *> (temp_.c_str ());
std::size_t i_ = 0;
while (curr_ < chars_end_)
{
while (*curr_ > curr_char_)
{
*ptr_ = curr_char_;
++ptr_;
++curr_char_;
++i_;
}
++curr_char_;
++curr_;
++i_;
}
for (; i_ < max_chars_; ++i_)
{
*ptr_ = curr_char_;
++ptr_;
++curr_char_;
}
_charset = temp_;
}
bool operator < (const basic_string_token &rhs_) const
{
return _negated < rhs_._negated ||
(_negated == rhs_._negated && _charset < rhs_._charset);
}
bool empty () const
{
return _charset.empty () && !_negated;
}
bool any () const
{
return _charset.empty () && _negated;
}
void clear ()
{
_negated = false;
_charset.clear ();
}
void intersect (basic_string_token &rhs_, basic_string_token &overlap_)
{
if ((any () && rhs_.any ()) || (_negated == rhs_._negated &&
!any () && !rhs_.any ()))
{
intersect_same_types (rhs_, overlap_);
}
else
{
intersect_diff_types (rhs_, overlap_);
}
}
static void escape_char (const CharT ch_, string &out_)
{
switch (ch_)
{
case '\0':
out_ += '\\';
out_ += '0';
break;
case '\a':
out_ += '\\';
out_ += 'a';
break;
case '\b':
out_ += '\\';
out_ += 'b';
break;
case 27:
out_ += '\\';
out_ += 'x';
out_ += '1';
out_ += 'b';
break;
case '\f':
out_ += '\\';
out_ += 'f';
break;
case '\n':
out_ += '\\';
out_ += 'n';
break;
case '\r':
out_ += '\\';
out_ += 'r';
break;
case '\t':
out_ += '\\';
out_ += 't';
break;
case '\v':
out_ += '\\';
out_ += 'v';
break;
case '\\':
out_ += '\\';
out_ += '\\';
break;
case '"':
out_ += '\\';
out_ += '"';
break;
case '\'':
out_ += '\\';
out_ += '\'';
break;
default:
{
if (ch_ < 32 && ch_ >= 0)
{
std::basic_stringstream<CharT> ss_;
out_ += '\\';
out_ += 'x';
ss_ << std::hex <<
static_cast<std::size_t> (ch_);
out_ += ss_.str ();
}
else
{
out_ += ch_;
}
break;
}
}
}
private:
void intersect_same_types (basic_string_token &rhs_,
basic_string_token &overlap_)
{
if (any ())
{
clear ();
overlap_._negated = true;
rhs_.clear ();
}
else
{
typename string::iterator iter_ = _charset.begin ();
typename string::iterator end_ = _charset.end ();
typename string::iterator rhs_iter_ = rhs_._charset.begin ();
typename string::iterator rhs_end_ = rhs_._charset.end ();
overlap_._negated = _negated;
while (iter_ != end_ && rhs_iter_ != rhs_end_)
{
if (*iter_ < *rhs_iter_)
{
++iter_;
}
else if (*iter_ > *rhs_iter_)
{
++rhs_iter_;
}
else
{
overlap_._charset += *iter_;
iter_ = _charset.erase (iter_);
end_ = _charset.end ();
rhs_iter_ = rhs_._charset.erase (rhs_iter_);
rhs_end_ = rhs_._charset.end ();
}
}
if (_negated)
{
// duplicates already merged, so safe to merge
// using std lib.
// src, dest
merge (_charset, overlap_._charset);
// duplicates already merged, so safe to merge
// using std lib.
// src, dest
merge (rhs_._charset, overlap_._charset);
_negated = false;
rhs_._negated = false;
std::swap (_charset, rhs_._charset);
normalise ();
overlap_.normalise ();
rhs_.normalise ();
}
else if (!overlap_._charset.empty ())
{
normalise ();
overlap_.normalise ();
rhs_.normalise ();
}
}
}
void intersect_diff_types (basic_string_token &rhs_,
basic_string_token &overlap_)
{
if (any ())
{
intersect_any (rhs_, overlap_);
}
else if (_negated)
{
intersect_negated (rhs_, overlap_);
}
else // _negated == false
{
intersect_charset (rhs_, overlap_);
}
}
void intersect_any (basic_string_token &rhs_, basic_string_token &overlap_)
{
if (rhs_._negated)
{
rhs_.intersect_negated (*this, overlap_);
}
else // rhs._negated == false
{
rhs_.intersect_charset (*this, overlap_);
}
}
void intersect_negated (basic_string_token &rhs_,
basic_string_token &overlap_)
{
if (rhs_.any ())
{
overlap_._negated = true;
overlap_._charset = _charset;
rhs_._negated = false;
rhs_._charset = _charset;
clear ();
}
else // rhs._negated == false
{
rhs_.intersect_charset (*this, overlap_);
}
}
void intersect_charset (basic_string_token &rhs_,
basic_string_token &overlap_)
{
if (rhs_.any ())
{
overlap_._charset = _charset;
rhs_._negated = true;
rhs_._charset = _charset;
clear ();
}
else // rhs_._negated == true
{
typename string::iterator iter_ = _charset.begin ();
typename string::iterator end_ = _charset.end ();
typename string::iterator rhs_iter_ = rhs_._charset.begin ();
typename string::iterator rhs_end_ = rhs_._charset.end ();
while (iter_ != end_ && rhs_iter_ != rhs_end_)
{
if (*iter_ < *rhs_iter_)
{
overlap_._charset += *iter_;
rhs_iter_ = rhs_._charset.insert (rhs_iter_, *iter_);
++rhs_iter_;
rhs_end_ = rhs_._charset.end ();
iter_ = _charset.erase (iter_);
end_ = _charset.end ();
}
else if (*iter_ > *rhs_iter_)
{
++rhs_iter_;
}
else
{
++iter_;
++rhs_iter_;
}
}
if (iter_ != end_)
{
// nothing bigger in rhs_ than iter_,
// so safe to merge using std lib.
string temp_ (iter_, end_);
// src, dest
merge (temp_, overlap_._charset);
_charset.erase (iter_, end_);
}
if (!overlap_._charset.empty ())
{
merge (overlap_._charset, rhs_._charset);
// possible duplicates, so check for any and erase.
rhs_._charset.erase (std::unique (rhs_._charset.begin (),
rhs_._charset.end ()), rhs_._charset.end ());
normalise ();
overlap_.normalise ();
rhs_.normalise ();
}
}
}
void merge (string &src_, string &dest_)
{
string tmp_ (src_.size () + dest_.size (), 0);
std::merge (src_.begin (), src_.end (), dest_.begin (), dest_.end (),
tmp_.begin ());
dest_ = tmp_;
}
};
}
}
#endif
@@ -0,0 +1,85 @@
/*=============================================================================
Copyright (c) 2001-2011 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_MAKE_CONS_OCTOBER_16_2008_1252PM
#define BOOST_SPIRIT_MAKE_CONS_OCTOBER_16_2008_1252PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
#include <boost/proto/proto.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_abstract.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace detail
{
template <typename T>
struct as_meta_element
: mpl::eval_if_c<is_abstract<T>::value || is_function<T>::value
, add_reference<T>, remove_const<T> >
{};
template <typename T>
struct as_meta_element<T&> : as_meta_element<T> // always store by value
{};
template <typename T, int N>
struct as_meta_element<T[N]>
{
typedef const T(&type)[N];
};
namespace result_of
{
template <typename Car, typename Cdr = fusion::nil_>
struct make_cons
{
typedef typename as_meta_element<Car>::type car_type; typedef typename fusion::cons<car_type, Cdr> type;
};
}
template <typename Car, typename Cdr>
fusion::cons<typename as_meta_element<Car>::type, Cdr>
make_cons(Car const& car, Cdr const& cdr)
{
typedef typename as_meta_element<Car>::type car_type;
typedef typename fusion::cons<car_type, Cdr> result;
return result(car, cdr);
}
template <typename Car>
fusion::cons<typename as_meta_element<Car>::type>
make_cons(Car const& car)
{
typedef typename as_meta_element<Car>::type car_type;
typedef typename fusion::cons<car_type> result;
return result(car);
}
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 0)
// workaround for gcc-4.0 bug where illegal function types
// can be formed (const is added to function type)
// description: http://lists.boost.org/Archives/boost/2009/04/150743.php
template <typename Car>
fusion::cons<typename as_meta_element<Car>::type>
make_cons(Car& car, typename enable_if<is_function<Car> >::type* = 0)
{
typedef typename as_meta_element<Car>::type car_type;
typedef typename fusion::cons<car_type> result;
return result(car);
}
#endif
}}}
#endif
@@ -0,0 +1,114 @@
/*=============================================================================
Copyright (c) 2001-2010 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)
==============================================================================*/
#include <boost/version.hpp>
// This is the same as the one in fusion in Boost 1.41. This is provided
// for compatibility with Boost 1.40 and below.
#if (BOOST_VERSION > 104000)
#include <boost/fusion/include/make_vector.hpp>
namespace boost { namespace spirit { namespace detail
{
namespace result_of
{
using fusion::result_of::make_vector;
}
using fusion::make_vector;
}}}
#else
#ifndef BOOST_PP_IS_ITERATING
#if !defined(SPIRIT_MAKE_VECTOR_07162005_0243)
#define SPIRIT_MAKE_VECTOR_07162005_0243
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/fusion/container/vector/vector.hpp>
#include <boost/fusion/support/detail/as_fusion_element.hpp>
namespace boost { namespace fusion
{
struct void_;
}}
namespace boost { namespace spirit { namespace detail
{
namespace result_of
{
template <
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
FUSION_MAX_VECTOR_SIZE, typename T, fusion::void_)
, typename Extra = fusion::void_
>
struct make_vector;
template <>
struct make_vector<>
{
typedef fusion::vector0 type;
};
}
inline fusion::vector0
make_vector()
{
return fusion::vector0();
}
#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
typename fusion::detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
#define BOOST_PP_FILENAME_1 <boost/spirit/home/support/detail/make_vector.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
#include BOOST_PP_ITERATE()
#undef BOOST_FUSION_AS_FUSION_ELEMENT
}}}
#endif
#else // defined(BOOST_PP_IS_ITERATING)
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#define N BOOST_PP_ITERATION()
namespace result_of
{
template <BOOST_PP_ENUM_PARAMS(N, typename T)>
#if defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)
#define TEXT(z, n, text) , text
struct make_vector< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, fusion::void_) >
#undef TEXT
#else
struct make_vector<BOOST_PP_ENUM_PARAMS(N, T)>
#endif
{
typedef BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
};
}
template <BOOST_PP_ENUM_PARAMS(N, typename T)>
inline BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
make_vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _))
{
return BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
BOOST_PP_ENUM_PARAMS(N, _));
}
#undef N
#endif // defined(BOOST_PP_IS_ITERATING)
#endif // (BOOST_VERSION > 103800)
@@ -0,0 +1,583 @@
// fp_traits.hpp
#ifndef BOOST_SPIRIT_MATH_FP_TRAITS_HPP
#define BOOST_SPIRIT_MATH_FP_TRAITS_HPP
// Copyright (c) 2006 Johan Rade
// Distributed under the 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(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
# error The VAX floating point mode on VMS is not supported.
#endif
#if defined(_MSC_VER)
#pragma once
#endif
#include <cstring>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/endian.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_floating_point.hpp>
//------------------------------------------------------------------------------
namespace boost {
namespace spirit {
namespace math {
namespace detail {
//------------------------------------------------------------------------------
/*
Most processors support three different floating point precisions:
single precision (32 bits), double precision (64 bits)
and extended double precision (>64 bits)
Note that the C++ type long double can be implemented
both as double precision and extended double precision.
*/
struct single_precision_tag {};
struct double_precision_tag {};
struct extended_double_precision_tag {};
//------------------------------------------------------------------------------
/*
template<class T, class U> struct fp_traits_impl;
This is traits class that describes the binary structure of floating
point numbers of C++ type T and precision U
Requirements:
T = float, double or long double
U = single_precision_tag, double_precision_tag
or extended_double_precision_tag
Typedef members:
bits -- the target type when copying the leading bytes of a floating
point number. It is a typedef for uint32_t or uint64_t.
coverage -- tells us whether all bytes are copied or not.
It is a typedef for all_bits or not_all_bits.
Static data members:
sign, exponent, flag, mantissa -- bit masks that give the meaning of the bits
in the leading bytes.
Static function members:
init() -- initializes the static data members, if needed.
(Is a no-op in the specialized versions of the template.)
get_bits(), set_bits() -- provide access to the leading bytes.
*/
struct all_bits {};
struct not_all_bits {};
// Generic version -------------------------------------------------------------
// The generic version uses run time initialization to determine the floating
// point format. It is capable of handling most formats,
// but not the Motorola 68K extended double precision format.
// Currently the generic version is used only for extended double precision
// on Itanium. In all other cases there are specializations of the template
// that use compile time initialization.
template<class T> struct uint32_t_coverage
{
typedef not_all_bits type;
};
template<> struct uint32_t_coverage<single_precision_tag>
{
typedef all_bits type;
};
template<class T, class U> struct fp_traits_impl
{
typedef uint32_t bits;
typedef BOOST_DEDUCED_TYPENAME uint32_t_coverage<U>::type coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
static uint32_t exponent;
static uint32_t flag;
static uint32_t mantissa;
static void init()
{
if(is_init_) return;
do_init_();
is_init_ = true;
}
static void get_bits(T x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
}
static void set_bits(T& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
}
private:
static size_t offset_;
static bool is_init_;
static void do_init_();
};
//..............................................................................
template<class T, class U> uint32_t fp_traits_impl<T,U>::exponent;
template<class T, class U> uint32_t fp_traits_impl<T,U>::flag;
template<class T, class U> uint32_t fp_traits_impl<T,U>::mantissa;
template<class T, class U> size_t fp_traits_impl<T,U>::offset_;
template<class T, class U> bool fp_traits_impl<T,U>::is_init_;
// In a single-threaded program, do_init will be called exactly once.
// In a multi-threaded program, do_init may be called simultaneously
// by more then one thread. That should not be a problem.
//..............................................................................
template<class T, class U> void fp_traits_impl<T,U>::do_init_()
{
T x = static_cast<T>(3) / static_cast<T>(4);
// sign bit = 0
// exponent: first and last bit = 0, all other bits = 1
// flag bit (if present) = 1
// mantissa: first bit = 1, all other bits = 0
uint32_t a;
for(size_t k = 0; k <= sizeof(T) - 4; ++k) {
memcpy(&a, reinterpret_cast<unsigned char*>(&x) + k, 4);
switch(a) {
case 0x3f400000: // IEEE single precision format
offset_ = k;
exponent = 0x7f800000;
flag = 0x00000000;
mantissa = 0x007fffff;
return;
case 0x3fe80000: // IEEE double precision format
// and PowerPC extended double precision format
offset_ = k;
exponent = 0x7ff00000;
flag = 0x00000000;
mantissa = 0x000fffff;
return;
case 0x3ffe0000: // Motorola extended double precision format
// Must not get here. Must be handled by specialization.
// To get accurate cutoff between normals and subnormals
// we must use the flag bit that is in the 5th byte.
// Otherwise this cutoff will be off by a factor 2.
// If we do get here, then we have failed to detect the Motorola
// processor at compile time.
BOOST_ASSERT(false &&
"Failed to detect the Motorola processor at compile time");
return;
case 0x3ffe8000: // IEEE extended double precision format
// with 15 exponent bits
offset_ = k;
exponent = 0x7fff0000;
flag = 0x00000000;
mantissa = 0x0000ffff;
return;
case 0x3ffec000: // Intel extended double precision format
offset_ = k;
exponent = 0x7fff0000;
flag = 0x00008000;
mantissa = 0x00007fff;
return;
default:
continue;
}
}
BOOST_ASSERT(false);
// Unknown format.
}
// float (32 bits) -------------------------------------------------------------
template<> struct fp_traits_impl<float, single_precision_tag>
{
typedef uint32_t bits;
typedef all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x007fffff);
static void init() {}
static void get_bits(float x, uint32_t& a) { memcpy(&a, &x, 4); }
static void set_bits(float& x, uint32_t a) { memcpy(&x, &a, 4); }
};
// double (64 bits) ------------------------------------------------------------
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
template<> struct fp_traits_impl<double, double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
static void init() {}
static void get_bits(double x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
}
static void set_bits(double& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
}
private:
#if defined(BOOST_BIG_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 4);
#else
BOOST_STATIC_ASSERT(false);
#endif
};
//..............................................................................
#else
template<> struct fp_traits_impl<double, double_precision_tag>
{
typedef uint64_t bits;
typedef all_bits coverage;
static const uint64_t sign = (uint64_t)0x80000000 << 32;
static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
static const uint64_t flag = 0;
static const uint64_t mantissa
= ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
static void init() {}
static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); }
static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }
};
#endif
// long double (64 bits) -------------------------------------------------------
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
template<> struct fp_traits_impl<long double, double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
static void init() {}
static void get_bits(long double x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
}
static void set_bits(long double& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
}
private:
#if defined(BOOST_BIG_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 4);
#else
BOOST_STATIC_ASSERT(false);
#endif
};
//..............................................................................
#else
template<> struct fp_traits_impl<long double, double_precision_tag>
{
typedef uint64_t bits;
typedef all_bits coverage;
static const uint64_t sign = (uint64_t)0x80000000 << 32;
static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
static const uint64_t flag = 0;
static const uint64_t mantissa
= ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
static void init() {}
static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); }
static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }
};
#endif
// long double (>64 bits), x86 and x64 -----------------------------------------
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|| defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
// Intel extended double precision format (80 bits)
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
static void init() {}
static void get_bits(long double x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
}
static void set_bits(long double& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
}
};
// long double (>64 bits), Itanium ---------------------------------------------
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
// The floating point format is unknown at compile time
// No template specialization is provided.
// The generic definition is used.
// The Itanium supports both
// the Intel extended double precision format (80 bits) and
// the IEEE extended double precision format with 15 exponent bits (128 bits).
// long double (>64 bits), PowerPC ---------------------------------------------
#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
|| defined(__ppc) || defined(__ppc__) || defined(__PPC__)
// PowerPC extended double precision format (128 bits)
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
static void init() {}
static void get_bits(long double x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
}
static void set_bits(long double& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
}
private:
#if defined(BOOST_BIG_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 12);
#else
BOOST_STATIC_ASSERT(false);
#endif
};
// long double (>64 bits), Motorola 68K ----------------------------------------
#elif defined(__m68k) || defined(__m68k__) \
|| defined(__mc68000) || defined(__mc68000__) \
// Motorola extended double precision format (96 bits)
// It is the same format as the Intel extended double precision format,
// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
// 3) the flag bit is not set for infinity
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
static void init() {}
// copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
static void get_bits(long double x, uint32_t& a)
{
memcpy(&a, &x, 2);
memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
reinterpret_cast<const unsigned char*>(&x) + 4, 2);
}
static void set_bits(long double& x, uint32_t a)
{
memcpy(&x, &a, 2);
memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
reinterpret_cast<const unsigned char*>(&a) + 2, 2);
}
};
// long double (>64 bits), All other processors --------------------------------
#else
// IEEE extended double precision format with 15 exponent bits (128 bits)
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
{
typedef uint32_t bits;
typedef not_all_bits coverage;
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff);
static void init() {}
static void get_bits(long double x, uint32_t& a)
{
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
}
static void set_bits(long double& x, uint32_t a)
{
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
}
private:
#if defined(BOOST_BIG_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 0);
#elif defined(BOOST_LITTLE_ENDIAN)
BOOST_STATIC_CONSTANT(int, offset_ = 12);
#else
BOOST_STATIC_ASSERT(false);
#endif
};
#endif
//------------------------------------------------------------------------------
// size_to_precision is a type switch for converting a C++ floating point type
// to the corresponding precision type.
template<int n> struct size_to_precision;
template<> struct size_to_precision<4>
{
typedef single_precision_tag type;
};
template<> struct size_to_precision<8>
{
typedef double_precision_tag type;
};
template<> struct size_to_precision<10>
{
typedef extended_double_precision_tag type;
};
template<> struct size_to_precision<12>
{
typedef extended_double_precision_tag type;
};
template<> struct size_to_precision<16>
{
typedef extended_double_precision_tag type;
};
// fp_traits is a type switch that selects the right fp_traits_impl
template<class T> struct fp_traits
{
BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision;
typedef fp_traits_impl<T, precision> type;
};
//------------------------------------------------------------------------------
} // namespace detail
} // namespace math
} // namespace spirit
} // namespace boost
#endif
@@ -0,0 +1,235 @@
// fpclassify.hpp
#ifndef BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
#define BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
// Copyright (c) 2006 Johan Rade
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
/*
The following algorithm is used:
If all exponent bits, the flag bit (if there is one),
and all mantissa bits are 0, then the number is zero.
If all exponent bits and the flag bit (if there is one) are 0,
and at least one mantissa bit is 1, then the number is subnormal.
If all exponent bits are 1 and all mantissa bits are 0,
then the number is infinity.
If all exponent bits are 1 and at least one mantissa bit is 1,
then the number is a not-a-number.
Otherwise the number is normal.
(Note that the binary representation of infinity
has flag bit 0 for Motorola 68K extended double precision,
and flag bit 1 for Intel extended double precision.)
To get the bits, the four or eight most significant bytes are copied
into an uint32_t or uint64_t and bit masks are applied.
This covers all the exponent bits and the flag bit (if there is one),
but not always all the mantissa bits.
Some of the functions below have two implementations,
depending on whether all the mantissa bits are copied or not.
*/
#if defined(_MSC_VER)
#pragma once
#endif
#include <cmath>
#ifndef FP_INFINITE
# define FP_INFINITE 0
# define FP_NAN 1
# define FP_NORMAL 2
# define FP_SUBNORMAL 3
# define FP_ZERO 4
#endif
#include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
namespace boost {
namespace spirit {
namespace math {
//------------------------------------------------------------------------------
template<class T> bool (isfinite)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent;
return a != traits::exponent;
}
//------------------------------------------------------------------------------
template<class T> bool (isnormal)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::flag;
return (a != 0) && (a < traits::exponent);
}
//------------------------------------------------------------------------------
namespace detail {
template<class T> bool isinf_impl(T x, all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::mantissa;
return a == traits::exponent;
}
template<class T> bool isinf_impl(T x, not_all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::mantissa;
if(a != traits::exponent)
return false;
traits::set_bits(x,0);
return x == 0;
}
} // namespace detail
template<class T> bool (isinf)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
}
//------------------------------------------------------------------------------
namespace detail {
template<class T> bool isnan_impl(T x, all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::mantissa;
return a > traits::exponent;
}
template<class T> bool isnan_impl(T x, not_all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::mantissa;
if(a < traits::exponent)
return false;
a &= traits::mantissa;
traits::set_bits(x,a);
return x != 0;
}
} // namespace detail
template<class T> bool (isnan)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
}
//------------------------------------------------------------------------------
namespace detail {
template<class T> int fpclassify_impl(T x, all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::flag | traits::mantissa;
if(a <= traits::mantissa) {
if(a == 0)
return FP_ZERO;
else
return FP_SUBNORMAL;
}
if(a < traits::exponent)
return FP_NORMAL;
a &= traits::mantissa;
if(a == 0)
return FP_INFINITE;
return FP_NAN;
}
template<class T> int fpclassify_impl(T x, not_all_bits)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::exponent | traits::flag | traits::mantissa;
if(a <= traits::mantissa) {
if(x == 0)
return FP_ZERO;
else
return FP_SUBNORMAL;
}
if(a < traits::exponent)
return FP_NORMAL;
a &= traits::mantissa;
traits::set_bits(x,a);
if(x == 0)
return FP_INFINITE;
return FP_NAN;
}
} // namespace detail
template<class T> int (fpclassify)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
}
//------------------------------------------------------------------------------
} // namespace math
} // namespace spirit
} // namespace boost
#endif
@@ -0,0 +1,92 @@
// signbit.hpp
#ifndef BOOST_SPIRIT_MATH_SIGNBIT_HPP
#define BOOST_SPIRIT_MATH_SIGNBIT_HPP
// Copyright (c) 2006 Johan Rade
// Distributed under the 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(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
namespace boost {
namespace spirit {
namespace math {
//------------------------------------------------------------------------------
template<class T> bool (signbit)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= traits::sign;
return a != 0;
}
//------------------------------------------------------------------------------
namespace detail {
template<class T> T copysign_impl(T x, T y)
{
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a &= ~traits::sign;
BOOST_DEDUCED_TYPENAME traits::bits b;
traits::get_bits(y,b);
b &= traits::sign;
traits::set_bits(x,a|b);
return x;
}
}
inline float (copysign)(float x, float y) // magnitude of x and sign of y
{
return detail::copysign_impl(x,y);
}
inline double (copysign)(double x, double y)
{
return detail::copysign_impl(x,y);
}
inline long double (copysign)(long double x, long double y)
{
return detail::copysign_impl(x,y);
}
//------------------------------------------------------------------------------
template<class T> T (changesign)(T x)
{
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
traits::init();
BOOST_DEDUCED_TYPENAME traits::bits a;
traits::get_bits(x,a);
a ^= traits::sign;
traits::set_bits(x,a);
return x;
}
//------------------------------------------------------------------------------
} // namespace math
} // namespace spirit
} // namespace boost
#endif
@@ -0,0 +1,113 @@
/*=============================================================================
Copyright (c) 2001-2011 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_POW10_DECEMBER_26_2008_1118AM)
#define SPIRIT_POW10_DECEMBER_26_2008_1118AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/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 traits
{
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 pow10_helper<T>::call(dim);
}
}}}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,28 @@
// 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)
#ifndef BOOST_SPIRIT_SCOPED_ENUM_EMULATION_HPP
#define BOOST_SPIRIT_SCOPED_ENUM_EMULATION_HPP
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/version.hpp>
#include <boost/config.hpp>
#if BOOST_VERSION >= 104000
# include <boost/detail/scoped_enum_emulation.hpp>
#else
# if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
# define BOOST_NO_CXX11_SCOPED_ENUMS
# endif
# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_type
# define BOOST_SCOPED_ENUM_END };
# define BOOST_SCOPED_ENUM(name) name::enum_type
#endif
#endif
@@ -0,0 +1,71 @@
/*=============================================================================
Copyright (c) 2001-2011 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
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION < 104000
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
#include <boost/spirit/home/support/detail/math/signbit.hpp>
#else
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
#endif
namespace boost { namespace spirit { namespace detail
{
#if BOOST_VERSION < 104000
// signbit(-NAN) is broken for versions of Boost earlier than 1.40.0
// This routine has been taken and adapted from Johan Rade's fp_traits
// library
template<typename T>
inline bool (signbit)(T x)
{
return (boost::spirit::math::signbit)(x);
}
template<typename T>
inline T (changesign)(T x)
{
return (boost::spirit::math::changesign)(x);
}
#else
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
}}}
#endif
@@ -0,0 +1,48 @@
/*=============================================================================
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(SPIRIT_WHAT_FUNCTION_APRIL_22_2007_0236PM)
#define SPIRIT_WHAT_FUNCTION_APRIL_22_2007_0236PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <string>
#include <boost/spirit/home/support/info.hpp>
#include <boost/detail/workaround.hpp>
namespace boost { namespace spirit { namespace detail
{
template <typename Context>
struct what_function
{
what_function(info& what_, Context& context_)
: what(what_), context(context_)
{
what.value = std::list<info>();
}
template <typename Component>
void operator()(Component const& component) const
{
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
#endif
boost::get<std::list<info> >(what.value).
push_back(component.what(context));
}
info& what;
Context& context;
private:
// silence MSVC warning C4512: assignment operator could not be generated
what_function& operator= (what_function const&);
};
}}}
#endif
@@ -0,0 +1,185 @@
/*=============================================================================
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_EXTENDED_VARIANT_AUGUST_6_2011_0859AM)
#define BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/variant.hpp>
#include <boost/mpl/limits/list.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
#define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_MPL_LIMIT_LIST_SIZE
#else
#define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_VARIANT_LIMIT_TYPES
#endif
#define BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T) \
BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES, T) \
/**/
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template <
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES,
typename T, boost::detail::variant::void_)
// We should not be depending on detail::variant::void_
// but I'm not sure if this can fixed. Any other way is
// clumsy at best.
>
#else
template <typename... Types>
#endif
struct extended_variant
{
// tell spirit that this is an adapted variant
struct adapted_variant_tag;
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
typedef boost::variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>
variant_type;
typedef typename variant_type::types types;
typedef extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)
> base_type;
#else
typedef boost::variant<Types...> variant_type;
typedef typename variant_type::types types;
typedef extended_variant<Types...> base_type;
#endif
extended_variant() : var() {}
template <typename T>
extended_variant(T const& var)
: var(var) {}
template <typename T>
extended_variant(T& var)
: var(var) {}
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(extended_variant& rhs) BOOST_NOEXCEPT
{
var.swap(rhs.var);
}
variant_type var;
};
}}
namespace boost
{
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
inline T const&
get(boost::spirit::extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const& x)
{
return boost::get<T>(x.get());
}
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
inline T&
get(boost::spirit::extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>& x)
{
return boost::get<T>(x.get());
}
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
inline T const*
get(boost::spirit::extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const* x)
{
return boost::get<T>(&x->get());
}
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
inline T*
get(boost::spirit::extended_variant<
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>* x)
{
return boost::get<T>(&x->get());
}
#else
template <typename T, typename... Types>
inline T const&
get(boost::spirit::extended_variant<Types...> const& x)
{
return boost::get<T>(x.get());
}
template <typename T, typename... Types>
inline T&
get(boost::spirit::extended_variant<Types...>& x)
{
return boost::get<T>(x.get());
}
template <typename T, typename... Types>
inline T const*
get(boost::spirit::extended_variant<Types...> const* x)
{
return boost::get<T>(&x->get());
}
template <typename T, typename... Types>
inline T*
get(boost::spirit::extended_variant<Types...>* x)
{
return boost::get<T>(&x->get());
}
#endif
}
#undef BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS
#undef BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES
#endif
@@ -0,0 +1,55 @@
/*=============================================================================
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_HANDLES_CONTAINER_DEC_18_2010_0920AM)
#define BOOST_SPIRIT_HANDLES_CONTAINER_DEC_18_2010_0920AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace traits
{
// Finds out whether a component handles container attributes intrinsically
// (or whether container attributes need to be split up separately).
template <typename T, typename Attribute, typename Context
, typename Iterator, typename Enable>
struct handles_container : mpl::false_ {};
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct unary_handles_container
: handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct binary_handles_container
: mpl::or_<
handles_container<Left, Attribute, Context, Iterator>
, handles_container<Right, Attribute, Context, Iterator> >
{};
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct nary_handles_container
: mpl::not_<
is_same<
typename mpl::find_if<
Elements, handles_container<mpl::_, Attribute
, Context, Iterator>
>::type
, typename mpl::end<Elements>::type> >
{};
}}}
#endif
@@ -0,0 +1,47 @@
/*=============================================================================
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_HAS_SEMANTIC_ACTION_SEP_20_2009_0626PM)
#define BOOST_SPIRIT_HAS_SEMANTIC_ACTION_SEP_20_2009_0626PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace traits
{
// finding out, whether a component contains a semantic action
template <typename T, typename Enable = void>
struct has_semantic_action
: mpl::false_ {};
template <typename Subject>
struct unary_has_semantic_action
: has_semantic_action<Subject> {};
template <typename Left, typename Right>
struct binary_has_semantic_action
: mpl::or_<has_semantic_action<Left>, has_semantic_action<Right> > {};
template <typename Elements>
struct nary_has_semantic_action
: mpl::not_<
is_same<
typename mpl::find_if<
Elements, has_semantic_action<mpl::_>
>::type
, typename mpl::end<Elements>::type
>
> {};
}}}
#endif
@@ -0,0 +1,159 @@
/*=============================================================================
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_INFO_NOVEMBER_22_2008_1132AM)
#define BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/foreach.hpp>
#include <boost/spirit/home/support/utf8.hpp>
#include <list>
#include <iterator>
#include <utility>
namespace boost { namespace spirit
{
// info provides information about a component. Each component
// has a what member function that returns an info object.
// strings in the info object are assumed to be encoded as UTF8
// for uniformity.
struct info
{
struct nil_ {};
typedef
boost::variant<
nil_
, utf8_string
, recursive_wrapper<info>
, recursive_wrapper<std::pair<info, info> >
, recursive_wrapper<std::list<info> >
>
value_type;
explicit info(utf8_string const& tag_)
: tag(tag_), value(nil_()) {}
template <typename T>
info(utf8_string const& tag_, T const& value_)
: tag(tag_), value(value_) {}
info(utf8_string const& tag_, char value_)
: tag(tag_), value(utf8_string(1, value_)) {}
info(utf8_string const& tag_, wchar_t value_)
: tag(tag_), value(to_utf8(value_)) {}
info(utf8_string const& tag_, ucs4_char value_)
: tag(tag_), value(to_utf8(value_)) {}
template <typename Char>
info(utf8_string const& tag_, Char const* str)
: tag(tag_), value(to_utf8(str)) {}
template <typename Char, typename Traits, typename Allocator>
info(utf8_string const& tag_
, std::basic_string<Char, Traits, Allocator> const& str)
: tag(tag_), value(to_utf8(str)) {}
utf8_string tag;
value_type value;
};
template <typename Callback>
struct basic_info_walker
{
typedef void result_type;
typedef basic_info_walker<Callback> this_type;
basic_info_walker(Callback& callback_, utf8_string const& tag_, int depth_)
: callback(callback_), tag(tag_), depth(depth_) {}
void operator()(info::nil_) const
{
callback.element(tag, "", depth);
}
void operator()(utf8_string const& str) const
{
callback.element(tag, str, depth);
}
void operator()(info const& what) const
{
boost::apply_visitor(
this_type(callback, what.tag, depth+1), what.value);
}
void operator()(std::pair<info, info> const& pair) const
{
callback.element(tag, "", depth);
boost::apply_visitor(
this_type(callback, pair.first.tag, depth+1), pair.first.value);
boost::apply_visitor(
this_type(callback, pair.second.tag, depth+1), pair.second.value);
}
void operator()(std::list<info> const& l) const
{
callback.element(tag, "", depth);
BOOST_FOREACH(info const& what, l)
{
boost::apply_visitor(
this_type(callback, what.tag, depth+1), what.value);
}
}
Callback& callback;
utf8_string const& tag;
int depth;
private:
// silence MSVC warning C4512: assignment operator could not be generated
basic_info_walker& operator= (basic_info_walker const&);
};
// bare-bones print support
template <typename Out>
struct simple_printer
{
typedef utf8_string string;
simple_printer(Out& out_)
: out(out_) {}
void element(string const& tag, string const& value, int /*depth*/) const
{
if (value == "")
out << '<' << tag << '>';
else
out << '"' << value << '"';
}
Out& out;
private:
// silence MSVC warning C4512: assignment operator could not be generated
simple_printer& operator= (simple_printer const&);
};
template <typename Out>
Out& operator<<(Out& out, info const& what)
{
simple_printer<Out> pr(out);
basic_info_walker<simple_printer<Out> > walker(pr, what.tag, 0);
boost::apply_visitor(walker, what.value);
return out;
}
}}
#endif
@@ -0,0 +1,90 @@
// Copyright (c) 2001, Daniel C. Nuffer
// 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_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <exception> // for std::exception
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class illegal_backtracking
// thrown by buf_id_check CheckingPolicy if an instance of an iterator is
// used after another one has invalidated the queue
///////////////////////////////////////////////////////////////////////////
class illegal_backtracking : public std::exception
{
public:
illegal_backtracking() throw() {}
~illegal_backtracking() throw() {}
char const* what() const throw()
{
return "boost::spirit::multi_pass::illegal_backtracking";
}
};
///////////////////////////////////////////////////////////////////////////////
// class buf_id_check
// Implementation of the CheckingPolicy used by multi_pass
// This policy is most effective when used together with the std_deque
// StoragePolicy.
//
// If used with the fixed_size_queue StoragePolicy, it will not detect
// iterator dereferences that are out of the range of the queue.
///////////////////////////////////////////////////////////////////////////////
struct buf_id_check
{
///////////////////////////////////////////////////////////////////////
struct unique //: detail::default_checking_policy
{
unique() : buf_id(0) {}
unique(unique const& x) : buf_id(x.buf_id) {}
void swap(unique& x)
{
boost::swap(buf_id, x.buf_id);
}
// called to verify that everything is ok.
template <typename MultiPass>
static void docheck(MultiPass const& mp)
{
if (mp.buf_id != mp.shared()->shared_buf_id)
boost::throw_exception(illegal_backtracking());
}
// called from multi_pass::clear_queue, so we can increment the count
template <typename MultiPass>
static void clear_queue(MultiPass& mp)
{
++mp.shared()->shared_buf_id;
++mp.buf_id;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
protected:
unsigned long buf_id;
};
///////////////////////////////////////////////////////////////////////
struct shared
{
shared() : shared_buf_id(0) {}
unsigned long shared_buf_id;
};
};
}}}
#endif
@@ -0,0 +1,128 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM)
#define BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class input_iterator
//
// Implementation of the InputPolicy used by multi_pass, this is different
// from the input_iterator policy only as it is buffering the last input
// character to allow returning it by reference. This is needed for
// wrapping iterators not buffering the last item (such as the
// std::istreambuf_iterator). Unfortunately there is no way to
// automatically figure this out at compile time.
//
// The buffering_input_iterator encapsulates an input iterator of type T
///////////////////////////////////////////////////////////////////////////
struct buffering_input_iterator
{
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique // : public detail::default_input_policy
{
private:
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
public:
typedef
typename boost::detail::iterator_traits<T>::difference_type
difference_type;
typedef
typename boost::detail::iterator_traits<T>::difference_type
distance_type;
typedef
typename boost::detail::iterator_traits<T>::pointer
pointer;
typedef result_type& reference;
typedef result_type value_type;
protected:
unique() {}
explicit unique(T x) {}
void swap(unique&) {}
public:
template <typename MultiPass>
static void destroy(MultiPass&) {}
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
return mp.shared()->get_input();
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
BOOST_ASSERT(0 != mp.shared());
mp.shared()->advance_input();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
static T const end_iter;
return mp.shared()->input_ == end_iter;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, value_type const& t)
{
return mp.shared()->input_is_valid_;
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
explicit shared(T const& input)
: input_(input), curtok_(0), input_is_valid_(false) {}
void advance_input()
{
++input_;
input_is_valid_ = false;
}
result_type& get_input()
{
if (!input_is_valid_) {
curtok_ = *input_;
input_is_valid_ = true;
}
return curtok_;
}
T input_;
result_type curtok_;
bool input_is_valid_;
};
};
}}}
#endif
@@ -0,0 +1,520 @@
// Copyright (c) 2001-2012 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_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
#define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
#include <boost/config.hpp>
#include <boost/type_traits/is_empty.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// The purpose of the multi_pass_unique template is to eliminate
// empty policy classes (policies not containing any data items) from the
// multiple inheritance chain. This is necessary since some compilers
// fail to apply the empty base optimization if multiple inheritance is
// involved.
// Additionally this can be used to combine separate policies into one
// single multi_pass_policy as required by the multi_pass template
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// select the correct derived classes based on if a policy is empty
template <typename T
, typename Ownership, typename Checking, typename Input, typename Storage
, bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
, bool CheckingIsEmpty = boost::is_empty<Checking>::value
, bool InputIsEmpty = boost::is_empty<Input>::value>
struct multi_pass_unique;
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, false, false>
: Ownership, Checking, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Checking::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, false, true>
: Ownership, Checking, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Checking::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(mp); }
template <typename MultiPass>
inline static bool input_at_eof(MultiPass const& mp)
{ return Input::input_at_eof(mp); }
template <typename MultiPass, typename TokenType>
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
{ return Input::input_is_valid(mp, curtok); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, true, false>
: Ownership, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, true, true>
: Ownership, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(mp); }
template <typename MultiPass>
inline static bool input_at_eof(MultiPass const& mp)
{ return Input::input_at_eof(mp); }
template <typename MultiPass, typename TokenType>
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
{ return Input::input_is_valid(mp, curtok); }
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, false, false>
: Checking, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Checking::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, false, true>
: Checking, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Checking::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(mp); }
template <typename MultiPass>
inline static bool input_at_eof(MultiPass const& mp)
{ return Input::input_at_eof(mp); }
template <typename MultiPass, typename TokenType>
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
{ return Input::input_is_valid(mp, curtok); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, true, false>
: Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, true, true>
: Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(mp); }
template <typename MultiPass>
inline static bool input_at_eof(MultiPass const& mp)
{ return Input::input_at_eof(mp); }
template <typename MultiPass, typename TokenType>
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
{ return Input::input_is_valid(mp, curtok); }
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
// the multi_pass_shared structure is used to combine the shared data items
// of all policies into one single structure
///////////////////////////////////////////////////////////////////////////
template<typename T, typename Ownership, typename Checking, typename Input
, typename Storage>
struct multi_pass_shared : Ownership, Checking, Input, Storage
{
explicit multi_pass_shared(T& input) : Input(input) {}
explicit multi_pass_shared(T const& input) : Input(input) {}
};
///////////////////////////////////////////////////////////////////////////
// This is a default implementation of a policy class as required by the
// multi_pass template, combining 4 separate policies into one. Any other
// multi_pass policy class needs to follow the scheme as shown below.
template<typename Ownership, typename Checking, typename Input
, typename Storage>
struct default_policy
{
typedef Ownership ownership_policy;
typedef Checking checking_policy;
typedef Input input_policy;
typedef Storage storage_policy;
///////////////////////////////////////////////////////////////////////
template <typename T>
struct unique : multi_pass_unique<T
, typename Ownership::unique, typename Checking::unique
, typename Input::BOOST_NESTED_TEMPLATE unique<T>
, typename Storage::BOOST_NESTED_TEMPLATE unique<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
{
typedef typename Ownership::unique ownership_policy;
typedef typename Checking::unique checking_policy;
typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
input_policy;
typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
typename input_policy::value_type> storage_policy;
typedef multi_pass_unique<T, ownership_policy, checking_policy
, input_policy, storage_policy> unique_base_type;
unique() {}
explicit unique(T& input) : unique_base_type(input) {}
explicit unique(T const& input) : unique_base_type(input) {}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared : multi_pass_shared<T
, typename Ownership::shared, typename Checking::shared
, typename Input::BOOST_NESTED_TEMPLATE shared<T>
, typename Storage::BOOST_NESTED_TEMPLATE shared<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
{
typedef typename Ownership::shared ownership_policy;
typedef typename Checking::shared checking_policy;
typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
input_policy;
typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
storage_policy;
typedef multi_pass_shared<T, ownership_policy, checking_policy
, input_policy, storage_policy> shared_base_type;
explicit shared(T& input)
: shared_base_type(input), inhibit_clear_queue_(false) {}
explicit shared(T const& input)
: shared_base_type(input), inhibit_clear_queue_(false) {}
// This is needed for the correct implementation of expectation
// points. Normally expectation points flush any multi_pass
// iterator they may act on, but if the corresponding error handler
// is of type 'retry' no flushing of the internal buffers should be
// executed (even if explicitly requested).
bool inhibit_clear_queue_;
};
};
}}}
#endif
@@ -0,0 +1,62 @@
// Copyright (c) 2001, Daniel C. Nuffer
// 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_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class first_owner
// Implementation of an OwnershipPolicy used by multi_pass
// This ownership policy dictates that the first iterator created will
// determine the lifespan of the shared components. This works well for
// spirit, since no dynamic allocation of iterators is done, and all
// copies are make on the stack.
//
// There is a caveat about using this policy together with the std_deque
// StoragePolicy. Since first_owner always returns false from unique(),
// std_deque will only release the queued data if clear_queue() is called.
///////////////////////////////////////////////////////////////////////////
struct first_owner
{
///////////////////////////////////////////////////////////////////////
struct unique : detail::default_ownership_policy
{
unique() : first(true) {}
unique(unique const&) : first(false) {}
// return true to indicate deletion of resources
template <typename MultiPass>
static bool release(MultiPass& mp)
{
return mp.first;
}
// use swap from default policy
// if we're the first, we still remain the first, even if assigned
// to, so don't swap first. swap is only called from operator=
template <typename MultiPass>
static bool is_unique(MultiPass const&)
{
return false; // no way to know, so always return false
}
protected:
bool first;
};
////////////////////////////////////////////////////////////////////////
struct shared {}; // no shared data
};
}}}
#endif
@@ -0,0 +1,392 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM)
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM
#include <cstdlib>
#include <iterator>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/assert.hpp> // for BOOST_ASSERT
#include <boost/iterator_adaptors.hpp>
///////////////////////////////////////////////////////////////////////////////
// Make sure we're using a decent version of the Boost.IteratorAdaptors lib
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!"
#endif
///////////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_ASSERT_FSQ_SIZE \
BOOST_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1)) \
/**/
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Queue, typename T, typename Pointer>
class fsq_iterator
: public boost::iterator_facade<
fsq_iterator<Queue, T, Pointer>, T,
std::random_access_iterator_tag
>
{
public:
typedef typename Queue::position_type position_type;
typedef boost::iterator_facade<
fsq_iterator<Queue, T, Pointer>, T,
std::random_access_iterator_tag
> base_type;
fsq_iterator() {}
fsq_iterator(position_type const &p_) : p(p_) {}
position_type &get_position() { return p; }
position_type const &get_position() const { return p; }
private:
friend class boost::iterator_core_access;
typename base_type::reference dereference() const
{
return p.self->m_queue[p.pos];
}
void increment()
{
++p.pos;
if (p.pos == Queue::MAX_SIZE+1)
p.pos = 0;
}
void decrement()
{
if (p.pos == 0)
p.pos = Queue::MAX_SIZE;
else
--p.pos;
}
bool is_eof() const
{
return p.self == 0 || p.pos == p.self->size();
}
template <typename Q, typename T_, typename P>
bool equal(fsq_iterator<Q, T_, P> const &x) const
{
if (is_eof())
return x.is_eof();
if (x.is_eof())
return false;
position_type const &rhs_pos = x.get_position();
return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
}
template <typename Q, typename T_, typename P>
typename base_type::difference_type distance_to(
fsq_iterator<Q, T_, P> const &x) const
{
typedef typename base_type::difference_type difference_type;
position_type const &p2 = x.get_position();
std::size_t pos1 = p.pos;
std::size_t pos2 = p2.pos;
// Undefined behavior if the iterators come from different
// containers
BOOST_ASSERT(p.self == p2.self);
if (pos1 < p.self->m_head)
pos1 += Queue::MAX_SIZE;
if (pos2 < p2.self->m_head)
pos2 += Queue::MAX_SIZE;
if (pos2 > pos1)
return difference_type(pos2 - pos1);
else
return -difference_type(pos1 - pos2);
}
void advance(typename base_type::difference_type n)
{
// Notice that we don't care values of n that can
// wrap around more than one time, since it would
// be undefined behavior anyway (going outside
// the begin/end range). Negative wrapping is a bit
// cumbersome because we don't want to case p.pos
// to signed.
if (n < 0)
{
n = -n;
if (p.pos < (std::size_t)n)
p.pos = Queue::MAX_SIZE+1 - (n - p.pos);
else
p.pos -= n;
}
else
{
p.pos += n;
if (p.pos >= Queue::MAX_SIZE+1)
p.pos -= Queue::MAX_SIZE+1;
}
}
private:
position_type p;
};
///////////////////////////////////////////////////////////////////////////
template <typename T, std::size_t N>
class fixed_size_queue
{
private:
struct position
{
fixed_size_queue* self;
std::size_t pos;
position() : self(0), pos(0) {}
// The const_cast here is just to avoid to have two different
// position structures for the const and non-const case.
// The const semantic is guaranteed by the iterator itself
position(const fixed_size_queue* s, std::size_t p)
: self(const_cast<fixed_size_queue*>(s)), pos(p)
{}
bool is_initialized() const { return self != 0; }
void set_queue(fixed_size_queue* q) { self = q; }
};
public:
// Declare the iterators
typedef fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator;
typedef
fsq_iterator<fixed_size_queue<T, N>, T const, T const*>
const_iterator;
typedef position position_type;
friend class fsq_iterator<fixed_size_queue<T, N>, T, T*>;
friend class fsq_iterator<fixed_size_queue<T, N>, T const, T const*>;
fixed_size_queue();
fixed_size_queue(const fixed_size_queue& x);
fixed_size_queue& operator=(const fixed_size_queue& x);
~fixed_size_queue();
void push_back(const T& e);
void push_front(const T& e);
void serve(T& e);
void pop_front();
bool empty() const
{
return m_size == 0;
}
bool full() const
{
return m_size == N;
}
iterator begin()
{
return iterator(position(this, m_head));
}
const_iterator begin() const
{
return const_iterator(position(this, m_head));
}
iterator end()
{
return iterator(position(0, m_tail));
}
const_iterator end() const
{
return const_iterator(position(0, m_tail));
}
std::size_t size() const
{
return m_size;
}
T& front()
{
return m_queue[m_head];
}
const T& front() const
{
return m_queue[m_head];
}
private:
// Redefine the template parameters to avoid using partial template
// specialization on the iterator policy to extract N.
BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N);
std::size_t m_head;
std::size_t m_tail;
std::size_t m_size;
T m_queue[N+1];
};
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::fixed_size_queue()
: m_head(0)
, m_tail(0)
, m_size(0)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x)
: m_head(x.m_head)
, m_tail(x.m_tail)
, m_size(x.m_size)
{
copy(x.begin(), x.end(), begin());
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline fixed_size_queue<T, N>&
fixed_size_queue<T, N>::operator=(const fixed_size_queue& x)
{
if (this != &x)
{
m_head = x.m_head;
m_tail = x.m_tail;
m_size = x.m_size;
copy(x.begin(), x.end(), begin());
}
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
return *this;
}
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::~fixed_size_queue()
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::push_back(const T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
BOOST_ASSERT(!full());
m_queue[m_tail] = e;
++m_size;
++m_tail;
if (m_tail == N+1)
m_tail = 0;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::push_front(const T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
BOOST_ASSERT(!full());
if (m_head == 0)
m_head = N;
else
--m_head;
m_queue[m_head] = e;
++m_size;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::serve(T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
e = m_queue[m_head];
pop_front();
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::pop_front()
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
++m_head;
if (m_head == N+1)
m_head = 0;
--m_size;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
}}}
#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE
#endif
@@ -0,0 +1,128 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM)
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp>
#include <boost/assert.hpp>
#include <cstdlib>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class fixed_size_queue
// Implementation of the StoragePolicy used by multi_pass
// fixed_size_queue keeps a circular buffer (implemented by
// boost::spirit::fixed_size_queue class) that is size N+1 and stores N
// elements.
//
// It is up to the user to ensure that there is enough look ahead for
// their grammar. Currently there is no way to tell if an iterator is
// pointing to forgotten data. The leading iterator will put an item in
// the queue and remove one when it is incremented. No dynamic allocation
// is done, except on creation of the queue (fixed_size_queue constructor).
///////////////////////////////////////////////////////////////////////////
template <std::size_t N>
struct fixed_size_queue
{
///////////////////////////////////////////////////////////////////////
template <typename Value>
class unique : public detail::default_storage_policy
{
private:
typedef detail::fixed_size_queue<Value, N> queue_type;
protected:
unique() {}
unique(unique const& x)
: queued_position(x.queued_position) {}
void swap(unique& x)
{
boost::swap(queued_position, x.queued_position);
}
// This is called when the iterator is dereferenced. It's a
// template method so we can recover the type of the multi_pass
// iterator and access the m_input data member.
template <typename MultiPass>
static typename MultiPass::reference
dereference(MultiPass const& mp)
{
if (!mp.queued_position.get_position().is_initialized())
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
if (mp.queued_position == mp.shared()->queued_elements.end())
return MultiPass::get_input(mp);
return *mp.queued_position;
}
// This is called when the iterator is incremented. It's a
// template method so we can recover the type of the multi_pass
// iterator and access the m_input data member.
template <typename MultiPass>
static void increment(MultiPass& mp)
{
if (!mp.queued_position.get_position().is_initialized())
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
if (mp.queued_position == mp.shared()->queued_elements.end())
{
// don't let the queue get larger than N
if (mp.shared()->queued_elements.size() >= N)
mp.shared()->queued_elements.pop_front();
mp.shared()->queued_elements.push_back(
MultiPass::get_input(mp));
MultiPass::advance_input(mp);
}
++mp.queued_position;
}
// clear_queue is a no-op
// called to determine whether the iterator is an eof iterator
template <typename MultiPass>
static bool is_eof(MultiPass const& mp)
{
return mp.queued_position == mp.shared()->queued_elements.end() &&
MultiPass::input_at_eof(mp);
}
// called by operator==
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position == x.queued_position;
}
// called by operator<
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position < x.queued_position;
}
protected:
mutable typename queue_type::iterator queued_position;
};
///////////////////////////////////////////////////////////////////////
template <typename Value>
struct shared
{
typedef detail::fixed_size_queue<Value, N> queue_type;
queue_type queued_elements;
};
};
}}}
#endif
@@ -0,0 +1,114 @@
// 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M)
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace is_valid_test_
{
template <typename Token>
inline bool token_is_valid(Token const&)
{
return true;
}
}
///////////////////////////////////////////////////////////////////////////
// class functor_input
// Implementation of the InputPolicy used by multi_pass
// functor_input gets tokens from a functor
//
// Note: the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined
// to represent EOF that is called eof.
//
///////////////////////////////////////////////////////////////////////////
struct functor_input
{
///////////////////////////////////////////////////////////////////////
template <typename Functor>
class unique : public detail::default_input_policy
{
private:
typedef typename Functor::result_type result_type;
protected:
unique() {}
explicit unique(Functor const& x) : ftor(x) {}
void swap(unique& x)
{
boost::swap(ftor, x.ftor);
}
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef result_type* pointer;
typedef result_type& reference;
public:
// get the next token
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
value_type& curtok = mp.shared()->curtok;
if (!input_is_valid(mp, curtok))
curtok = mp.ftor();
return curtok;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
// if mp.shared is NULL then this instance of the multi_pass
// represents a end iterator
BOOST_ASSERT(0 != mp.shared());
mp.shared()->curtok = mp.ftor();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->curtok == mp.ftor.eof;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
using namespace is_valid_test_;
return token_is_valid(t);
}
Functor& get_functor() const
{
return ftor;
}
protected:
mutable Functor ftor;
};
///////////////////////////////////////////////////////////////////////
template <typename Functor>
struct shared
{
explicit shared(Functor const&) : curtok(0) {}
typename Functor::result_type curtok;
};
};
}}}
#endif
@@ -0,0 +1,111 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM)
#define BOOST_SPIRIT_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace input_iterator_is_valid_test_
{
///////////////////////////////////////////////////////////////////////
template <typename Token>
inline bool token_is_valid(Token const& c)
{
return c ? true : false;
}
}
///////////////////////////////////////////////////////////////////////////
// class input_iterator
// Implementation of the InputPolicy used by multi_pass
//
// The input_iterator encapsulates an input iterator of type T
///////////////////////////////////////////////////////////////////////////
struct input_iterator
{
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique // : public detail::default_input_policy
{
private:
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
public:
typedef
typename boost::detail::iterator_traits<T>::difference_type
difference_type;
typedef
typename boost::detail::iterator_traits<T>::difference_type
distance_type;
typedef
typename boost::detail::iterator_traits<T>::pointer
pointer;
typedef
typename boost::detail::iterator_traits<T>::reference
reference;
typedef result_type value_type;
protected:
unique() {}
explicit unique(T x) {}
void swap(unique&) {}
public:
template <typename MultiPass>
static void destroy(MultiPass&) {}
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
return *mp.shared()->input_;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
++mp.shared()->input_;
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
static T const end_iter;
return mp.shared()->input_ == end_iter;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, value_type const& t)
{
using namespace input_iterator_is_valid_test_;
return token_is_valid(t);
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
explicit shared(T const& input) : input_(input) {}
T input_;
};
};
}}}
#endif
@@ -0,0 +1,124 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ISTREAM_POLICY_JAN_04_2010_0130PM)
#define BOOST_SPIRIT_ISTREAM_POLICY_JAN_04_2010_0130PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class istream
// Implementation of the InputPolicy used by multi_pass
//
// The istream encapsulates an std::basic_istream
///////////////////////////////////////////////////////////////////////////
struct istream
{
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique // : public detail::default_input_policy
{
private:
typedef typename T::char_type result_type;
public:
typedef typename T::off_type difference_type;
typedef typename T::off_type distance_type;
typedef result_type const* pointer;
typedef result_type const& reference;
typedef result_type value_type;
protected:
unique() {}
explicit unique(T&) {}
void swap(unique&) {}
public:
template <typename MultiPass>
static void destroy(MultiPass&) {}
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
if (!mp.shared()->initialized_)
mp.shared()->read_one();
return mp.shared()->curtok_;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
// We invalidate the currently cached input character to avoid
// reading more input from the underlying iterator than
// required. Without this we would always read ahead one
// character, even if this character never gets consumed by the
// client.
mp.shared()->peek_one();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->eof_reached_;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, value_type const&)
{
return mp.shared()->initialized_;
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
private:
typedef typename T::char_type result_type;
public:
explicit shared(T& input)
: input_(input), curtok_(-1)
, initialized_(false), eof_reached_(false)
{
peek_one(); // istreams may be at eof right in the beginning
}
void read_one()
{
if (!(input_ >> curtok_)) {
initialized_ = false;
eof_reached_ = true;
}
else {
initialized_ = true;
}
}
void peek_one()
{
input_.peek(); // try for eof
initialized_ = false;
eof_reached_ = input_.eof();
}
T& input_;
result_type curtok_;
bool initialized_;
bool eof_reached_;
};
};
}}}
#endif
@@ -0,0 +1,86 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM)
#define BOOST_SPIRIT_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////////
// class lex_input
// Implementation of the InputPolicy used by multi_pass
//
// The lex_input class gets tokens (integers) from yylex()
///////////////////////////////////////////////////////////////////////////
struct lex_input
{
typedef int value_type;
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique : public detail::default_input_policy
{
public:
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef int* pointer;
typedef int& reference;
protected:
unique() {}
explicit unique(T) {}
public:
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
value_type& curtok = mp.shared()->curtok;
if (-1 == curtok)
{
extern int yylex();
curtok = yylex();
}
return curtok;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
extern int yylex();
mp.shared()->curtok = yylex();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->curtok == 0;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
return -1 != t;
}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
explicit shared(T) : curtok(-1) {}
value_type curtok;
};
};
}}}
#endif
@@ -0,0 +1,109 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM)
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM
#include <boost/config.hpp>
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/iterator.hpp>
#include <boost/mpl/bool.hpp>
#include <iterator>
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// Default implementations of the different policies to be used with a
// multi_pass iterator
///////////////////////////////////////////////////////////////////////////
struct default_input_policy
{
default_input_policy() {}
template <typename Functor>
default_input_policy(Functor const&) {}
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_input_policy&) {}
template <typename MultiPass, typename TokenType>
static void advance_input(MultiPass& mp);
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp);
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp);
template <typename MultiPass, typename TokenType>
static bool input_is_valid(MultiPass& mp, TokenType& curtok);
};
struct default_ownership_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_ownership_policy&) {}
template <typename MultiPass>
static void clone(MultiPass&) {}
template <typename MultiPass>
static bool release(MultiPass& mp);
template <typename MultiPass>
static bool is_unique(MultiPass const& mp);
};
struct default_storage_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_storage_policy&) {}
template <typename MultiPass>
static typename MultiPass::reference dereference(MultiPass const& mp);
template <typename MultiPass>
static void increment(MultiPass&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
template <typename MultiPass>
static bool is_eof(MultiPass const& mp);
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x);
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x);
};
struct default_checking_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_checking_policy&) {}
template <typename MultiPass>
static void docheck(MultiPass const&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
};
}}}
#endif
@@ -0,0 +1,31 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM)
#define BOOST_SPIRIT_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class no_check
// Implementation of the CheckingPolicy used by multi_pass
// It does not do anything :-)
///////////////////////////////////////////////////////////////////////////
struct no_check
{
///////////////////////////////////////////////////////////////////////
struct unique : public detail::default_checking_policy {};
///////////////////////////////////////////////////////////////////////
struct shared {};
};
}}}
#endif
@@ -0,0 +1,79 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#if defined(BOOST_HAS_THREADS)
#include <boost/detail/atomic_count.hpp>
#endif
#include <cstdlib>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class ref_counted
// Implementation of an OwnershipPolicy used by multi_pass.
//
// Implementation modified from RefCounted class from the Loki library by
// Andrei Alexandrescu.
///////////////////////////////////////////////////////////////////////////
struct ref_counted
{
///////////////////////////////////////////////////////////////////////
struct unique // : detail::default_ownership_policy
{
void swap(unique&) {}
// clone is called when a copy of the iterator is made, so
// increment the ref-count.
template <typename MultiPass>
static void clone(MultiPass& mp)
{
if (0 != mp.shared())
++mp.shared()->count;
}
// called when a copy is deleted. Decrement the ref-count. Return
// value of true indicates that the last copy has been released.
template <typename MultiPass>
static bool release(MultiPass& mp)
{
return 0 != mp.shared() && 0 == --mp.shared()->count;
}
// returns true if there is only one iterator in existence.
// std_deque StoragePolicy will free it's buffered data if this
// returns true.
template <typename MultiPass>
static bool is_unique(MultiPass const& mp)
{
return 0 == mp.shared() || 1 == mp.shared()->count;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
};
////////////////////////////////////////////////////////////////////////
struct shared
{
shared() : count(1) {}
#if defined(BOOST_HAS_THREADS)
boost::detail::atomic_count count;
#else
std::size_t count;
#endif
};
};
}}}
#endif
@@ -0,0 +1,201 @@
// 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM)
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
#include <boost/type_traits/is_empty.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace split_functor_input_is_valid_test_
{
template <typename Token>
inline bool token_is_valid(Token const&)
{
return true;
}
}
///////////////////////////////////////////////////////////////////////////
// class split_functor_input
// Implementation of the InputPolicy used by multi_pass
// split_functor_input gets tokens from a functor
//
// This policy should be used when the functor holds two parts of data: a
// unique part (unique for each instance of the iterator) and a shared
// part (to be shared between the different copies of the same iterator).
// Using this policy allows to merge the shared part of the functor with
// the shared part of the iterator data, saving one pointer and one
// allocation per iterator instance.
//
// The Functor template parameter of this policy is expected to be a
// std::pair<unique, shared>, where 'unique' and 'shared' represent the
// respective parts of the functor itself.
//
// Note: the unique part of the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined
// to represent EOF that is called eof.
//
///////////////////////////////////////////////////////////////////////////
struct split_functor_input
{
///////////////////////////////////////////////////////////////////////
template <typename Functor
, bool FunctorIsEmpty = is_empty<typename Functor::first_type>::value>
class unique;
// the unique part of the functor is empty, do not include the functor
// as a member at all to avoid unnecessary padding bytes to be included
// into the generated structure
template <typename Functor>
class unique<Functor, true> // : public detail::default_input_policy
{
protected:
typedef typename Functor::first_type functor_type;
typedef typename functor_type::result_type result_type;
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef result_type const* pointer;
typedef result_type const& reference;
protected:
unique() {}
explicit unique(Functor const&) {}
public:
void swap(unique&) {}
// get the next token
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
value_type& curtok = mp.shared()->curtok;
using namespace split_functor_input_is_valid_test_;
if (!token_is_valid(curtok))
functor_type::get_next(mp, curtok);
return curtok;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
functor_type::get_next(mp, mp.shared()->curtok);
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->curtok == functor_type::eof;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
using namespace split_functor_input_is_valid_test_;
return token_is_valid(t);
}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
functor_type::destroy(mp);
}
};
// the unique part of the functor is non-empty
template <typename Functor>
class unique<Functor, false> : public unique<Functor, true>
{
protected:
typedef typename Functor::first_type functor_type;
typedef typename functor_type::result_type result_type;
protected:
unique() {}
explicit unique(Functor const& x) : ftor(x.first) {}
void swap(unique& x)
{
boost::swap(ftor, x.ftor);
}
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef result_type const* pointer;
typedef result_type const& reference;
public:
// get the next token
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
value_type& curtok = mp.shared()->curtok;
using namespace split_functor_input_is_valid_test_;
if (!token_is_valid(curtok))
functor_type::get_next(mp, curtok);
return curtok;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
mp.ftor.get_next(mp, mp.shared()->curtok);
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
using namespace split_functor_input_is_valid_test_;
return token_is_valid(t);
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->curtok == mp.ftor.eof;
}
typename Functor::first_type& get_functor() const
{
return ftor;
}
mutable functor_type ftor;
};
///////////////////////////////////////////////////////////////////////
template <typename Functor>
struct shared
{
protected:
typedef typename Functor::first_type functor_type;
typedef typename functor_type::result_type result_type;
public:
explicit shared(Functor const& x) : ftor(x.second), curtok(0) {}
mutable typename Functor::second_type ftor;
result_type curtok;
private:
// silence MSVC warning C4512: assignment operator could not be generated
shared& operator= (shared const&);
};
};
}}}
#endif
@@ -0,0 +1,170 @@
// Copyright (c) 2001 Daniel C. Nuffer
// 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_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
#include <vector>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class split_std_deque
//
// Implementation of the StoragePolicy used by multi_pass
// This stores all data in a std::vector (despite its name), and keeps an
// offset to the current position. It stores all the data unless there is
// only one iterator using the queue.
//
///////////////////////////////////////////////////////////////////////////
struct split_std_deque
{
enum { threshold = 16 };
///////////////////////////////////////////////////////////////////////
template <typename Value>
class unique //: public detail::default_storage_policy
{
private:
typedef std::vector<Value> queue_type;
protected:
unique() : queued_position(0) {}
unique(unique const& x)
: queued_position(x.queued_position) {}
void swap(unique& x)
{
boost::swap(queued_position, x.queued_position);
}
// This is called when the iterator is dereferenced. It's a
// template method so we can recover the type of the multi_pass
// iterator and call advance_input and input_is_valid.
template <typename MultiPass>
static typename MultiPass::reference
dereference(MultiPass const& mp)
{
queue_type& queue = mp.shared()->queued_elements;
typename queue_type::size_type size = queue.size();
BOOST_ASSERT(mp.queued_position <= size);
if (mp.queued_position == size)
{
// check if this is the only iterator
if (size >= threshold && MultiPass::is_unique(mp))
{
// free up the memory used by the queue.
queue.clear();
mp.queued_position = 0;
}
return MultiPass::get_input(mp);
}
return queue[mp.queued_position];
}
// This is called when the iterator is incremented. It's a template
// method so we can recover the type of the multi_pass iterator
// and call is_unique and advance_input.
template <typename MultiPass>
static void increment(MultiPass& mp)
{
queue_type& queue = mp.shared()->queued_elements;
typename queue_type::size_type size = queue.size();
BOOST_ASSERT(mp.queued_position <= size);
// // do not increment iterator as long as the current token is
// // invalid
// if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
// return;
if (mp.queued_position == size)
{
// check if this is the only iterator
if (size >= threshold && MultiPass::is_unique(mp))
{
// free up the memory used by the queue. we avoid
// clearing the queue on every increment, though,
// because this would be too time consuming
queue.clear();
mp.queued_position = 0;
}
else
{
queue.push_back(MultiPass::get_input(mp));
++mp.queued_position;
}
MultiPass::advance_input(mp);
}
else
{
++mp.queued_position;
}
}
// called to forcibly clear the queue
template <typename MultiPass>
static void clear_queue(MultiPass& mp)
{
mp.shared()->queued_elements.clear();
mp.queued_position = 0;
}
// called to determine whether the iterator is an eof iterator
template <typename MultiPass>
static bool is_eof(MultiPass const& mp)
{
return mp.queued_position == mp.shared()->queued_elements.size()
&& MultiPass::input_at_eof(mp);
}
// called by operator==
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position == x.queued_position;
}
// called by operator<
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position < x.queued_position;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
protected:
mutable typename queue_type::size_type queued_position;
};
///////////////////////////////////////////////////////////////////////
template <typename Value>
struct shared
{
shared()
{
queued_elements.reserve(threshold);
}
typedef std::vector<Value> queue_type;
queue_type queued_elements;
};
}; // split_std_deque
}}}
#endif
@@ -0,0 +1,80 @@
// 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_ISTREAM_ITERATOR_JAN_03_2010_0522PM)
#define BOOST_SPIRIT_ISTREAM_ITERATOR_JAN_03_2010_0522PM
#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp>
#if defined(BOOST_SPIRIT_DEBUG)
#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp>
#else
#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
#endif
#include <boost/spirit/home/support/iterators/detail/istream_policy.hpp>
#include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp>
#include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
#include <boost/spirit/home/support/iterators/multi_pass.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
template <typename Elem, typename Traits = std::char_traits<Elem> >
class basic_istream_iterator :
public multi_pass<
std::basic_istream<Elem, Traits>
, iterator_policies::default_policy<
iterator_policies::ref_counted
#if defined(BOOST_SPIRIT_DEBUG)
, iterator_policies::buf_id_check
#else
, iterator_policies::no_check
#endif
, iterator_policies::istream
, iterator_policies::split_std_deque>
>
{
private:
typedef multi_pass<
std::basic_istream<Elem, Traits>
, iterator_policies::default_policy<
iterator_policies::ref_counted
#if defined(BOOST_SPIRIT_DEBUG)
, iterator_policies::buf_id_check
#else
, iterator_policies::no_check
#endif
, iterator_policies::istream
, iterator_policies::split_std_deque>
> base_type;
public:
basic_istream_iterator()
: base_type() {}
explicit basic_istream_iterator(std::basic_istream<Elem, Traits>& x)
: base_type(x) {}
basic_istream_iterator(basic_istream_iterator const& x)
: base_type(x) {}
#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
basic_istream_iterator(int) // workaround for a bug in the library
: base_type() {} // shipped with gcc 3.1
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
basic_istream_iterator operator= (base_type const& rhs)
{
this->base_type::operator=(rhs);
return *this;
}
// default generated operators, destructor and assignment operator are ok.
};
typedef basic_istream_iterator<char> istream_iterator;
}}
#endif

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