|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r70574 - in branches/release/boost/spirit: . home home/classic/iterator home/classic/iterator/impl home/karma home/karma/auto home/karma/auxiliary home/karma/binary home/karma/char home/karma/detail home/karma/directive home/karma/nonterminal home/karma/nonterminal/detail home/karma/numeric home/karma/operator home/karma/stream home/karma/string home/lex home/lex/lexer home/lex/lexer/lexertl home/lex/qi home/phoenix/core home/qi home/qi/action home/qi/auto home/qi/auxiliary home/qi/binary home/qi/char home/qi/detail home/qi/directive home/qi/nonterminal home/qi/nonterminal/detail home/qi/numeric home/qi/operator home/qi/stream home/qi/stream/detail home/qi/string home/support home/support/detail home/support/iterators home/support/iterators/detail home/support/utree home/support/utree/detail include repository/home repository/home/qi repository/home/qi/directive repository/home/qi/nonterminal repository/home/qi/operator repository/home/qi/operator/detail repository/home/qi/primitive repository/home/support repository/include
From: hartmut.kaiser_at_[hidden]
Date: 2011-03-26 13:09:26
Author: hkaiser
Date: 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
New Revision: 70574
URL: http://svn.boost.org/trac/boost/changeset/70574
Log:
Spirit: merging from trunk (68457,68496,68522,68865,69218-69219,69294,69476,69546,70042-70043,70049-70050
68320,68374,68377,68386,68449,68461,68485,68487,68489,68491,68494-68495
68519-68520,68523,68536,68538-68539,68548-68549,68576,68645-68646,68657,68676
68687,68690,68707,68725,68744-68746,68852-68853,68861,68870,68904,68906-68908
68938,68989,69020,69022-69024,69091-69092,69103-69104,69114,69136,69138,69193
69202,69204,69233,69292-69293,69295,69297-69298,69323,69337,69378-69380,69405,69429,69431-69433,69444,69450
69495-69498,69501,69503,69505,69527,69599,69618,69623,69670-69671,69673,69675,69772-69774,69780
69811,69813-69814,69833,69851,70045,70211-70216,70224-70225,70483,70549-70550
Fusion: 69113,69118,69137,69583,69589,70008-70009)
Added:
branches/release/boost/spirit/home/karma/detail/indirect_iterator.hpp
- copied, changed from r68657, /trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp
branches/release/boost/spirit/home/qi/nonterminal/success_handler.hpp
- copied unchanged from r69501, /trunk/boost/spirit/home/qi/nonterminal/success_handler.hpp
branches/release/boost/spirit/home/support/utree/
- copied from r68408, /branches/release/boost/spirit/home/support/utree/
branches/release/boost/spirit/home/support/utree.hpp
- copied, changed from r68408, /branches/release/boost/spirit/home/support/utree.hpp
branches/release/boost/spirit/home/support/utree/detail/
- copied from r68408, /branches/release/boost/spirit/home/support/utree/detail/
branches/release/boost/spirit/home/support/utree/detail/utree_detail1.hpp
- copied unchanged from r68408, /branches/release/boost/spirit/home/support/utree/detail/utree_detail1.hpp
branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp
- copied, changed from r68408, /branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp
branches/release/boost/spirit/home/support/utree/operators.hpp
- copied, changed from r68408, /branches/release/boost/spirit/home/support/utree/operators.hpp
branches/release/boost/spirit/home/support/utree/utree.hpp
- copied, changed from r68408, /branches/release/boost/spirit/home/support/utree/utree.hpp
branches/release/boost/spirit/home/support/utree/utree_traits.hpp
- copied, changed from r68408, /branches/release/boost/spirit/home/support/utree/utree_traits.hpp
branches/release/boost/spirit/home/support/utree/utree_traits_fwd.hpp
- copied, changed from r68861, /trunk/boost/spirit/home/support/utree/utree_traits_fwd.hpp
branches/release/boost/spirit/include/qi_as_string.hpp
- copied unchanged from r69671, /trunk/boost/spirit/include/qi_as_string.hpp
branches/release/boost/spirit/include/support_info.hpp
- copied unchanged from r69671, /trunk/boost/spirit/include/support_info.hpp
branches/release/boost/spirit/include/support_utree.hpp
- copied unchanged from r68408, /branches/release/boost/spirit/include/support_utree.hpp
branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp
- copied, changed from r69505, /trunk/boost/spirit/repository/home/qi/directive/kwd.hpp
branches/release/boost/spirit/repository/home/qi/operator/
- copied from r69671, /trunk/boost/spirit/repository/home/qi/operator/
branches/release/boost/spirit/repository/home/qi/operator.hpp
- copied unchanged from r69505, /trunk/boost/spirit/repository/home/qi/operator.hpp
branches/release/boost/spirit/repository/home/qi/operator/detail/
- copied from r69671, /trunk/boost/spirit/repository/home/qi/operator/detail/
branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
- copied, changed from r69671, /trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp
- copied, changed from r69671, /trunk/boost/spirit/repository/home/qi/operator/keywords.hpp
branches/release/boost/spirit/repository/home/qi/primitive/advance.hpp
- copied unchanged from r68461, /trunk/boost/spirit/repository/home/qi/primitive/advance.hpp
branches/release/boost/spirit/repository/home/support/kwd.hpp
- copied unchanged from r69505, /trunk/boost/spirit/repository/home/support/kwd.hpp
branches/release/boost/spirit/repository/include/qi_advance.hpp
- copied unchanged from r68461, /trunk/boost/spirit/repository/include/qi_advance.hpp
branches/release/boost/spirit/repository/include/qi_keywords.hpp
- copied unchanged from r69505, /trunk/boost/spirit/repository/include/qi_keywords.hpp
branches/release/boost/spirit/repository/include/qi_kwd.hpp
- copied unchanged from r69671, /trunk/boost/spirit/repository/include/qi_kwd.hpp
Properties modified:
branches/release/boost/spirit/ (props changed)
branches/release/boost/spirit/home/ (props changed)
branches/release/boost/spirit/home/karma/ (props changed)
branches/release/boost/spirit/home/support/attributes.hpp (contents, props changed)
Text files modified:
branches/release/boost/spirit/home/classic/iterator/file_iterator.hpp | 2
branches/release/boost/spirit/home/classic/iterator/impl/file_iterator.ipp | 10
branches/release/boost/spirit/home/karma/auto/auto.hpp | 20
branches/release/boost/spirit/home/karma/auto/meta_create.hpp | 224
branches/release/boost/spirit/home/karma/auxiliary/attr_cast.hpp | 2
branches/release/boost/spirit/home/karma/auxiliary/eol.hpp | 2
branches/release/boost/spirit/home/karma/auxiliary/eps.hpp | 2
branches/release/boost/spirit/home/karma/auxiliary/lazy.hpp | 2
branches/release/boost/spirit/home/karma/binary/binary.hpp | 33
branches/release/boost/spirit/home/karma/binary/padding.hpp | 2
branches/release/boost/spirit/home/karma/char/char.hpp | 2
branches/release/boost/spirit/home/karma/detail/alternative_function.hpp | 4
branches/release/boost/spirit/home/karma/detail/attributes.hpp | 2
branches/release/boost/spirit/home/karma/detail/extract_from.hpp | 132
branches/release/boost/spirit/home/karma/detail/indirect_iterator.hpp | 17
branches/release/boost/spirit/home/karma/detail/pass_container.hpp | 328 +
branches/release/boost/spirit/home/karma/directive/as.hpp | 4
branches/release/boost/spirit/home/karma/directive/buffer.hpp | 2
branches/release/boost/spirit/home/karma/directive/center_alignment.hpp | 6
branches/release/boost/spirit/home/karma/directive/columns.hpp | 2
branches/release/boost/spirit/home/karma/directive/delimit.hpp | 2
branches/release/boost/spirit/home/karma/directive/duplicate.hpp | 2
branches/release/boost/spirit/home/karma/directive/left_alignment.hpp | 2
branches/release/boost/spirit/home/karma/directive/maxwidth.hpp | 2
branches/release/boost/spirit/home/karma/directive/no_delimit.hpp | 2
branches/release/boost/spirit/home/karma/directive/omit.hpp | 4
branches/release/boost/spirit/home/karma/directive/repeat.hpp | 74
branches/release/boost/spirit/home/karma/directive/right_alignment.hpp | 8
branches/release/boost/spirit/home/karma/directive/strict_relaxed.hpp | 4
branches/release/boost/spirit/home/karma/directive/verbatim.hpp | 2
branches/release/boost/spirit/home/karma/domain.hpp | 21
branches/release/boost/spirit/home/karma/generate.hpp | 59
branches/release/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp | 13
branches/release/boost/spirit/home/karma/nonterminal/rule.hpp | 57
branches/release/boost/spirit/home/karma/numeric/bool.hpp | 54
branches/release/boost/spirit/home/karma/numeric/int.hpp | 68
branches/release/boost/spirit/home/karma/numeric/real.hpp | 60
branches/release/boost/spirit/home/karma/numeric/real_policies.hpp | 4
branches/release/boost/spirit/home/karma/numeric/uint.hpp | 94
branches/release/boost/spirit/home/karma/operator/kleene.hpp | 69
branches/release/boost/spirit/home/karma/operator/list.hpp | 79
branches/release/boost/spirit/home/karma/operator/optional.hpp | 4
branches/release/boost/spirit/home/karma/operator/plus.hpp | 87
branches/release/boost/spirit/home/karma/operator/sequence.hpp | 96
branches/release/boost/spirit/home/karma/phoenix_attributes.hpp | 14
branches/release/boost/spirit/home/karma/stream/stream.hpp | 6
branches/release/boost/spirit/home/karma/string/lit.hpp | 2
branches/release/boost/spirit/home/karma/string/symbols.hpp | 11
branches/release/boost/spirit/home/lex/argument.hpp | 7
branches/release/boost/spirit/home/lex/lexer/char_token_def.hpp | 96
branches/release/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp | 2
branches/release/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp | 8
branches/release/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp | 4
branches/release/boost/spirit/home/lex/lexer/lexertl/token.hpp | 1
branches/release/boost/spirit/home/lex/lexer/string_token_def.hpp | 62
branches/release/boost/spirit/home/lex/lexer/terminals.hpp | 1
branches/release/boost/spirit/home/lex/qi/in_state.hpp | 1
branches/release/boost/spirit/home/lex/qi/plain_token.hpp | 3
branches/release/boost/spirit/home/lex/qi/plain_tokenid.hpp | 3
branches/release/boost/spirit/home/lex/qi/state_switcher.hpp | 4
branches/release/boost/spirit/home/phoenix/core/actor.hpp | 25
branches/release/boost/spirit/home/phoenix/core/value.hpp | 13
branches/release/boost/spirit/home/qi/action/action.hpp | 56
branches/release/boost/spirit/home/qi/auto/auto.hpp | 5
branches/release/boost/spirit/home/qi/auto/meta_create.hpp | 52
branches/release/boost/spirit/home/qi/auxiliary/attr.hpp | 16
branches/release/boost/spirit/home/qi/auxiliary/eoi.hpp | 2
branches/release/boost/spirit/home/qi/auxiliary/eol.hpp | 2
branches/release/boost/spirit/home/qi/auxiliary/eps.hpp | 2
branches/release/boost/spirit/home/qi/auxiliary/lazy.hpp | 2
branches/release/boost/spirit/home/qi/binary/binary.hpp | 23
branches/release/boost/spirit/home/qi/char/char.hpp | 4
branches/release/boost/spirit/home/qi/detail/alternative_function.hpp | 112
branches/release/boost/spirit/home/qi/detail/assign_to.hpp | 136
branches/release/boost/spirit/home/qi/detail/attributes.hpp | 15
branches/release/boost/spirit/home/qi/detail/construct.hpp | 56
branches/release/boost/spirit/home/qi/detail/pass_container.hpp | 336 +
branches/release/boost/spirit/home/qi/directive/as.hpp | 37
branches/release/boost/spirit/home/qi/directive/hold.hpp | 2
branches/release/boost/spirit/home/qi/directive/lexeme.hpp | 2
branches/release/boost/spirit/home/qi/directive/matches.hpp | 2
branches/release/boost/spirit/home/qi/directive/no_skip.hpp | 2
branches/release/boost/spirit/home/qi/directive/omit.hpp | 2
branches/release/boost/spirit/home/qi/directive/raw.hpp | 2
branches/release/boost/spirit/home/qi/directive/repeat.hpp | 94
branches/release/boost/spirit/home/qi/directive/skip.hpp | 2
branches/release/boost/spirit/home/qi/domain.hpp | 18
branches/release/boost/spirit/home/qi/nonterminal.hpp | 1
branches/release/boost/spirit/home/qi/nonterminal/debug_handler.hpp | 14
branches/release/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp | 13
branches/release/boost/spirit/home/qi/nonterminal/rule.hpp | 29
branches/release/boost/spirit/home/qi/nonterminal/simple_trace.hpp | 2
branches/release/boost/spirit/home/qi/numeric/bool.hpp | 29
branches/release/boost/spirit/home/qi/numeric/int.hpp | 58
branches/release/boost/spirit/home/qi/numeric/real.hpp | 39
branches/release/boost/spirit/home/qi/numeric/uint.hpp | 47
branches/release/boost/spirit/home/qi/operator/expect.hpp | 5
branches/release/boost/spirit/home/qi/operator/kleene.hpp | 37
branches/release/boost/spirit/home/qi/operator/list.hpp | 47
branches/release/boost/spirit/home/qi/operator/optional.hpp | 33
branches/release/boost/spirit/home/qi/operator/plus.hpp | 44
branches/release/boost/spirit/home/qi/operator/sequence.hpp | 5
branches/release/boost/spirit/home/qi/operator/sequence_base.hpp | 3
branches/release/boost/spirit/home/qi/parse.hpp | 36
branches/release/boost/spirit/home/qi/stream/detail/iterator_source.hpp | 27
branches/release/boost/spirit/home/qi/stream/stream.hpp | 16
branches/release/boost/spirit/home/qi/string/lit.hpp | 4
branches/release/boost/spirit/home/qi/string/symbols.hpp | 9
branches/release/boost/spirit/home/support/argument.hpp | 47
branches/release/boost/spirit/home/support/attributes.hpp | 160
branches/release/boost/spirit/home/support/attributes_fwd.hpp | 27
branches/release/boost/spirit/home/support/common_terminals.hpp | 153
branches/release/boost/spirit/home/support/container.hpp | 20
branches/release/boost/spirit/home/support/context.hpp | 76
branches/release/boost/spirit/home/support/detail/hold_any.hpp | 140
branches/release/boost/spirit/home/support/iterators/detail/combine_policies.hpp | 6
branches/release/boost/spirit/home/support/iterators/line_pos_iterator.hpp | 67
branches/release/boost/spirit/home/support/lazy.hpp | 2
branches/release/boost/spirit/home/support/string_traits.hpp | 11
branches/release/boost/spirit/home/support/terminal.hpp | 82
branches/release/boost/spirit/home/support/utree.hpp | 1
branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 47
branches/release/boost/spirit/home/support/utree/operators.hpp | 37
branches/release/boost/spirit/home/support/utree/utree.hpp | 19
branches/release/boost/spirit/home/support/utree/utree_traits.hpp | 191
branches/release/boost/spirit/home/support/utree/utree_traits_fwd.hpp | 2
branches/release/boost/spirit/repository/home/qi.hpp | 1
branches/release/boost/spirit/repository/home/qi/directive.hpp | 1
branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp | 70
branches/release/boost/spirit/repository/home/qi/nonterminal/subrule.hpp | 4
branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp | 2897 -----------
branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp | 9624 ---------------------------------------
branches/release/boost/spirit/repository/home/qi/primitive.hpp | 1
branches/release/boost/spirit/version.hpp | 4
134 files changed, 3161 insertions(+), 13937 deletions(-)
Modified: branches/release/boost/spirit/home/classic/iterator/file_iterator.hpp
==============================================================================
--- branches/release/boost/spirit/home/classic/iterator/file_iterator.hpp (original)
+++ branches/release/boost/spirit/home/classic/iterator/file_iterator.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -166,7 +166,7 @@
file_iterator()
{}
- file_iterator(std::string fileName)
+ file_iterator(std::string const& fileName)
: base_t(adapted_t(fileName))
{}
Modified: branches/release/boost/spirit/home/classic/iterator/impl/file_iterator.ipp
==============================================================================
--- branches/release/boost/spirit/home/classic/iterator/impl/file_iterator.ipp (original)
+++ branches/release/boost/spirit/home/classic/iterator/impl/file_iterator.ipp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -63,7 +63,7 @@
std_file_iterator()
{}
- explicit std_file_iterator(std::string fileName)
+ explicit std_file_iterator(std::string const& fileName)
{
using namespace std;
FILE* f = fopen(fileName.c_str(), "rb");
@@ -177,9 +177,11 @@
typedef CharT value_type;
mmap_file_iterator()
+ : m_filesize(0), m_curChar(0)
{}
- explicit mmap_file_iterator(std::string fileName)
+ explicit mmap_file_iterator(std::string const& fileName)
+ : m_filesize(0), m_curChar(0)
{
HANDLE hFile = ::CreateFileA(
fileName.c_str(),
@@ -334,9 +336,11 @@
typedef CharT value_type;
mmap_file_iterator()
+ : m_curChar(0)
{}
- explicit mmap_file_iterator(std::string file_name)
+ explicit mmap_file_iterator(std::string const& file_name)
+ : m_curChar(0)
{
// open the file
int fd = open(file_name.c_str(),
Modified: branches/release/boost/spirit/home/karma/auto/auto.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auto/auto.hpp (original)
+++ branches/release/boost/spirit/home/karma/auto/auto.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -47,8 +47,10 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::auto_;
- using spirit::auto__type;
+#endif
+ using spirit::auto_type;
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
@@ -60,13 +62,13 @@
template <typename Context, typename Unused>
struct attribute
{
- typedef spirit::hold_any type;
+ typedef spirit::basic_hold_any<char> type;
};
auto_generator(Modifiers const& modifiers)
: modifiers_(modifiers) {}
- // auto_generator has an attached attribute
+ // auto_generator has an attached attribute
template <
typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
@@ -84,8 +86,8 @@
static bool
generate(OutputIterator&, Context&, Delimiter const&, unused_type)
{
- // It is not possible (doesn't make sense) to use auto_ generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use auto_ generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false, auto_not_usable_without_attribute, ());
@@ -116,10 +118,10 @@
lit_auto_generator(typename add_reference<T>::type t, Modifiers const& modifiers)
: t_(t)
- , generator_(compile<karma::domain>(create_generator<T>(), modifiers))
+ , generator_(compile<karma::domain>(create_generator<T>(), modifiers))
{}
- // auto_generator has an attached attribute
+ // auto_generator has an attached attribute
template <
typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
@@ -135,7 +137,7 @@
return info("auto_");
}
- typedef typename spirit::result_of::create_generator<T>::type
+ typedef typename spirit::result_of::create_generator<T>::type
generator_type;
typedef typename spirit::result_of::compile<
@@ -155,7 +157,7 @@
// auto_
template <typename Modifiers>
- struct make_primitive<tag::auto_, Modifiers>
+ struct make_primitive<tag::auto_, Modifiers>
{
typedef auto_generator<Modifiers> result_type;
Modified: branches/release/boost/spirit/home/karma/auto/meta_create.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auto/meta_create.hpp (original)
+++ branches/release/boost/spirit/home/karma/auto/meta_create.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -30,8 +30,8 @@
{
///////////////////////////////////////////////////////////////////////////
// compatible STL containers
- template <typename Container>
- struct meta_create_container
+ template <typename Container>
+ struct meta_create_container
{
typedef make_unary_proto_expr<
typename Container::value_type
@@ -48,71 +48,71 @@
///////////////////////////////////////////////////////////////////////////
// String types
- template <typename String>
- struct meta_create_string
+ template <typename String>
+ struct meta_create_string
{
- typedef spirit::standard::string_type type;
+ typedef spirit::standard::string_type type;
static type const& call() { return spirit::standard::string; }
};
- template <>
+ template <>
struct meta_create_string<wchar_t*>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <>
+ template <>
struct meta_create_string<wchar_t const*>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <int N>
+ template <int N>
struct meta_create_string<wchar_t[N]>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <int N>
+ template <int N>
struct meta_create_string<wchar_t const[N]>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <int N>
+ template <int N>
struct meta_create_string<wchar_t(&)[N]>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <int N>
+ template <int N>
struct meta_create_string<wchar_t const(&)[N]>
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
- template <typename Traits, typename Allocator>
+ template <typename Traits, typename Allocator>
struct meta_create_string<std::basic_string<wchar_t, Traits, Allocator> >
{
- typedef spirit::standard_wide::string_type type;
+ typedef spirit::standard_wide::string_type type;
static type const& call() { return spirit::standard_wide::string; }
};
///////////////////////////////////////////////////////////////////////////
// Fusion sequences
- template <typename Sequence>
- struct meta_create_sequence
+ template <typename Sequence>
+ struct meta_create_sequence
{
// create a mpl sequence from the given fusion sequence
typedef typename mpl::fold<
typename fusion::result_of::as_vector<Sequence>::type
- , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
+ , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
>::type sequence_type;
typedef make_nary_proto_expr<
@@ -128,10 +128,10 @@
};
///////////////////////////////////////////////////////////////////////////
- // the default is to use the standard streaming operator unless it's a
+ // the default is to use the standard streaming operator unless it's a
// STL container or a fusion sequence
- // The default implementation will be chosen if no predefined mapping of
+ // The default implementation will be chosen if no predefined mapping of
// the data type T to a Karma component is defined.
struct no_auto_mapping_exists {};
@@ -142,9 +142,9 @@
struct meta_create_impl<T
, typename enable_if<
mpl::and_<
- traits::is_container<T>
+ traits::is_container<T>
, mpl::not_<traits::is_string<T> >
- , mpl::not_<fusion::traits::is_sequence<T> >
+ , mpl::not_<fusion::traits::is_sequence<T> >
> >::type>
: meta_create_container<T> {};
@@ -155,7 +155,7 @@
template <typename T>
struct meta_create_impl<T, typename enable_if<
- spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
+ spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
>::type>
: meta_create_sequence<T> {};
@@ -164,8 +164,8 @@
///////////////////////////////////////////////////////////////////////////
// optional
- template <typename T>
- struct meta_create<boost::optional<T> >
+ template <typename T>
+ struct meta_create<boost::optional<T> >
{
typedef make_unary_proto_expr<
T, proto::tag::negate, karma::domain
@@ -181,8 +181,8 @@
///////////////////////////////////////////////////////////////////////////
// alternatives
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
{
typedef make_nary_proto_expr<
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
@@ -201,113 +201,113 @@
// predefined specializations for primitive components
// character generator
- template <>
- struct meta_create<char>
- {
+ template <>
+ struct meta_create<char>
+ {
typedef spirit::standard::char_type type;
static type const& call() { return spirit::standard::char_; }
};
- template <>
- struct meta_create<signed char>
- {
+ template <>
+ struct meta_create<signed char>
+ {
typedef spirit::standard::char_type type;
static type const& call() { return spirit::standard::char_; }
};
- template <>
- struct meta_create<wchar_t>
- {
+ template <>
+ struct meta_create<wchar_t>
+ {
typedef spirit::standard_wide::char_type type;
static type const& call() { return spirit::standard_wide::char_; }
};
- template <>
- struct meta_create<unsigned char>
- {
+ template <>
+ struct meta_create<unsigned char>
+ {
typedef spirit::standard::char_type type;
static type const& call() { return spirit::standard::char_; }
};
// boolean generator
- template <>
- struct meta_create<bool>
- {
- typedef spirit::bool__type type;
- static type const& call() { return spirit::bool_; }
+ template <>
+ struct meta_create<bool>
+ {
+ typedef spirit::bool_type type;
+ static type call() { return type(); }
};
// integral generators
- template <>
- struct meta_create<int>
- {
- typedef spirit::int__type type;
- static type const& call() { return spirit::int_; }
- };
- template <>
- struct meta_create<short>
- {
- typedef spirit::short__type type;
- static type const& call() { return spirit::short_; }
- };
- template <>
- struct meta_create<long>
- {
- typedef spirit::long__type type;
- static type const& call() { return spirit::long_; }
- };
- template <>
- struct meta_create<unsigned int>
- {
- typedef spirit::uint__type type;
- static type const& call() { return spirit::uint_; }
+ template <>
+ struct meta_create<int>
+ {
+ typedef spirit::int_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<short>
+ {
+ typedef spirit::short_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<long>
+ {
+ typedef spirit::long_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<unsigned int>
+ {
+ typedef spirit::uint_type type;
+ static type call() { return type(); }
};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- template <>
- struct meta_create<unsigned short>
- {
- typedef spirit::ushort__type type;
- static type const& call() { return spirit::ushort_; }
+ template <>
+ struct meta_create<unsigned short>
+ {
+ typedef spirit::ushort_type type;
+ static type call() { return type(); }
};
#endif
- template <>
- struct meta_create<unsigned long>
- {
- typedef spirit::ulong__type type;
- static type const& call() { return spirit::ulong_; }
+ template <>
+ struct meta_create<unsigned long>
+ {
+ typedef spirit::ulong_type type;
+ static type call() { return type(); }
};
#ifdef BOOST_HAS_LONG_LONG
- template <>
- struct meta_create<boost::long_long_type>
- {
- typedef spirit::long_long_type type;
- static type const& call() { return spirit::long_long; }
- };
- template <>
- struct meta_create<boost::ulong_long_type>
- {
- typedef spirit::ulong_long_type type;
- static type const& call() { return spirit::ulong_long; }
+ template <>
+ struct meta_create<boost::long_long_type>
+ {
+ typedef spirit::long_long_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<boost::ulong_long_type>
+ {
+ typedef spirit::ulong_long_type type;
+ static type call() { return type(); }
};
#endif
// floating point generators
- template <>
- struct meta_create<float>
- {
- typedef spirit::float__type type;
- static type const& call() { return spirit::float_; }
- };
- template <>
- struct meta_create<double>
- {
- typedef spirit::double__type type;
- static type const& call() { return spirit::double_; }
- };
- template <>
- struct meta_create<long double>
- {
- typedef spirit::long_double_type type;
- static type const& call() { return spirit::long_double; }
+ template <>
+ struct meta_create<float>
+ {
+ typedef spirit::float_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<double>
+ {
+ typedef spirit::double_type type;
+ static type call() { return type(); }
+ };
+ template <>
+ struct meta_create<long double>
+ {
+ typedef spirit::long_double_type type;
+ static type call() { return type(); }
};
}}}
@@ -326,10 +326,10 @@
: create_generator<typename spirit::detail::remove_const_ref<T>::type> {};
///////////////////////////////////////////////////////////////////////////
- // Check whether a valid mapping exits for the given data type to a Karma
- // component
+ // Check whether a valid mapping exits for the given data type to a Karma
+ // component
template <typename T>
- struct meta_create_exists<karma::domain, T>
+ struct meta_create_exists<karma::domain, T>
: mpl::not_<is_same<
karma::no_auto_mapping_exists
, typename meta_create<karma::domain, T>::type
Modified: branches/release/boost/spirit/home/karma/auxiliary/attr_cast.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auxiliary/attr_cast.hpp (original)
+++ branches/release/boost/spirit/home/karma/auxiliary/attr_cast.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -31,7 +31,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::attr_cast;
+#endif
///////////////////////////////////////////////////////////////////////////
// attr_cast_generator consumes the attribute of subject generator without
Modified: branches/release/boost/spirit/home/karma/auxiliary/eol.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auxiliary/eol.hpp (original)
+++ branches/release/boost/spirit/home/karma/auxiliary/eol.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -33,7 +33,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::eol;
+#endif
using boost::spirit::eol_type;
struct eol_generator : primitive_generator<eol_generator>
Modified: branches/release/boost/spirit/home/karma/auxiliary/eps.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auxiliary/eps.hpp (original)
+++ branches/release/boost/spirit/home/karma/auxiliary/eps.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -45,7 +45,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::eps;
+#endif
using boost::spirit::eps_type;
struct eps_generator : primitive_generator<eps_generator>
Modified: branches/release/boost/spirit/home/karma/auxiliary/lazy.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/auxiliary/lazy.hpp (original)
+++ branches/release/boost/spirit/home/karma/auxiliary/lazy.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,7 +18,7 @@
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/lazy.hpp>
-#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
Modified: branches/release/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/binary/binary.hpp (original)
+++ branches/release/boost/spirit/home/karma/binary/binary.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -71,26 +71,31 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::byte_;
- using boost::spirit::byte__type;
using boost::spirit::word;
- using boost::spirit::word_type;
using boost::spirit::big_word;
- using boost::spirit::big_word_type;
using boost::spirit::little_word;
- using boost::spirit::little_word_type;
using boost::spirit::dword;
- using boost::spirit::dword_type;
using boost::spirit::big_dword;
- using boost::spirit::big_dword_type;
using boost::spirit::little_dword;
- using boost::spirit::little_dword_type;
#ifdef BOOST_HAS_LONG_LONG
using boost::spirit::qword;
- using boost::spirit::qword_type;
using boost::spirit::big_qword;
- using boost::spirit::big_qword_type;
using boost::spirit::little_qword;
+#endif
+#endif
+
+ using boost::spirit::byte_type;
+ using boost::spirit::word_type;
+ using boost::spirit::big_word_type;
+ using boost::spirit::little_word_type;
+ using boost::spirit::dword_type;
+ using boost::spirit::big_dword_type;
+ using boost::spirit::little_dword_type;
+#ifdef BOOST_HAS_LONG_LONG
+ using boost::spirit::qword_type;
+ using boost::spirit::big_qword_type;
using boost::spirit::little_qword_type;
#endif
@@ -170,11 +175,11 @@
///////////////////////////////////////////////////////////////////////////
template <BOOST_SCOPED_ENUM(boost::integer::endianness) endian, int bits>
- struct any_binary_generator
+ struct any_binary_generator
: primitive_generator<any_binary_generator<endian, bits> >
{
template <typename Context, typename Unused = unused_type>
- struct attribute
+ struct attribute
: karma::detail::integer<bits>
{};
@@ -208,7 +213,7 @@
unsigned char const* bytes =
reinterpret_cast<unsigned char const*>(&p);
- for (unsigned int i = 0; i < sizeof(p); ++i)
+ for (unsigned int i = 0; i < sizeof(p); ++i)
{
if (!detail::generate_to(sink, *bytes++))
return false;
@@ -223,8 +228,8 @@
static bool generate(OutputIterator& sink, Context&, Delimiter const& d
, unused_type)
{
- // It is not possible (doesn't make sense) to use binary generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use binary generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false,
Modified: branches/release/boost/spirit/home/karma/binary/padding.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/binary/padding.hpp (original)
+++ branches/release/boost/spirit/home/karma/binary/padding.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -45,7 +45,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::pad;
+#endif
using boost::spirit::pad_type;
struct binary_padding_generator
Modified: branches/release/boost/spirit/home/karma/char/char.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/char/char.hpp (original)
+++ branches/release/boost/spirit/home/karma/char/char.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -94,7 +94,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit; // lit('x') is equivalent to 'x'
+#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/detail/alternative_function.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/detail/alternative_function.hpp (original)
+++ branches/release/boost/spirit/home/karma/detail/alternative_function.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,6 +14,7 @@
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/directive/buffer.hpp>
#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
@@ -128,7 +129,8 @@
// returns true if any of the generators succeed
typedef typename component_type::compatible_type compatible_type;
- return component.generate(sink, ctx, d, get<compatible_type>(attr_));
+ return component.generate(sink, ctx, d
+ , boost::get<compatible_type>(attr_));
}
};
Modified: branches/release/boost/spirit/home/karma/detail/attributes.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/detail/attributes.hpp (original)
+++ branches/release/boost/spirit/home/karma/detail/attributes.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -20,7 +20,7 @@
typedef Transformed type;
static Transformed pre(Exposed& val)
{
- return Transformed(traits::extract_from<Exposed>(val, unused));
+ return Transformed(traits::extract_from<Transformed>(val, unused));
}
// Karma only, no post() and no fail() required
};
Modified: branches/release/boost/spirit/home/karma/detail/extract_from.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/detail/extract_from.hpp (original)
+++ branches/release/boost/spirit/home/karma/detail/extract_from.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -10,7 +10,7 @@
#pragma once
#endif
-#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
@@ -80,24 +80,24 @@
// This handles optional attributes.
template <typename Attribute, typename Exposed>
- struct extract_from_attribute<optional<Attribute>, Exposed>
+ struct extract_from_attribute<boost::optional<Attribute>, Exposed>
{
typedef Attribute const& type;
template <typename Context>
- static type call(optional<Attribute> const& attr, Context& ctx)
+ static type call(boost::optional<Attribute> const& attr, Context& ctx)
{
return extract_from<Exposed>(boost::get<Attribute>(attr), ctx);
}
};
template <typename Attribute, typename Exposed>
- struct extract_from_attribute<optional<Attribute const>, Exposed>
+ struct extract_from_attribute<boost::optional<Attribute const>, Exposed>
{
typedef Attribute const& type;
template <typename Context>
- static type call(optional<Attribute const> const& attr, Context& ctx)
+ static type call(boost::optional<Attribute const> const& attr, Context& ctx)
{
return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx);
}
@@ -117,8 +117,109 @@
};
///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Exposed, typename Enable>
+ struct extract_from_container
+ {
+ typedef typename traits::container_value<Attribute const>::type
+ value_type;
+ typedef typename is_convertible<value_type, Exposed>::type
+ is_convertible_to_value_type;
+
+ typedef typename mpl::if_<
+ mpl::or_<
+ is_same<value_type, Exposed>, is_same<Attribute, Exposed> >
+ , Exposed const&, Exposed
+ >::type type;
+
+ // handle case where container value type is convertible to result type
+ // we simply return the front element of the container
+ template <typename Context, typename Pred>
+ static type call(Attribute const& attr, Context& ctx, mpl::true_, Pred)
+ {
+ // return first element from container
+ typedef typename traits::container_iterator<Attribute const>::type
+ iterator_type;
+
+ iterator_type it = boost::begin(attr);
+ type result = *it;
+ ++it;
+ return result;
+ }
+
+ // handle strings
+ template <typename Iterator>
+ static void append_to_string(Exposed& result, Iterator begin, Iterator end)
+ {
+ for (Iterator i = begin; i != end; ++i)
+ push_back(result, *i);
+ }
+
+ template <typename Context>
+ static type call(Attribute const& attr, Context& ctx, mpl::false_, mpl::true_)
+ {
+ typedef typename char_type_of<Attribute>::type char_type;
+
+ Exposed result;
+ append_to_string(result, traits::get_begin<char_type>(attr)
+ , traits::get_end<char_type>(attr));
+ return result;
+ }
+
+ // everything else gets just passed through
+ template <typename Context>
+ static type call(Attribute const& attr, Context& ctx, mpl::false_, mpl::false_)
+ {
+ return type(attr);
+ }
+
+ template <typename Context>
+ static type call(Attribute const& attr, Context& ctx)
+ {
+ typedef typename mpl::and_<
+ traits::is_string<Exposed>, traits::is_string<Attribute>
+ >::type handle_strings;
+
+ // return first element from container
+ return call(attr, ctx, is_convertible_to_value_type()
+ , handle_strings());
+ }
+ };
+
+ template <typename Attribute>
+ struct extract_from_container<Attribute, Attribute>
+ {
+ typedef Attribute const& type;
+
+ template <typename Context>
+ static type call(Attribute const& attr, Context& ctx)
+ {
+ return attr;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ // overload for non-container attributes
+ template <typename Exposed, typename Attribute, typename Context>
+ inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
+ extract_from(Attribute const& attr, Context& ctx, mpl::false_)
+ {
+ return extract_from_attribute<Attribute, Exposed>::call(attr, ctx);
+ }
+
+ // overload for containers (but not for variants or optionals
+ // holding containers)
+ template <typename Exposed, typename Attribute, typename Context>
+ inline typename spirit::result_of::extract_from<Exposed, Attribute>::type
+ extract_from(Attribute const& attr, Context& ctx, mpl::true_)
+ {
+ return extract_from_container<Attribute, Exposed>::call(attr, ctx);
+ }
+ }
+
template <typename Exposed, typename Attribute, typename Context>
- typename spirit::result_of::extract_from<Exposed, Attribute>::type
+ inline 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))
@@ -126,11 +227,18 @@
#endif
)
{
- return extract_from_attribute<Attribute, Exposed>::call(attr, ctx);
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , traits::not_is_variant<Attribute>
+ , traits::not_is_optional<Attribute>
+ >::type is_not_wrapped_container;
+
+ return detail::extract_from<Exposed>(attr, ctx
+ , is_not_wrapped_container());
}
template <typename Exposed, typename Context>
- unused_type extract_from(unused_type, Context&)
+ inline unused_type extract_from(unused_type, Context&)
{
return unused;
}
@@ -141,7 +249,13 @@
{
template <typename Exposed, typename Attribute>
struct extract_from
- : traits::extract_from_attribute<Attribute, Exposed>
+ : mpl::if_<
+ mpl::and_<
+ traits::is_container<Attribute>
+ , traits::not_is_variant<Attribute>
+ , traits::not_is_optional<Attribute> >
+ , traits::extract_from_container<Attribute, Exposed>
+ , traits::extract_from_attribute<Attribute, Exposed> >::type
{};
template <typename Exposed>
Copied: branches/release/boost/spirit/home/karma/detail/indirect_iterator.hpp (from r68657, /trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp)
==============================================================================
--- /trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp (original)
+++ branches/release/boost/spirit/home/karma/detail/indirect_iterator.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -64,17 +64,21 @@
private:
Iterator* iter_;
};
+}}}}
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
template <typename Iterator>
struct make_indirect_iterator
{
- typedef indirect_iterator<Iterator> type;
+ typedef karma::detail::indirect_iterator<Iterator> type;
};
template <typename Iterator>
- struct make_indirect_iterator<indirect_iterator<Iterator> >
+ struct make_indirect_iterator<karma::detail::indirect_iterator<Iterator> >
{
- typedef indirect_iterator<Iterator> type;
+ typedef karma::detail::indirect_iterator<Iterator> type;
};
template <>
@@ -82,6 +86,11 @@
{
typedef unused_type const* type;
};
-}}}}
+
+ template <typename Iterator>
+ struct make_indirect_iterator<Iterator const&>
+ : make_indirect_iterator<Iterator const>
+ {};
+}}}
#endif
Modified: branches/release/boost/spirit/home/karma/detail/pass_container.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/detail/pass_container.hpp (original)
+++ branches/release/boost/spirit/home/karma/detail/pass_container.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -19,52 +19,227 @@
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/range/iterator_range.hpp>
-#include <boost/iterator/iterator_facade.hpp>
+#include <boost/fusion/include/deduce_sequence.hpp>
+
+#include <boost/mpl/print.hpp>
namespace boost { namespace spirit { namespace karma { namespace detail
{
- // has_same_elements: utility to check if the LHS attribute
- // is an STL container and that its value_type is convertible
- // to the RHS.
-
- template <typename RHS, typename LHSAttribute
- , bool IsContainer = traits::is_container<LHSAttribute>::value>
- struct has_same_elements : mpl::false_ {};
+ // Helper meta-function allowing to evaluate weak substitutability and
+ // negate the result if the predicate (Sequence) is not true
+ template <typename Sequence, typename Attribute, typename ValueType>
+ struct negate_weak_substitute_if_not
+ : mpl::if_<
+ Sequence
+ , typename traits::is_weak_substitute<Attribute, ValueType>::type
+ , typename mpl::not_<
+ traits::is_weak_substitute<Attribute, ValueType>
+ >::type>
+ {};
+
+ // pass_through_container: utility to check decide whether a provided
+ // container attribute needs to be passed through to the current component
+ // or of we need to split the container by passing along instances of its
+ // value type
+
+ // if the expected attribute of the current component is neither a Fusion
+ // sequence nor a container, we will pass through the provided container
+ // only if its value type is not compatible with the component
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename Enable = void>
+ struct pass_through_container_base
+ : negate_weak_substitute_if_not<Sequence, ValueType, Attribute>
+ {};
+
+ // Specialization for fusion sequences, in this case we check whether all
+ // the types in the sequence are convertible to the lhs attribute.
+ //
+ // We return false if the rhs attribute itself is a fusion sequence, which
+ // is compatible with the LHS sequence (we want to pass through this
+ // attribute without it being split apart).
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence = mpl::true_>
+ struct not_compatible_element
+ : mpl::and_<
+ negate_weak_substitute_if_not<Sequence, Container, Attribute>
+ , negate_weak_substitute_if_not<Sequence, ValueType, Attribute> >
+ {};
+
+ // If the value type of the container is not a Fusion sequence, we pass
+ // through the container if each of the elements of the Attribute
+ // sequence is compatible with either the container or its value type.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence
+ , bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
+ struct pass_through_container_fusion_sequence
+ {
+ typedef typename mpl::find_if<
+ Attribute, not_compatible_element<Container, ValueType, mpl::_1>
+ >::type iter;
+ typedef typename mpl::end<Attribute>::type end;
+
+ typedef typename is_same<iter, end>::type type;
+ };
+
+ // If both, the Attribute and the value type of the provided container
+ // are Fusion sequences, we pass the container only if the two
+ // sequences are not compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence, true>
+ {
+ typedef typename mpl::find_if<
+ Attribute
+ , not_compatible_element<Container, ValueType, mpl::_1, Sequence>
+ >::type iter;
+ typedef typename mpl::end<Attribute>::type end;
+
+ typedef typename is_same<iter, end>::type type;
+ };
- template <typename RHS, typename LHSAttribute>
- struct has_same_elements<RHS, LHSAttribute, true>
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_base<Container, ValueType, Attribute
+ , Sequence
+ , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence>
+ {};
+
+ // Specialization for containers
+ //
+ // If the value type of the attribute of the current component is not
+ // a Fusion sequence, we have to pass through the provided container if
+ // both are compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename AttributeValueType
+ , bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
+ struct pass_through_container_container
+ : mpl::or_<
+ traits::is_weak_substitute<Container, Attribute>
+ , traits::is_weak_substitute<Container, AttributeValueType> >
+ {};
+
+ // If the value type of the exposed container attribute is a Fusion
+ // sequence, we use the already existing logic for those.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename AttributeValueType>
+ struct pass_through_container_container<
+ Container, ValueType, Attribute, Sequence, AttributeValueType, true>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, AttributeValueType, Sequence>
+ {};
+
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_base<Container, ValueType, Attribute
+ , Sequence
+ , typename enable_if<traits::is_container<Attribute> >::type>
+ : detail::pass_through_container_container<
+ Container, ValueType, Attribute, Sequence
+ , typename traits::container_value<Attribute>::type>
+ {};
+
+ // Specialization for exposed optional attributes
+ //
+ // If the type embedded in the exposed optional is not a Fusion
+ // sequence we pass through the container attribute if it is compatible
+ // either to the optionals embedded type or to the containers value
+ // type.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence
+ , bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
+ struct pass_through_container_optional
: mpl::or_<
- is_convertible<RHS, typename LHSAttribute::value_type>
- , is_same<typename LHSAttribute::value_type, hold_any>
- > {};
-
- template <typename RHS, typename T>
- struct has_same_elements<RHS, optional<T>, true>
- : has_same_elements<RHS, T> {};
+ traits::is_weak_substitute<Container, Attribute>
+ , traits::is_weak_substitute<ValueType, Attribute> >
+ {};
+
+ // If the embedded type of the exposed optional attribute is a Fusion
+ // sequence, we use the already existing logic for those.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_optional<
+ Container, ValueType, Attribute, Sequence, true>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence>
+ {};
-#define BOOST_SPIRIT_IS_CONVERTIBLE(z, N, data) \
- has_same_elements<RHS, BOOST_PP_CAT(T, N)>::value || \
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container
+ : pass_through_container_base<Container, ValueType, Attribute, Sequence>
+ {};
+
+ // Handle optional attributes
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, ValueType, boost::optional<Attribute>, Sequence>
+ : pass_through_container_optional<
+ Container, ValueType, Attribute, Sequence>
+ {};
+
+ // If both, the containers value type and the exposed attribute type are
+ // optionals we are allowed to pass through the the container only if the
+ // embedded types of those optionals are not compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, boost::optional<ValueType>, boost::optional<Attribute>
+ , Sequence>
+ : mpl::not_<traits::is_weak_substitute<ValueType, Attribute> >
+ {};
+
+ // Specialization for exposed variant attributes
+ //
+ // We pass through the container attribute if at least one of the embedded
+ // types in the variant requires to pass through the attribute
+
+#define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \
+ pass_through_container<Container, ValueType, \
+ BOOST_PP_CAT(T, N), Sequence>::type::value || \
/***/
- // Note: variants are treated as containers if one of the held types is a
- // container (see support/container.hpp).
- template <typename RHS, BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct has_same_elements<
- RHS, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, true>
+ template <typename Container, typename ValueType, typename Sequence
+ , BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct pass_through_container<Container, ValueType
+ , boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
- , BOOST_SPIRIT_IS_CONVERTIBLE, _) false> {};
+ , BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
+ {};
-#undef BOOST_SPIRIT_IS_CONVERTIBLE
+#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
+}}}}
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // forwarding customization point for domain karma::domain
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, ValueType, Attribute, Sequence, karma::domain>
+ : karma::detail::pass_through_container<
+ Container, ValueType, Attribute, Sequence>
+ {};
+}}}
+
+namespace boost { namespace spirit { namespace karma { namespace detail
+{
///////////////////////////////////////////////////////////////////////////
// This function handles the case where the attribute (Attr) given
// to the sequence is an STL container. This is a wrapper around F.
// The function F does the actual generating.
- template <typename F, typename Attr, typename Iterator, typename Strict>
+ template <typename F, typename Attr, typename Iterator, typename Sequence>
struct pass_container
{
typedef typename F::context_type context_type;
@@ -73,53 +248,43 @@
: f(f), iter(begin), end(end)
{}
+ bool is_at_end() const
+ {
+ return traits::compare(iter, end);
+ }
+
+ void next()
+ {
+ traits::next(iter);
+ }
+
// this is for the case when the current element expects an attribute
// which is taken from the next entry in the container
template <typename Component>
- bool dispatch_attribute_element(Component const& component, mpl::false_) const
+ bool dispatch_container(Component const& component, mpl::false_) const
{
// get the next value to generate from container
- if (!traits::compare(iter, end) && !f(component, traits::deref(iter)))
+ if (!is_at_end() && !f(component, traits::deref(iter)))
{
// needs to return false as long as everything is ok
traits::next(iter);
return false;
}
+
// either no elements available any more or generation failed
return true;
}
- // This is for the case when the current element expects an attribute
- // which is a container itself, this element will get the rest of the
- // attribute container.
+ // this is for the case when the current element is able to handle an
+ // attribute which is a container itself, this element will push its
+ // data directly into the attribute container
template <typename Component>
- bool dispatch_attribute_element(Component const& component, mpl::true_) const
+ bool dispatch_container(Component const& component, mpl::true_) const
{
return f(component, make_iterator_range(iter, end));
}
- // This handles the distinction between elements in a sequence expecting
- // containers themselves and elements expecting non-containers as their
- // attribute. Note: is_container treats optional<T>, where T is a
- // container as a container as well.
- template <typename Component>
- bool dispatch_attribute(Component const& component, mpl::true_) const
- {
- typedef typename traits::attribute_of<
- Component, context_type>::type attribute_type;
-
-// typedef mpl::and_<
-// traits::is_container<attribute_type>
-// , is_convertible<Attr, attribute_type> > predicate;
-
- typedef mpl::and_<
- traits::is_container<attribute_type>
- , traits::handles_container<Component, Attr, context_type>
- > predicate;
-
- return dispatch_attribute_element(component, predicate());
- }
-
+ ///////////////////////////////////////////////////////////////////////
// this is for the case when the current element doesn't expect an
// attribute
template <typename Component>
@@ -128,30 +293,25 @@
return f(component, unused);
}
- // This handles the case where the attribute of the component
- // is not a STL container or which elements are not
- // convertible to the target attribute (Attr) value_type.
+ // the current element expects an attribute
template <typename Component>
- bool dispatch_main(Component const& component, mpl::false_) const
+ bool dispatch_attribute(Component const& component, mpl::true_) const
{
- // we need to dispatch again depending on the type of the attribute
- // of the current element (component). If this is has no attribute
- // we shouldn't use an element of the container but unused_type
- // instead
- typedef traits::not_is_unused<
- typename traits::attribute_of<Component, context_type>::type
+ typedef typename traits::container_value<Attr>::type value_type;
+ typedef typename
+ traits::attribute_of<Component, context_type>::type
+ lhs_attribute;
+
+ // this predicate detects, whether the value type of the container
+ // attribute is a substitute for the attribute of the current
+ // element
+ typedef mpl::and_<
+ traits::handles_container<Component, Attr, context_type>
+ , traits::pass_through_container<
+ Attr, value_type, lhs_attribute, Sequence, karma::domain>
> predicate;
- return dispatch_attribute(component, predicate());
- }
-
- // This handles the case where the attribute of the component is
- // an STL container *and* its value_type is convertible to the
- // target attribute's (Attr) value_type.
- template <typename Component>
- bool dispatch_main(Component const& component, mpl::true_) const
- {
- return f(component, make_iterator_range(iter, end));
+ return dispatch_container(component, predicate());
}
// Dispatches to dispatch_main depending on the attribute type
@@ -159,17 +319,15 @@
template <typename Component>
bool operator()(Component const& component) const
{
- typedef typename traits::container_value<Attr>::type rhs;
- typedef typename traits::attribute_of<
- Component, context_type>::type lhs_attribute;
-
- typedef mpl::and_<
- has_same_elements<rhs, lhs_attribute>
- , traits::handles_container<Component, Attr, context_type>
+ // we need to dispatch depending on the type of the attribute
+ // of the current element (component). If this is has no attribute
+ // we shouldn't use an element of the container but unused_type
+ // instead
+ typedef traits::not_is_unused<
+ typename traits::attribute_of<Component, context_type>::type
> predicate;
- // false means everything went ok
- return dispatch_main(component, predicate());
+ return dispatch_attribute(component, predicate());
}
F f;
Modified: branches/release/boost/spirit/home/karma/directive/as.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/as.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/as.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -62,9 +62,11 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::as_string;
- using spirit::as_string_type;
using spirit::as_wstring;
+#endif
+ using spirit::as_string_type;
using spirit::as_wstring_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/buffer.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/buffer.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/buffer.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -34,7 +34,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::buffer;
+#endif
using spirit::buffer_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/center_alignment.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/center_alignment.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/center_alignment.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -51,7 +51,7 @@
, terminal_ex<tag::center, fusion::vector1<T> > >
: mpl::true_ {};
- // enables *lazy* delimit(d)[g], where d provides a generator
+ // enables *lazy* center(d)[g], where d provides a generator
template <>
struct use_lazy_directive<karma::domain, tag::center, 1>
: mpl::true_ {};
@@ -63,7 +63,7 @@
, terminal_ex<tag::center, fusion::vector2<Width, Padding> > >
: spirit::traits::matches<karma::domain, Padding> {};
- // enables *lazy* delimit(w, d)[g], where d provides a generator and w is
+ // enables *lazy* center(w, d)[g], where d provides a generator and w is
// a maximum width
template <>
struct use_lazy_directive<karma::domain, tag::center, 2>
@@ -74,7 +74,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::center;
+#endif
using spirit::center_type;
namespace detail
Modified: branches/release/boost/spirit/home/karma/directive/columns.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/columns.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/columns.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -62,7 +62,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::columns;
+#endif
using spirit::columns_type;
namespace detail
Modified: branches/release/boost/spirit/home/karma/directive/delimit.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/delimit.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/delimit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -49,7 +49,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::delimit;
+#endif
using spirit::delimit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/duplicate.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/duplicate.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/duplicate.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -38,7 +38,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::duplicate;
+#endif
using spirit::duplicate_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/left_alignment.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/left_alignment.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/left_alignment.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -74,7 +74,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::left_align;
+#endif
using spirit::left_align_type;
namespace detail
Modified: branches/release/boost/spirit/home/karma/directive/maxwidth.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/maxwidth.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/maxwidth.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -72,7 +72,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::maxwidth;
+#endif
using spirit::maxwidth_type;
namespace detail
Modified: branches/release/boost/spirit/home/karma/directive/no_delimit.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/no_delimit.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/no_delimit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -35,7 +35,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::no_delimit;
+#endif
using spirit::no_delimit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/omit.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/omit.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/omit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -36,9 +36,11 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::omit;
- using spirit::omit_type;
using spirit::skip;
+#endif
+ using spirit::omit_type;
using spirit::skip_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/directive/repeat.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/repeat.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/repeat.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -69,9 +69,11 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::repeat;
- using spirit::repeat_type;
using spirit::inf;
+#endif
+ using spirit::repeat_type;
using spirit::inf_type;
///////////////////////////////////////////////////////////////////////////
@@ -141,36 +143,36 @@
{
private:
// iterate over the given container until its exhausted or the embedded
- // (left) generator succeeds
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Iterator, typename Attribute>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator& it, Iterator& end, Attribute const&) const
+ // generator succeeds
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const&, mpl::false_) const
{
// Failing subject generators are just skipped. This allows to
// selectively generate items in the provided attribute.
- while (!traits::compare(it, end))
+ while (!f.is_at_end())
{
- if (subject.generate(sink, ctx, d, traits::deref(it)))
+ bool r = !f(subject);
+ if (r)
return true;
- if (Strict::value)
- return false;
- traits::next(it);
+ if (!f.is_at_end())
+ f.next();
}
return false;
}
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Iterator>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator&, Iterator&, unused_type) const
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const&, mpl::true_) const
+ {
+ return !f(subject);
+ }
+
+ // There is no way to distinguish a failed generator from a
+ // generator to be skipped. We assume the user takes responsibility
+ // for ending the loop if no attribute is specified.
+ template <typename F>
+ bool generate_subject(F f, unused_type, mpl::false_) const
{
- // There is no way to distinguish a failed generator from a
- // generator to be skipped. We assume the user takes responsibility
- // for ending the loop if no attribute is specified.
- return subject.generate(sink, ctx, d, unused);
+ return !f(subject);
}
public:
@@ -196,18 +198,33 @@
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
+ typedef detail::fail_function<
+ OutputIterator, Context, Delimiter
+ > fail_function;
+
typedef typename traits::container_iterator<
typename add_const<Attribute>::type
>::type iterator_type;
+ typedef
+ typename traits::make_indirect_iterator<iterator_type>::type
+ indirect_iterator_type;
+
+ typedef detail::pass_container<
+ fail_function, Attribute, indirect_iterator_type, mpl::false_>
+ pass_container;
+
iterator_type it = traits::begin(attr);
iterator_type end = traits::end(attr);
- typename LoopIter::type i = iter.start();
+
+ pass_container pass(fail_function(sink, ctx, d),
+ indirect_iterator_type(it), indirect_iterator_type(end));
// generate the minimal required amount of output
- for (/**/; !iter.got_min(i); ++i, traits::next(it))
+ typename LoopIter::type i = iter.start();
+ for (/**/; !pass.is_at_end() && !iter.got_min(i); ++i)
{
- if (!generate_subject(sink, ctx, d, it, end, attr))
+ if (!generate_subject(pass, attr, Strict()))
{
// if we fail before reaching the minimum iteration
// required, do not output anything and return false
@@ -215,11 +232,13 @@
}
}
+ if (pass.is_at_end() && !iter.got_min(i))
+ return false; // insufficient attribute elements
+
// generate some more up to the maximum specified
- for (/**/; detail::sink_is_good(sink) && !iter.got_max(i);
- ++i, traits::next(it))
+ for (/**/; !pass.is_at_end() && !iter.got_max(i); ++i)
{
- if (!generate_subject(sink, ctx, d, it, end, attr))
+ if (!generate_subject(pass, attr, Strict()))
break;
}
return detail::sink_is_good(sink);
@@ -346,7 +365,6 @@
return result_type(subject, fusion::at_c<0>(term.args));
}
};
-
}}}
namespace boost { namespace spirit { namespace traits
Modified: branches/release/boost/spirit/home/karma/directive/right_alignment.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/right_alignment.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/right_alignment.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -51,7 +51,7 @@
, terminal_ex<tag::right_align, fusion::vector1<T> > >
: mpl::true_ {};
- // enables *lazy* delimit(d)[g], where d provides a generator
+ // enables *lazy* right_align(d)[g], where d provides a generator
template <>
struct use_lazy_directive<karma::domain, tag::right_align, 1>
: mpl::true_ {};
@@ -63,8 +63,8 @@
, terminal_ex<tag::right_align, fusion::vector2<Width, Padding> > >
: spirit::traits::matches<karma::domain, Padding> {};
- // enables *lazy* delimit(w, d)[g], where d provides a generator and w is
- // a maximum width
+ // enables *lazy* right_align(w, d)[g], where d provides a generator and w
+ // is a maximum width
template <>
struct use_lazy_directive<karma::domain, tag::right_align, 2>
: mpl::true_ {};
@@ -74,7 +74,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::right_align;
+#endif
using spirit::right_align_type;
namespace detail
Modified: branches/release/boost/spirit/home/karma/directive/strict_relaxed.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/strict_relaxed.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/strict_relaxed.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -66,9 +66,11 @@
namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::strict;
- using boost::spirit::strict_type;
using boost::spirit::relaxed;
+#endif
+ using boost::spirit::strict_type;
using boost::spirit::relaxed_type;
}
}}
Modified: branches/release/boost/spirit/home/karma/directive/verbatim.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/directive/verbatim.hpp (original)
+++ branches/release/boost/spirit/home/karma/directive/verbatim.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -36,7 +36,9 @@
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::verbatim;
+#endif
using spirit::verbatim_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/domain.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/domain.hpp (original)
+++ branches/release/boost/spirit/home/karma/domain.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,7 +1,7 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// Distributed under the Boost Software 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_KARMA_DOMAIN_FEB_20_2007_0943AM)
@@ -38,6 +38,21 @@
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
+ using spirit::_pass_type;
+ using spirit::_val_type;
+ using spirit::_a_type;
+ using spirit::_b_type;
+ using spirit::_c_type;
+ using spirit::_d_type;
+ using spirit::_e_type;
+ using spirit::_f_type;
+ using spirit::_g_type;
+ using spirit::_h_type;
+ using spirit::_i_type;
+ using spirit::_j_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
using spirit::_pass;
using spirit::_val;
using spirit::_a;
@@ -50,6 +65,8 @@
using spirit::_h;
using spirit::_i;
using spirit::_j;
+
+#endif
}
}}}
Modified: branches/release/boost/spirit/home/karma/generate.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/generate.hpp (original)
+++ branches/release/boost/spirit/home/karma/generate.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -10,6 +10,8 @@
#pragma once
#endif
+#include <boost/spirit/home/support/context.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/karma/detail/generate.hpp>
namespace boost { namespace spirit { namespace karma
@@ -31,14 +33,30 @@
, Expr const& expr)
{
OutputIterator sink = sink_;
- return generate(sink, expr);
+ return karma::generate(sink, expr);
}
///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Expr, typename Attr>
+ namespace detail
+ {
+ template <typename T>
+ struct make_context
+ {
+ typedef context<fusion::cons<T const&>, locals<> > type;
+ };
+
+ template <>
+ struct make_context<unused_type>
+ {
+ typedef unused_type type;
+ };
+ }
+
+ template <typename OutputIterator, typename Properties, typename Expr
+ , typename Attr>
inline bool
generate(
- OutputIterator& sink_
+ detail::output_iterator<OutputIterator, Properties>& sink
, Expr const& expr
, Attr const& attr)
{
@@ -47,21 +65,14 @@
// then the expression (expr) is not a valid spirit karma expression.
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
- typedef traits::properties_of<
- typename result_of::compile<karma::domain, Expr>::type
- > properties;
-
- // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator
- , mpl::int_<properties::value> > sink(sink_);
- return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
+ typename detail::make_context<Attr>::type context(attr);
+ return compile<karma::domain>(expr).generate(sink, context, unused, attr);
}
- template <typename OutputIterator, typename Properties, typename Expr
- , typename Attr>
+ template <typename OutputIterator, typename Expr, typename Attr>
inline bool
generate(
- detail::output_iterator<OutputIterator, Properties>& sink
+ OutputIterator& sink_
, Expr const& expr
, Attr const& attr)
{
@@ -70,7 +81,14 @@
// then the expression (expr) is not a valid spirit karma expression.
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
- return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
+ typedef traits::properties_of<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+
+ // wrap user supplied iterator into our own output iterator
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value> > sink(sink_);
+ return karma::generate(sink, expr, attr);
}
template <typename OutputIterator, typename Expr, typename Attr>
@@ -81,7 +99,7 @@
, Attr const& attr)
{
OutputIterator sink = sink_;
- return generate(sink, expr, attr);
+ return karma::generate(sink, expr, attr);
}
///////////////////////////////////////////////////////////////////////////
@@ -108,7 +126,7 @@
delimit_flag::dont_predelimit)
{
OutputIterator sink = sink_;
- return generate_delimited(sink, expr, delimiter, pre_delimit);
+ return karma::generate_delimited(sink, expr, delimiter, pre_delimit);
}
///////////////////////////////////////////////////////////////////////////
@@ -137,8 +155,10 @@
{
return false;
}
+
+ typename detail::make_context<Attribute>::type context(attr);
return compile<karma::domain>(expr).
- generate(sink, unused, delimiter_, attr);
+ generate(sink, context, delimiter_, attr);
}
template <typename OutputIterator, typename Expr, typename Delimiter
@@ -176,7 +196,7 @@
, Attribute const& attr)
{
OutputIterator sink = sink_;
- return generate_delimited(sink, expr, delimiter, pre_delimit, attr);
+ return karma::generate_delimited(sink, expr, delimiter, pre_delimit, attr);
}
///////////////////////////////////////////////////////////////////////////
@@ -206,7 +226,6 @@
return karma::generate_delimited(sink, expr, delimiter
, delimit_flag::dont_predelimit, attr);
}
-
}}}
#endif
Modified: branches/release/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp (original)
+++ branches/release/boost/spirit/home/karma/nonterminal/detail/parameterized.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,6 +14,7 @@
#include <boost/ref.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/generator.hpp>
namespace boost { namespace spirit { namespace karma
@@ -60,4 +61,16 @@
};
}}}
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Params, typename Attribute
+ , typename Context, typename Iterator>
+ struct handles_container<karma::parameterized_nonterminal<Subject, Params>
+ , Attribute, Context, Iterator>
+ : handles_container<typename remove_const<Subject>::type
+ , Attribute, Context, Iterator>
+ {};
+}}}
+
#endif
Modified: branches/release/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/nonterminal/rule.hpp (original)
+++ branches/release/boost/spirit/home/karma/nonterminal/rule.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,7 +1,7 @@
// Copyright (c) 2001-2011 Joel de Guzman
// Copyright (c) 2001-2011 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// Distributed under the Boost Software 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_KARMA_RULE_MAR_05_2007_0455PM)
@@ -48,6 +48,21 @@
{
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
+ using spirit::_pass_type;
+ using spirit::_val_type;
+ using spirit::_a_type;
+ using spirit::_b_type;
+ using spirit::_c_type;
+ using spirit::_d_type;
+ using spirit::_e_type;
+ using spirit::_f_type;
+ using spirit::_g_type;
+ using spirit::_h_type;
+ using spirit::_i_type;
+ using spirit::_j_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
using spirit::_pass;
using spirit::_val;
using spirit::_a;
@@ -61,6 +76,8 @@
using spirit::_i;
using spirit::_j;
+#endif
+
using spirit::info;
using spirit::locals;
@@ -86,7 +103,7 @@
typedef mpl::vector<T1, T2, T3, T4> template_params;
// the output iterator is always wrapped by karma
- typedef detail::output_iterator<OutputIterator, properties>
+ typedef detail::output_iterator<OutputIterator, properties>
output_iterator;
// locals_type is a sequence of types to be used as local variables
@@ -115,7 +132,7 @@
spirit::detail::attr_from_sig<sig_type>::type
attr_type;
typedef typename add_reference<
- typename add_const<attr_type>::type>::type
+ typename add_const<attr_type>::type>::type
attr_reference_type;
// parameter_types is a sequence of types passed as parameters to the rule
@@ -176,7 +193,7 @@
{
// The following assertion fires when you try to initialize a rule
// from an uninitialized one. Did you mean to refer to the right
- // hand side rule instead of assigning from it? In this case you
+ // hand side rule instead of assigning from it? In this case you
// should write lhs = rhs.alias();
BOOST_ASSERT(rhs.f && "Did you mean rhs.alias() instead of rhs?");
@@ -232,7 +249,7 @@
}
#else
// both friend functions have to be defined out of class as VC7.1
- // will complain otherwise
+ // will complain otherwise
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
@@ -257,14 +274,14 @@
{
if (f)
{
- // Create an attribute if none is supplied.
- typedef traits::make_attribute<attr_type, Attribute>
+ // Create an attribute if none is supplied.
+ typedef traits::make_attribute<attr_type, Attribute>
make_attribute;
typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, domain>
+ typename make_attribute::type, attr_type, domain>
transform;
- typename transform::type attr_ =
+ typename transform::type attr_ =
traits::pre_transform<domain, attr_type>(
make_attribute::call(attr));
@@ -273,9 +290,9 @@
// attributes, without passing values for them.
context_type context(attr_);
- // If you are seeing a compilation error here stating that the
+ // If you are seeing a compilation error here stating that the
// third parameter can't be converted to a karma::reference
- // then you are probably trying to use a rule or a grammar with
+ // then you are probably trying to use a rule or a grammar with
// an incompatible delimiter type.
if (f(sink, context, delim))
{
@@ -297,14 +314,14 @@
{
if (f)
{
- // Create an attribute if none is supplied.
- typedef traits::make_attribute<attr_type, Attribute>
+ // Create an attribute if none is supplied.
+ typedef traits::make_attribute<attr_type, Attribute>
make_attribute;
typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, domain>
+ typename make_attribute::type, attr_type, domain>
transform;
- typename transform::type attr_ =
+ typename transform::type attr_ =
traits::pre_transform<domain, attr_type>(
make_attribute::call(attr));
@@ -313,9 +330,9 @@
// attributes, passing values of incompatible types for them.
context_type context(attr_, params, caller_context);
- // If you are seeing a compilation error here stating that the
+ // If you are seeing a compilation error here stating that the
// third parameter can't be converted to a karma::reference
- // then you are probably trying to use a rule or a grammar with
+ // then you are probably trying to use a rule or a grammar with
// an incompatible delimiter type.
if (f(sink, context, delim))
{
@@ -366,7 +383,7 @@
// the expression (expr) is not a valid spirit karma expression.
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
- typedef typename
+ typedef typename
rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
encoding_modifier_type;
@@ -405,7 +422,7 @@
struct handles_container<
karma::rule<IteratorA, T1, T2, T3, T4>, Attribute, Context
, IteratorB>
- : detail::nonterminal_handles_container<
+ : detail::nonterminal_handles_container<
typename attribute_of<
karma::rule<IteratorA, T1, T2, T3, T4>
, Context, IteratorB
Modified: branches/release/boost/spirit/home/karma/numeric/bool.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/bool.hpp (original)
+++ branches/release/boost/spirit/home/karma/numeric/bool.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -40,7 +40,7 @@
struct bool_policies;
///////////////////////////////////////////////////////////////////////
- // This is the class that the user can instantiate directly in
+ // This is the class that the user can instantiate directly in
// order to create a customized bool generator
template <typename T = bool, typename Policies = bool_policies<T> >
struct bool_generator
@@ -79,7 +79,7 @@
> : mpl::true_ {};
template <> // enables *lazy* bool_(...)
- struct use_lazy_terminal<karma::domain, tag::bool_, 1>
+ struct use_lazy_terminal<karma::domain, tag::bool_, 1>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
@@ -99,7 +99,7 @@
// enables *lazy* custom bool_generator
template <typename Policies, typename T>
struct use_lazy_terminal<karma::domain
- , tag::stateful_tag<Policies, tag::bool_, T>, 1>
+ , tag::stateful_tag<Policies, tag::bool_, T>, 1>
: mpl::true_ {};
// enables lit(bool)
@@ -113,19 +113,21 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::bool_;
- using spirit::bool__type;
using spirit::true_;
- using spirit::true__type;
using spirit::false_;
- using spirit::false__type;
-
using spirit::lit; // lit(true) is equivalent to true
+#endif
+
+ using spirit::bool_type;
+ using spirit::true_type;
+ using spirit::false_type;
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// This specialization is used for bool generators not having a direct
- // initializer: bool_. These generators must be used in conjunction with
+ // initializer: bool_. These generators must be used in conjunction with
// an Attribute.
///////////////////////////////////////////////////////////////////////////
template <typename T, typename CharEncoding, typename Tag, typename Policies>
@@ -165,8 +167,8 @@
static bool
generate(OutputIterator&, Context&, Delimiter const&, unused_type)
{
- // It is not possible (doesn't make sense) to use boolean generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use boolean generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false, bool_not_usable_without_attribute, ());
@@ -213,7 +215,7 @@
, Delimiter const& d, Attribute const& attr) const
{
typedef typename attribute<Context>::type attribute_type;
- if (!traits::has_optional_value(attr) ||
+ if (!traits::has_optional_value(attr) ||
bool(n_) != bool(traits::extract_from<attribute_type>(attr, context)))
{
return false;
@@ -222,7 +224,7 @@
call(sink, n_, p_) && delimit_out(sink, d);
}
- // A bool_() without any associated attribute just emits its
+ // A bool_() without any associated attribute just emits its
// immediate literal
template <typename OutputIterator, typename Context, typename Delimiter>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
@@ -251,9 +253,9 @@
, typename Policies = bool_policies<T> >
struct make_bool
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef any_bool_generator<
@@ -276,9 +278,9 @@
template <typename Modifiers, bool b>
struct make_bool_literal
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_bool_generator<
@@ -298,21 +300,22 @@
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
- struct make_primitive<tag::bool_, Modifiers>
+ struct make_primitive<tag::bool_, Modifiers>
: detail::make_bool<Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::true_, Modifiers>
+ struct make_primitive<tag::true_, Modifiers>
: detail::make_bool_literal<Modifiers, true> {};
template <typename Modifiers>
- struct make_primitive<tag::false_, Modifiers>
+ struct make_primitive<tag::false_, Modifiers>
: detail::make_bool_literal<Modifiers, false> {};
template <typename T, typename Policies, typename Modifiers>
struct make_primitive<
tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
- : detail::make_bool<Modifiers, T, Policies> {};
+ : detail::make_bool<Modifiers
+ , typename remove_const<T>::type, Policies> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -321,9 +324,9 @@
, typename Policies = bool_policies<T> >
struct make_bool_direct
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_bool_generator<
@@ -356,7 +359,8 @@
terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
, fusion::vector1<A0> >
, Modifiers>
- : detail::make_bool_direct<Modifiers, T, Policies> {};
+ : detail::make_bool_direct<Modifiers
+ , typename remove_const<T>::type, Policies> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -386,7 +390,7 @@
}
template <typename Modifiers>
- struct make_primitive<bool, Modifiers>
+ struct make_primitive<bool, Modifiers>
: detail::basic_bool_literal<Modifiers> {};
template <typename Modifiers, typename A0>
@@ -394,7 +398,7 @@
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_bool<A0> >::type>
- : detail::basic_bool_literal<Modifiers>
+ : detail::basic_bool_literal<Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
Modified: branches/release/boost/spirit/home/karma/numeric/int.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/int.hpp (original)
+++ branches/release/boost/spirit/home/karma/numeric/int.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -46,11 +46,11 @@
namespace karma
{
///////////////////////////////////////////////////////////////////////
- // This one is the class that the user can instantiate directly in
+ // This one is the class that the user can instantiate directly in
// order to create a customized int generator
template <typename T = int, unsigned Radix = 10, bool force_sign = false>
struct int_generator
- : spirit::terminal<tag::int_generator<T, Radix, force_sign> >
+ : spirit::terminal<tag::int_generator<T, Radix, force_sign> >
{};
}
@@ -119,20 +119,20 @@
///////////////////////////////////////////////////////////////////////////
template <> // enables *lazy* short_(...)
- struct use_lazy_terminal<karma::domain, tag::short_, 1>
+ struct use_lazy_terminal<karma::domain, tag::short_, 1>
: mpl::true_ {};
template <> // enables *lazy* int_(...)
- struct use_lazy_terminal<karma::domain, tag::int_, 1>
+ struct use_lazy_terminal<karma::domain, tag::int_, 1>
: mpl::true_ {};
template <> // enables *lazy* long_(...)
- struct use_lazy_terminal<karma::domain, tag::long_, 1>
+ struct use_lazy_terminal<karma::domain, tag::long_, 1>
: mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <> // enables *lazy* long_long(...)
- struct use_lazy_terminal<karma::domain, tag::long_long, 1>
+ struct use_lazy_terminal<karma::domain, tag::long_long, 1>
: mpl::true_ {};
#endif
@@ -163,23 +163,28 @@
, terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_int<A0> >::type>
: mpl::true_ {};
-}}
+}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::short_;
- using spirit::short__type;
using spirit::int_;
- using spirit::int__type;
using spirit::long_;
- using spirit::long__type;
#ifdef BOOST_HAS_LONG_LONG
using spirit::long_long;
+#endif
+ using spirit::lit; // lit(1) is equivalent to 1
+#endif
+
+ using spirit::short_type;
+ using spirit::int_type;
+ using spirit::long_type;
+#ifdef BOOST_HAS_LONG_LONG
using spirit::long_long_type;
#endif
- using spirit::lit; // lit(1) is equivalent to 1
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
@@ -239,8 +244,8 @@
static bool
generate(OutputIterator&, Context&, Delimiter const&, unused_type)
{
- // It is not possible (doesn't make sense) to use numeric generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use numeric generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false, int_not_usable_without_attribute, ());
@@ -301,7 +306,7 @@
, Delimiter const& d, Attribute const& attr) const
{
typedef typename attribute<Context>::type attribute_type;
- if (!traits::has_optional_value(attr) ||
+ if (!traits::has_optional_value(attr) ||
n_ != traits::extract_from<attribute_type>(attr, context))
{
return false;
@@ -309,7 +314,7 @@
return insert_int(sink, n_) && delimit_out(sink, d);
}
- // A int_(1) without any associated attribute just emits its
+ // A int_(1) without any associated attribute just emits its
// immediate literal
template <typename OutputIterator, typename Context, typename Delimiter>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
@@ -336,9 +341,9 @@
, bool force_sign = false>
struct make_int
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef any_int_generator<
@@ -359,26 +364,27 @@
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
- struct make_primitive<tag::short_, Modifiers>
+ struct make_primitive<tag::short_, Modifiers>
: detail::make_int<short, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::int_, Modifiers>
+ struct make_primitive<tag::int_, Modifiers>
: detail::make_int<int, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::long_, Modifiers>
+ struct make_primitive<tag::long_, Modifiers>
: detail::make_int<long, Modifiers> {};
#ifdef BOOST_HAS_LONG_LONG
template <typename Modifiers>
- struct make_primitive<tag::long_long, Modifiers>
+ struct make_primitive<tag::long_long, Modifiers>
: detail::make_int<boost::long_long_type, Modifiers> {};
#endif
template <typename T, unsigned Radix, bool force_sign, typename Modifiers>
struct make_primitive<tag::int_generator<T, Radix, force_sign>, Modifiers>
- : detail::make_int<T, Modifiers, Radix, force_sign> {};
+ : detail::make_int<typename remove_const<T>::type
+ , Modifiers, Radix, force_sign> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -387,9 +393,9 @@
, bool force_sign = false>
struct make_int_direct
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_int_generator<
@@ -436,7 +442,8 @@
struct make_primitive<
terminal_ex<tag::int_generator<T, Radix, force_sign>
, fusion::vector1<A0> >, Modifiers>
- : detail::make_int_direct<T, Modifiers, Radix, force_sign> {};
+ : detail::make_int_direct<typename remove_const<T>::type
+ , Modifiers, Radix, force_sign> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -466,20 +473,20 @@
}
template <typename Modifiers>
- struct make_primitive<short, Modifiers>
+ struct make_primitive<short, Modifiers>
: detail::basic_int_literal<short, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<int, Modifiers>
+ struct make_primitive<int, Modifiers>
: detail::basic_int_literal<int, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<long, Modifiers>
+ struct make_primitive<long, Modifiers>
: detail::basic_int_literal<long, Modifiers> {};
#ifdef BOOST_HAS_LONG_LONG
template <typename Modifiers>
- struct make_primitive<boost::long_long_type, Modifiers>
+ struct make_primitive<boost::long_long_type, Modifiers>
: detail::basic_int_literal<boost::long_long_type, Modifiers> {};
#endif
@@ -489,7 +496,6 @@
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_int<A0> >::type>
- : detail::basic_int_literal<A0, Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
@@ -497,7 +503,7 @@
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_int_generator<
- A0
+ typename remove_const<A0>::type
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
Modified: branches/release/boost/spirit/home/karma/numeric/real.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/real.hpp (original)
+++ branches/release/boost/spirit/home/karma/numeric/real.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -35,7 +35,7 @@
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
-namespace boost { namespace spirit
+namespace boost { namespace spirit
{
namespace karma
{
@@ -45,11 +45,11 @@
struct real_policies;
///////////////////////////////////////////////////////////////////////
- // This is the class that the user can instantiate directly in
+ // This is the class that the user can instantiate directly in
// order to create a customized real generator
template <typename T = double, typename Policies = real_policies<T> >
struct real_generator
- : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
+ : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
{
typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
@@ -105,15 +105,15 @@
// lazy float_(...), double_(...), long_double(...)
template <>
- struct use_lazy_terminal<karma::domain, tag::float_, 1>
+ struct use_lazy_terminal<karma::domain, tag::float_, 1>
: mpl::true_ {};
template <>
- struct use_lazy_terminal<karma::domain, tag::double_, 1>
+ struct use_lazy_terminal<karma::domain, tag::double_, 1>
: mpl::true_ {};
template <>
- struct use_lazy_terminal<karma::domain, tag::long_double, 1>
+ struct use_lazy_terminal<karma::domain, tag::long_double, 1>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
@@ -148,11 +148,14 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::float_;
- using spirit::float__type;
using spirit::double_;
- using spirit::double__type;
using spirit::long_double;
+#endif
+
+ using spirit::float_type;
+ using spirit::double_type;
using spirit::long_double_type;
///////////////////////////////////////////////////////////////////////////
@@ -194,10 +197,10 @@
// been initialized from a direct literal
template <typename OutputIterator, typename Context, typename Delimiter>
static bool generate(OutputIterator&, Context&, Delimiter const&
- , unused_type)
+ , unused_type)
{
- // It is not possible (doesn't make sense) to use numeric generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use numeric generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false, real_not_usable_without_attribute, ()); return false;
@@ -243,7 +246,7 @@
, Delimiter const& d, Attribute const& attr) const
{
typedef typename attribute<Context>::type attribute_type;
- if (!traits::has_optional_value(attr) ||
+ if (!traits::has_optional_value(attr) ||
n_ != traits::extract_from<attribute_type>(attr, context))
{
return false;
@@ -254,7 +257,7 @@
karma::delimit_out(sink, d); // always do post-delimiting
}
- // A double_(1.0) without any associated attribute just emits its
+ // A double_(1.0) without any associated attribute just emits its
// immediate literal
template <typename OutputIterator, typename Context, typename Delimiter>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
@@ -284,9 +287,9 @@
, typename Policies = real_policies<T> >
struct make_real
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef any_real_generator<
@@ -307,22 +310,23 @@
}
template <typename Modifiers>
- struct make_primitive<tag::float_, Modifiers>
+ struct make_primitive<tag::float_, Modifiers>
: detail::make_real<float, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::double_, Modifiers>
+ struct make_primitive<tag::double_, Modifiers>
: detail::make_real<double, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::long_double, Modifiers>
+ struct make_primitive<tag::long_double, Modifiers>
: detail::make_real<long double, Modifiers> {};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Policies, typename Modifiers>
struct make_primitive<
- tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
- : detail::make_real<T, Modifiers, Policies> {};
+ tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
+ : detail::make_real<typename remove_const<T>::type
+ , Modifiers, Policies> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -331,9 +335,9 @@
, typename Policies = real_policies<T> >
struct make_real_direct
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_real_generator<
@@ -376,7 +380,8 @@
terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
, fusion::vector1<A0> >
, Modifiers>
- : detail::make_real_direct<T, Modifiers, Policies> {};
+ : detail::make_real_direct<typename remove_const<T>::type
+ , Modifiers, Policies> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -406,15 +411,15 @@
}
template <typename Modifiers>
- struct make_primitive<float, Modifiers>
+ struct make_primitive<float, Modifiers>
: detail::basic_real_literal<float, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<double, Modifiers>
+ struct make_primitive<double, Modifiers>
: detail::basic_real_literal<double, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<long double, Modifiers>
+ struct make_primitive<long double, Modifiers>
: detail::basic_real_literal<long double, Modifiers> {};
// lit(double)
@@ -423,7 +428,6 @@
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_real<A0> >::type>
- : detail::basic_real_literal<A0, Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
@@ -431,7 +435,7 @@
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_real_generator<
- A0, real_policies<A0>
+ typename remove_const<A0>::type, real_policies<A0>
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
Modified: branches/release/boost/spirit/home/karma/numeric/real_policies.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/real_policies.hpp (original)
+++ branches/release/boost/spirit/home/karma/numeric/real_policies.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -12,6 +12,7 @@
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/type_traits/remove_const.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/karma/generator.hpp>
@@ -257,7 +258,8 @@
// generate(sink, right_align(precision, '0')[ulong], n);
// but it's spelled out to avoid inter-modular dependencies.
- T digits = (detail::is_zero(n) ? 0 : floor(log10(n))) + 1;
+ typename remove_const<T>::type digits =
+ (detail::is_zero(n) ? 0 : floor(log10(n))) + 1;
bool r = true;
for (/**/; r && digits < precision_; digits = digits + 1)
r = char_inserter<>::call(sink, '0');
Modified: branches/release/boost/spirit/home/karma/numeric/uint.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/uint.hpp (original)
+++ branches/release/boost/spirit/home/karma/numeric/uint.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -34,7 +34,7 @@
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
-namespace boost { namespace spirit
+namespace boost { namespace spirit
{
namespace tag
{
@@ -45,11 +45,11 @@
namespace karma
{
///////////////////////////////////////////////////////////////////////
- // This one is the class that the user can instantiate directly in
+ // This one is the class that the user can instantiate directly in
// order to create a customized int generator
template <typename T = unsigned int, unsigned Radix = 10>
struct uint_generator
- : spirit::terminal<tag::uint_generator<T, Radix> >
+ : spirit::terminal<tag::uint_generator<T, Radix> >
{};
}
@@ -103,7 +103,7 @@
#ifdef BOOST_HAS_LONG_LONG
template <> // enables lit(0ULL)
- struct use_terminal<karma::domain, boost::ulong_long_type>
+ struct use_terminal<karma::domain, boost::ulong_long_type>
: mpl::true_ {};
#endif
@@ -147,32 +147,32 @@
///////////////////////////////////////////////////////////////////////////
template <> // enables *lazy* ushort_(...)
- struct use_lazy_terminal<karma::domain, tag::ushort_, 1>
+ struct use_lazy_terminal<karma::domain, tag::ushort_, 1>
: mpl::true_ {};
template <> // enables *lazy* uint_(...)
- struct use_lazy_terminal<karma::domain, tag::uint_, 1>
+ struct use_lazy_terminal<karma::domain, tag::uint_, 1>
: mpl::true_ {};
template <> // enables *lazy* ulong_(...)
- struct use_lazy_terminal<karma::domain, tag::ulong_, 1>
+ struct use_lazy_terminal<karma::domain, tag::ulong_, 1>
: mpl::true_ {};
template <> // enables *lazy* bin(...)
- struct use_lazy_terminal<karma::domain, tag::bin, 1>
+ struct use_lazy_terminal<karma::domain, tag::bin, 1>
: mpl::true_ {};
template <> // enables *lazy* oct(...)
- struct use_lazy_terminal<karma::domain, tag::oct, 1>
+ struct use_lazy_terminal<karma::domain, tag::oct, 1>
: mpl::true_ {};
template <> // enables *lazy* hex(...)
- struct use_lazy_terminal<karma::domain, tag::hex, 1>
+ struct use_lazy_terminal<karma::domain, tag::hex, 1>
: mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <> // enables *lazy* ulong_long(...)
- struct use_lazy_terminal<karma::domain, tag::ulong_long, 1>
+ struct use_lazy_terminal<karma::domain, tag::ulong_long, 1>
: mpl::true_ {};
#endif
@@ -202,33 +202,39 @@
, terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_uint<A0> >::type>
: mpl::true_ {};
-}}
+}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::ushort_;
- using spirit::ushort__type;
using spirit::uint_;
- using spirit::uint__type;
using spirit::ulong_;
- using spirit::ulong__type;
#ifdef BOOST_HAS_LONG_LONG
using spirit::ulong_long;
- using spirit::ulong_long_type;
#endif
using spirit::bin;
- using spirit::bin_type;
using spirit::oct;
- using spirit::oct_type;
using spirit::hex;
- using spirit::hex_type;
using spirit::lit; // lit(1U) is equivalent to 1U
+#endif
+
+ using spirit::ushort_type;
+ using spirit::uint_type;
+ using spirit::ulong_type;
+#ifdef BOOST_HAS_LONG_LONG
+ using spirit::ulong_long_type;
+#endif
+ using spirit::bin_type;
+ using spirit::oct_type;
+ using spirit::hex_type;
+
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
- // This specialization is used for unsigned int generators not having a
+ // This specialization is used for unsigned int generators not having a
// direct initializer: uint_, ulong_ etc. These generators must be used in
// conjunction with an Attribute.
///////////////////////////////////////////////////////////////////////////
@@ -247,7 +253,7 @@
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
- BOOST_SPIRIT_ASSERT_MSG(
+ BOOST_SPIRIT_ASSERT_MSG(
// the following is a workaround for STLPort, where the simpler
// `!std::numeric_limits<T>::is_signed` wouldn't compile
mpl::not_<mpl::bool_<std::numeric_limits<T>::is_signed> >::value,
@@ -274,8 +280,8 @@
static bool
generate(OutputIterator&, Context&, Delimiter const&, unused_type)
{
- // It is not possible (doesn't make sense) to use numeric generators
- // without providing any attribute, as the generator doesn't 'know'
+ // It is not possible (doesn't make sense) to use numeric generators
+ // without providing any attribute, as the generator doesn't 'know'
// what to output. The following assertion fires if this situation
// is detected in your code.
BOOST_SPIRIT_ASSERT_MSG(false, uint_not_usable_without_attribute, ());
@@ -328,7 +334,7 @@
, Delimiter const& d, Attribute const& attr) const
{
typedef typename attribute<Context>::type attribute_type;
- if (!traits::has_optional_value(attr) ||
+ if (!traits::has_optional_value(attr) ||
n_ != traits::extract_from<attribute_type>(attr, context))
{
return false;
@@ -337,7 +343,7 @@
delimit_out(sink, d); // always do post-delimiting
}
- // A uint(1U) without any associated attribute just emits its
+ // A uint(1U) without any associated attribute just emits its
// immediate literal
template <typename OutputIterator, typename Context, typename Delimiter>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
@@ -364,9 +370,9 @@
template <typename T, typename Modifiers, unsigned Radix = 10>
struct make_uint
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef any_uint_generator<
@@ -386,38 +392,38 @@
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
- struct make_primitive<tag::ushort_, Modifiers>
+ struct make_primitive<tag::ushort_, Modifiers>
: detail::make_uint<unsigned short, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::uint_, Modifiers>
+ struct make_primitive<tag::uint_, Modifiers>
: detail::make_uint<unsigned int, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::ulong_, Modifiers>
+ struct make_primitive<tag::ulong_, Modifiers>
: detail::make_uint<unsigned long, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<tag::bin, Modifiers>
+ struct make_primitive<tag::bin, Modifiers>
: detail::make_uint<unsigned, Modifiers, 2> {};
template <typename Modifiers>
- struct make_primitive<tag::oct, Modifiers>
+ struct make_primitive<tag::oct, Modifiers>
: detail::make_uint<unsigned, Modifiers, 8> {};
template <typename Modifiers>
- struct make_primitive<tag::hex, Modifiers>
+ struct make_primitive<tag::hex, Modifiers>
: detail::make_uint<unsigned, Modifiers, 16> {};
#ifdef BOOST_HAS_LONG_LONG
template <typename Modifiers>
- struct make_primitive<tag::ulong_long, Modifiers>
+ struct make_primitive<tag::ulong_long, Modifiers>
: detail::make_uint<boost::ulong_long_type, Modifiers> {};
#endif
template <typename T, unsigned Radix, typename Modifiers>
struct make_primitive<tag::uint_generator<T, Radix>, Modifiers>
- : detail::make_uint<T, Modifiers, Radix> {};
+ : detail::make_uint<typename remove_const<T>::type, Modifiers, Radix> {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -425,9 +431,9 @@
template <typename T, typename Modifiers, unsigned Radix = 10>
struct make_uint_direct
{
- static bool const lower =
+ static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
- static bool const upper =
+ static bool const upper =
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_uint_generator<
@@ -487,7 +493,8 @@
struct make_primitive<
terminal_ex<tag::uint_generator<T, Radix>, fusion::vector1<A0> >
, Modifiers>
- : detail::make_uint_direct<T, Modifiers, Radix> {};
+ : detail::make_uint_direct<typename remove_const<T>::type, Modifiers, Radix>
+ {};
///////////////////////////////////////////////////////////////////////////
namespace detail
@@ -518,21 +525,21 @@
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <typename Modifiers>
- struct make_primitive<unsigned short, Modifiers>
+ struct make_primitive<unsigned short, Modifiers>
: detail::basic_uint_literal<unsigned short, Modifiers> {};
#endif
template <typename Modifiers>
- struct make_primitive<unsigned int, Modifiers>
+ struct make_primitive<unsigned int, Modifiers>
: detail::basic_uint_literal<unsigned int, Modifiers> {};
template <typename Modifiers>
- struct make_primitive<unsigned long, Modifiers>
+ struct make_primitive<unsigned long, Modifiers>
: detail::basic_uint_literal<unsigned long, Modifiers> {};
#ifdef BOOST_HAS_LONG_LONG
template <typename Modifiers>
- struct make_primitive<boost::ulong_long_type, Modifiers>
+ struct make_primitive<boost::ulong_long_type, Modifiers>
: detail::basic_uint_literal<boost::ulong_long_type, Modifiers> {};
#endif
@@ -542,7 +549,6 @@
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers
, typename enable_if<traits::is_uint<A0> >::type>
- : detail::basic_uint_literal<A0, Modifiers>
{
static bool const lower =
has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
@@ -550,7 +556,7 @@
has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
typedef literal_uint_generator<
- A0
+ typename remove_const<A0>::type
, typename spirit::detail::get_encoding_with_case<
Modifiers, unused_type, lower || upper>::type
, typename detail::get_casetag<Modifiers, lower || upper>::type
Modified: branches/release/boost/spirit/home/karma/operator/kleene.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/operator/kleene.hpp (original)
+++ branches/release/boost/spirit/home/karma/operator/kleene.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -15,7 +15,10 @@
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/karma/detail/get_stricttag.hpp>
+#include <boost/spirit/home/karma/detail/pass_container.hpp>
+#include <boost/spirit/home/karma/detail/fail_function.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/container.hpp>
@@ -41,29 +44,39 @@
struct base_kleene : unary_generator<Derived>
{
private:
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Attribute const& attr) const
+ // Ignore return value in relaxed mode (failing subject generators
+ // are just skipped). This allows to selectively generate items in
+ // the provided attribute.
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const&, mpl::false_) const
{
- // Ignore return value, failing subject generators are just
- // skipped. This allows to selectively generate items in the
- // provided attribute.
- bool r = subject.generate(sink, ctx, d, attr);
- return !Strict::value || r;
+ bool r = !f(subject);
+ if (!r && !f.is_at_end())
+ f.next();
+ return true;
}
- template <typename OutputIterator, typename Context, typename Delimiter>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, unused_type) const
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const&, mpl::true_) const
{
- // There is no way to distinguish a failed generator from a
- // generator to be skipped. We assume the user takes responsibility
- // for ending the loop if no attribute is specified.
- return subject.generate(sink, ctx, d, unused);
+ return !f(subject);
}
+ // There is no way to distinguish a failed generator from a
+ // generator to be skipped. We assume the user takes responsibility
+ // for ending the loop if no attribute is specified.
+ template <typename F>
+ bool generate_subject(F f, unused_type, mpl::false_) const
+ {
+ return !f(subject);
+ }
+
+// template <typename F>
+// bool generate_subject(F f, unused_type, mpl::true_) const
+// {
+// return !f(subject);
+// }
+
public:
typedef Subject subject_type;
typedef typename subject_type::properties properties;
@@ -87,18 +100,30 @@
bool generate(OutputIterator& sink, Context& ctx
, Delimiter const& d, Attribute const& attr) const
{
+ typedef detail::fail_function<
+ OutputIterator, Context, Delimiter> fail_function;
+
typedef typename traits::container_iterator<
typename add_const<Attribute>::type
>::type iterator_type;
+ typedef
+ typename traits::make_indirect_iterator<iterator_type>::type
+ indirect_iterator_type;
+ typedef detail::pass_container<
+ fail_function, Attribute, indirect_iterator_type, mpl::false_>
+ pass_container;
+
iterator_type it = traits::begin(attr);
iterator_type end = traits::end(attr);
+ pass_container pass(fail_function(sink, ctx, d),
+ indirect_iterator_type(it), indirect_iterator_type(end));
+
// kleene fails only if the underlying output fails
- for (/**/; detail::sink_is_good(sink) && !traits::compare(it, end);
- traits::next(it))
+ while (!pass.is_at_end())
{
- if (!generate_subject(sink, ctx, d, traits::deref(it)))
+ if (!generate_subject(pass, attr, Strict()))
break;
}
return detail::sink_is_good(sink);
@@ -170,13 +195,13 @@
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::kleene<Subject>, Attribute
- , Context, Iterator>
+ , Context, Iterator>
: mpl::true_ {};
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::strict_kleene<Subject>, Attribute
- , Context, Iterator>
+ , Context, Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/karma/operator/list.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/operator/list.hpp (original)
+++ branches/release/boost/spirit/home/karma/operator/list.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -15,7 +15,10 @@
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/karma/detail/get_stricttag.hpp>
+#include <boost/spirit/home/karma/detail/pass_container.hpp>
+#include <boost/spirit/home/karma/detail/fail_function.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/container.hpp>
@@ -41,39 +44,35 @@
private:
// iterate over the given container until its exhausted or the embedded
// (left) generator succeeds
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Iterator, typename Attribute>
- bool generate_left(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator& it, Iterator& end, Attribute const&) const
+ template <typename F, typename Attribute>
+ bool generate_left(F f, Attribute const&, mpl::false_) const
{
- if (Strict::value) {
- if (!traits::compare(it, end))
- return left.generate(sink, ctx, d, traits::deref(it));
- }
- else {
- // Failing subject generators are just skipped. This allows to
- // selectively generate items in the provided attribute.
- while (!traits::compare(it, end))
- {
- if (left.generate(sink, ctx, d, traits::deref(it)))
- return true;
- traits::next(it);
- }
+ // Failing subject generators are just skipped. This allows to
+ // selectively generate items in the provided attribute.
+ while (!f.is_at_end())
+ {
+ bool r = !f(left);
+ if (r)
+ return true;
+ if (!f.is_at_end())
+ f.next();
}
return false;
}
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Iterator>
- bool generate_left(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator&, Iterator&, unused_type) const
+ template <typename F, typename Attribute>
+ bool generate_left(F f, Attribute const&, mpl::true_) const
+ {
+ return !f(left);
+ }
+
+ // There is no way to distinguish a failed generator from a
+ // generator to be skipped. We assume the user takes responsibility
+ // for ending the loop if no attribute is specified.
+ template <typename F>
+ bool generate_left(F f, unused_type, mpl::false_) const
{
- // There is no way to distinguish a failed generator from a
- // generator to be skipped. We assume the user takes responsibility
- // for ending the loop if no attribute is specified.
- return left.generate(sink, ctx, d, unused);
+ return !f(left);
}
public:
@@ -106,16 +105,30 @@
bool generate(OutputIterator& sink, Context& ctx
, Delimiter const& d, Attribute const& attr) const
{
+ typedef detail::fail_function<
+ OutputIterator, Context, Delimiter
+ > fail_function;
+
typedef typename traits::container_iterator<
typename add_const<Attribute>::type
>::type iterator_type;
+ typedef
+ typename traits::make_indirect_iterator<iterator_type>::type
+ indirect_iterator_type;
+ typedef detail::pass_container<
+ fail_function, Attribute, indirect_iterator_type, mpl::false_>
+ pass_container;
+
iterator_type it = traits::begin(attr);
iterator_type end = traits::end(attr);
- if (generate_left(sink, ctx, d, it, end, attr))
+ pass_container pass(fail_function(sink, ctx, d),
+ indirect_iterator_type(it), indirect_iterator_type(end));
+
+ if (generate_left(pass, attr, Strict()))
{
- for (traits::next(it); !traits::compare(it, end); traits::next(it))
+ while (!pass.is_at_end())
{
// wrap the given output iterator as generate_left might fail
detail::enable_buffering<OutputIterator> buffering(sink);
@@ -125,12 +138,12 @@
if (!right.generate(sink, ctx, d, unused))
return false; // shouldn't happen
- if (!generate_left(sink, ctx, d, it, end, attr))
+ if (!generate_left(pass, attr, Strict()))
break; // return true as one item succeeded
}
buffering.buffer_copy();
}
- return true;
+ return detail::sink_is_good(sink);
}
return false;
}
@@ -203,13 +216,13 @@
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::list<Left, Right>, Attribute
- , Context, Iterator>
+ , Context, Iterator>
: mpl::true_ {};
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::strict_list<Left, Right>, Attribute
- , Context, Iterator>
+ , Context, Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/karma/operator/optional.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/operator/optional.hpp (original)
+++ branches/release/boost/spirit/home/karma/operator/optional.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -98,8 +98,8 @@
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::optional<Subject>, Attribute, Context
- , Iterator>
- : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+ , Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/karma/operator/plus.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/operator/plus.hpp (original)
+++ branches/release/boost/spirit/home/karma/operator/plus.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,8 +14,11 @@
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/karma/detail/output_iterator.hpp>
#include <boost/spirit/home/karma/detail/get_stricttag.hpp>
+#include <boost/spirit/home/karma/detail/pass_container.hpp>
+#include <boost/spirit/home/karma/detail/fail_function.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/container.hpp>
@@ -42,36 +45,50 @@
struct base_plus : unary_generator<Derived>
{
private:
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Attribute const& attr, bool& result) const
+ // Ignore return value in relaxed mode (failing subject generators
+ // are just skipped). This allows to selectively generate items in
+ // the provided attribute.
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const& attr, bool& result, mpl::false_) const
{
- // Ignore return value, failing subject generators are just
- // skipped. This allows to selectively generate items in the
- // provided attribute.
- if (subject.generate(sink, ctx, d, attr)) {
+ bool r = !f(subject);
+ if (r)
result = true;
- return true;
- }
- return !Strict::value;
+ else if (!f.is_at_end())
+ f.next();
+ return true;
}
- template <typename OutputIterator, typename Context, typename Delimiter>
- bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, unused_type, bool& result) const
+ template <typename F, typename Attribute>
+ bool generate_subject(F f, Attribute const& attr, bool& result, mpl::true_) const
{
- // There is no way to distinguish a failed generator from a
- // generator to be skipped. We assume the user takes responsibility
- // for ending the loop if no attribute is specified.
- if (subject.generate(sink, ctx, d, unused)) {
+ bool r = !f(subject);
+ if (r)
result = true;
- return true;
- }
- return false;
+ return r;
}
+ // There is no way to distinguish a failed generator from a
+ // generator to be skipped. We assume the user takes responsibility
+ // for ending the loop if no attribute is specified.
+ template <typename F>
+ bool generate_subject(F f, unused_type, bool& result, mpl::false_) const
+ {
+ bool r = f(subject);
+ if (!r)
+ result = true;
+ return !r;
+ }
+
+// template <typename F>
+// bool generate_subject(F f, unused_type, bool& result, mpl::true_) const
+// {
+// bool r = f(subject);
+// if (!r)
+// result = true;
+// return !r;
+// }
+
public:
typedef Subject subject_type;
typedef typename subject_type::properties properties;
@@ -95,10 +112,20 @@
bool generate(OutputIterator& sink, Context& ctx
, Delimiter const& d, Attribute const& attr) const
{
+ typedef detail::fail_function<
+ OutputIterator, Context, Delimiter> fail_function;
+
typedef typename traits::container_iterator<
typename add_const<Attribute>::type
>::type iterator_type;
+ typedef
+ typename traits::make_indirect_iterator<iterator_type>::type
+ indirect_iterator_type;
+ typedef detail::pass_container<
+ fail_function, Attribute, indirect_iterator_type, mpl::false_>
+ pass_container;
+
iterator_type it = traits::begin(attr);
iterator_type end = traits::end(attr);
@@ -106,13 +133,15 @@
if (traits::compare(it, end))
return false;
+ pass_container pass(fail_function(sink, ctx, d),
+ indirect_iterator_type(it), indirect_iterator_type(end));
+
// from now on plus fails if the underlying output fails or overall
// no subject generators succeeded
bool result = false;
- for (/**/; detail::sink_is_good(sink) && !traits::compare(it, end);
- traits::next(it))
+ while (!pass.is_at_end())
{
- if (!generate_subject(sink, ctx, d, traits::deref(it), result))
+ if (!generate_subject(pass, attr, result, Strict()))
break;
}
return result && detail::sink_is_good(sink);
@@ -184,14 +213,14 @@
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::plus<Subject>, Attribute
- , Context, Iterator>
- : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+ , Context, Iterator>
+ : mpl::true_ {};
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::strict_plus<Subject>, Attribute
- , Context, Iterator>
- : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+ , Context, Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/operator/sequence.hpp (original)
+++ branches/release/boost/spirit/home/karma/operator/sequence.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -20,6 +20,7 @@
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/support/algorithm/any_if.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/sequence_base_id.hpp>
@@ -83,83 +84,11 @@
, mpl::bitor_<mpl::_2, mpl::_1>
>::type type;
};
-
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
- namespace detail
- {
-
- ///////////////////////////////////////////////////////////////////////
- // This is a wrapper for any iterator allowing to pass a reference of it
- // to the components of the sequence
- template <typename Iterator>
- class indirect_iterator
- : public boost::iterator_facade<
- indirect_iterator<Iterator>
- , typename boost::detail::iterator_traits<Iterator>::value_type
- , boost::forward_traversal_tag
- , typename boost::detail::iterator_traits<Iterator>::value_type const&>
- {
- typedef typename boost::detail::iterator_traits<Iterator>::value_type
- base_value_type;
-
- typedef boost::iterator_facade<
- indirect_iterator<Iterator>, base_value_type
- , boost::forward_traversal_tag, base_value_type const&
- > base_type;
-
- public:
- indirect_iterator(Iterator& iter)
- : iter_(&iter)
- {}
- indirect_iterator(indirect_iterator const& iter)
- : iter_(iter.iter_)
- {}
-
- private:
- friend class boost::iterator_core_access;
-
- void increment()
- {
- ++*iter_;
- }
-
- bool equal(indirect_iterator const& other) const
- {
- return *iter_ == *other.iter_;
- }
-
- typename base_type::reference dereference() const
- {
- return **iter_;
- }
-
- private:
- Iterator* iter_;
- };
-
- template <typename Iterator>
- struct make_indirect_iterator
- {
- typedef indirect_iterator<Iterator> type;
- };
-
- template <typename Iterator>
- struct make_indirect_iterator<indirect_iterator<Iterator> >
- {
- typedef indirect_iterator<Iterator> type;
- };
-
- template <>
- struct make_indirect_iterator<unused_type const*>
- {
- typedef unused_type const* type;
- };
- }
-
template <typename Elements, typename Strict, typename Derived>
struct base_sequence : nary_generator<Derived>
{
@@ -248,12 +177,15 @@
typedef detail::fail_function<
OutputIterator, Context, Delimiter> fail_function;
- typedef typename traits::container_iterator<Attribute const>::type
- iterator_type;
- typedef typename detail::make_indirect_iterator<iterator_type>::type
- indirect_iterator_type;
+ typedef typename traits::container_iterator<
+ typename add_const<Attribute>::type
+ >::type iterator_type;
+
+ typedef
+ typename traits::make_indirect_iterator<iterator_type>::type
+ indirect_iterator_type;
typedef detail::pass_container<
- fail_function, Attribute, indirect_iterator_type, Strict>
+ fail_function, Attribute, indirect_iterator_type, mpl::true_>
pass_container;
iterator_type begin = traits::begin(attr_);
@@ -365,14 +297,14 @@
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::sequence<Elements>, Attribute, Context
- , Iterator>
- : nary_handles_container<Elements, Attribute, Context, Iterator> {};
-
+ , Iterator>
+ : mpl::true_ {};
+
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<karma::strict_sequence<Elements>, Attribute
- , Context, Iterator>
- : nary_handles_container<Elements, Attribute, Context, Iterator> {};
+ , Context, Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/karma/phoenix_attributes.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/phoenix_attributes.hpp (original)
+++ branches/release/boost/spirit/home/karma/phoenix_attributes.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -16,6 +16,7 @@
#if SPIRIT_VERSION >= 0x2020
#include <boost/spirit/home/karma/detail/attributes.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
@@ -90,6 +91,18 @@
}
};
+ template <typename Eval>
+ struct container_value<phoenix::actor<Eval> >
+ {
+ typedef phoenix::actor<Eval> const& type;
+ };
+
+ template <typename Eval>
+ struct make_indirect_iterator<phoenix::actor<Eval> const>
+ {
+ typedef phoenix::actor<Eval> const& type;
+ };
+
///////////////////////////////////////////////////////////////////////////
// Handle Phoenix actors as attributes, just invoke the function object
// and deal with the result as the attribute.
@@ -105,7 +118,6 @@
return f(unused, context);
}
};
-
}}}
#endif
Modified: branches/release/boost/spirit/home/karma/stream/stream.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/stream/stream.hpp (original)
+++ branches/release/boost/spirit/home/karma/stream/stream.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -102,8 +102,12 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::stream;
using spirit::wstream;
+#endif
+ using spirit::stream_type;
+ using spirit::wstream_type;
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename CharEncoding, typename Tag>
@@ -113,7 +117,7 @@
template <typename Context, typename Unused = unused_type>
struct attribute
{
- typedef spirit::hold_any type;
+ typedef spirit::basic_hold_any<Char> type;
};
// any_stream_generator has an attached attribute
Modified: branches/release/boost/spirit/home/karma/string/lit.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/string/lit.hpp (original)
+++ branches/release/boost/spirit/home/karma/string/lit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -78,7 +78,9 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit;
+#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/karma/string/symbols.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/string/symbols.hpp (original)
+++ branches/release/boost/spirit/home/karma/string/symbols.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -732,6 +732,17 @@
};
}}}
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename T, typename Lookup
+ , typename CharEncoding, typename Tag
+ , typename Attr, typename Context, typename Iterator>
+ struct handles_container<karma::symbols<Attribute, T, Lookup, CharEncoding, Tag>
+ , Attr, Context, Iterator>
+ : traits::is_container<Attr> {};
+}}}
+
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
Modified: branches/release/boost/spirit/home/lex/argument.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/argument.hpp (original)
+++ branches/release/boost/spirit/home/lex/argument.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -31,7 +31,7 @@
///////////////////////////////////////////////////////////////////////////
// The state_getter is a Phoenix actor used to access the name of the
// current lexer state by calling get_state_name() on the context (which
- // is the 4th parameter to any lexer semantic actions).
+ // is the 5th parameter to any lexer semantic actions).
//
// This Phoenix actor is invoked whenever the placeholder '_state' is used
// as a rvalue inside a lexer semantic action:
@@ -68,7 +68,7 @@
///////////////////////////////////////////////////////////////////////////
// The state_setter is a Phoenix actor used to change the name of the
// current lexer state by calling set_state_name() on the context (which
- // is the 4th parameter to any lexer semantic actions).
+ // is the 5th parameter to any lexer semantic actions).
//
// This Phoenix actor is invoked whenever the placeholder '_state' is used
// as a lvalue inside a lexer semantic action:
@@ -179,7 +179,7 @@
///////////////////////////////////////////////////////////////////////////
// The value_setter is a Phoenix actor used to change the name of the
// current lexer state by calling set_state_name() on the context (which
- // is the 4th parameter to any lexer semantic actions).
+ // is the 5th parameter to any lexer semantic actions).
//
// This Phoenix actor is invoked whenever the placeholder '_val' is used
// as a lvalue inside a lexer semantic action:
@@ -381,7 +381,6 @@
// to its real, second argument (the RHS actor).
typedef spirit::lex::value_setter<typename as_actor<RHS>::type> type;
};
-
}}
#undef SPIRIT_DECLARE_ARG
Modified: branches/release/boost/spirit/home/lex/lexer/char_token_def.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/char_token_def.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/char_token_def.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -21,36 +21,51 @@
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
+
+ // enables 'x'
template <>
- struct use_terminal<lex::domain, char> // enables 'x'
+ struct use_terminal<lex::domain, char>
: mpl::true_ {};
+ // enables "x"
template <>
- struct use_terminal<lex::domain, char[2]> // enables "x"
+ struct use_terminal<lex::domain, char[2]>
: mpl::true_ {};
+ // enables wchar_t
template <>
- struct use_terminal<lex::domain, wchar_t> // enables wchar_t
+ struct use_terminal<lex::domain, wchar_t>
: mpl::true_ {};
+ // enables L"x"
template <>
- struct use_terminal<lex::domain, wchar_t[2]> // enables L"x"
+ struct use_terminal<lex::domain, wchar_t[2]>
: mpl::true_ {};
+ // enables char_('x'), char_("x")
template <typename CharEncoding, typename A0>
struct use_terminal<lex::domain
, terminal_ex<
- tag::char_code<tag::char_, CharEncoding> // enables char_('x'), char_("x")
- , fusion::vector1<A0>
- >
- > : mpl::true_ {};
+ tag::char_code<tag::char_, CharEncoding>
+ , fusion::vector1<A0> > >
+ : mpl::true_ {};
+
+ // enables char_('x', ID), char_("x", ID)
+ template <typename CharEncoding, typename A0, typename A1>
+ struct use_terminal<lex::domain
+ , terminal_ex<
+ tag::char_code<tag::char_, CharEncoding>
+ , fusion::vector2<A0, A1> > >
+ : mpl::true_ {};
}}
namespace boost { namespace spirit { namespace lex
{
// use char_ from standard character set by default
- using spirit::standard::char_type;
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::standard::char_;
+#endif
+ using spirit::standard::char_type;
///////////////////////////////////////////////////////////////////////////
//
@@ -58,14 +73,16 @@
// represents a single character token definition
//
///////////////////////////////////////////////////////////////////////////
- template <typename CharEncoding = char_encoding::standard>
+ template <typename CharEncoding = char_encoding::standard
+ , typename IdType = std::size_t>
struct char_token_def
- : primitive_lexer<char_token_def<CharEncoding> >
+ : primitive_lexer<char_token_def<CharEncoding, IdType> >
{
typedef typename CharEncoding::char_type char_type;
- char_token_def(char_type ch)
- : ch(ch), unique_id_(std::size_t(~0)), token_state_(std::size_t(~0))
+ char_token_def(char_type ch, IdType const& id)
+ : ch(ch), id_(id), unique_id_(std::size_t(~0))
+ , token_state_(std::size_t(~0))
{}
template <typename LexerDef, typename String>
@@ -88,18 +105,18 @@
lexdef.add_state(target);
token_state_ = state_id;
- unique_id_ = lexdef.add_token (state.c_str(), ch
- , static_cast<std::size_t>(ch), target);
+ unique_id_ = lexdef.add_token (state.c_str(), ch, id_, target);
}
template <typename LexerDef>
void add_actions(LexerDef&) const {}
- std::size_t id() const { return static_cast<std::size_t>(ch); }
+ IdType id() const { return id_; }
std::size_t unique_id() const { return unique_id_; }
std::size_t state() const { return token_state_; }
char_type ch;
+ mutable IdType id_;
mutable std::size_t unique_id_;
mutable std::size_t token_state_;
};
@@ -117,13 +134,13 @@
template <typename Char>
result_type operator()(Char ch, unused_type) const
{
- return result_type(ch);
+ return result_type(ch, ch);
}
template <typename Char>
result_type operator()(Char const* str, unused_type) const
{
- return result_type(str[0]);
+ return result_type(str[0], str[0]);
}
};
}
@@ -160,7 +177,7 @@
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
- return result_type(fusion::at_c<0>(term.args));
+ return result_type(fusion::at_c<0>(term.args), fusion::at_c<0>(term.args));
}
};
@@ -178,7 +195,46 @@
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
- return result_type(fusion::at_c<0>(term.args)[0]);
+ Char ch = fusion::at_c<0>(term.args)[0];
+ return result_type(ch, ch);
+ }
+ };
+
+ // handle char_('x', ID)
+ template <typename CharEncoding, typename Modifiers, typename A0, typename A1>
+ struct make_primitive<
+ terminal_ex<
+ tag::char_code<tag::char_, CharEncoding>
+ , fusion::vector2<A0, A1>
+ >
+ , Modifiers>
+ {
+ typedef char_token_def<CharEncoding> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, unused_type) const
+ {
+ return result_type(
+ fusion::at_c<0>(term.args), fusion::at_c<1>(term.args));
+ }
+ };
+
+ // handle char_("x", ID)
+ template <typename CharEncoding, typename Modifiers, typename Char, typename A1>
+ struct make_primitive<
+ terminal_ex<
+ tag::char_code<tag::char_, CharEncoding>
+ , fusion::vector2<Char(&)[2], A1> // single char strings
+ >
+ , Modifiers>
+ {
+ typedef char_token_def<CharEncoding> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, unused_type) const
+ {
+ return result_type(
+ fusion::at_c<0>(term.args)[0], fusion::at_c<1>(term.args));
}
};
}}} // namespace boost::spirit::lex
Modified: branches/release/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -548,7 +548,7 @@
typedef typename boost::lexer::basic_state_machine<Char>::iterator
iterator_type;
iterator_type iter_ = sm_.begin();
- std::size_t states_ = iter_->states;
+ std::size_t const states_ = iter_->states;
for (std::size_t state_ = 0; state_ < states_; ++state_)
{
Modified: branches/release/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -40,12 +40,14 @@
}
bool bol = bol_;
+ boost::lexer::detail::internals const& internals_ =
+ state_machine_.data();
again:
- std::size_t const* lookup_ = &state_machine_.data()._lookup[dfa_state_]->
+ std::size_t const* lookup_ = &internals_._lookup[dfa_state_]->
front ();
- std::size_t dfa_alphabet_ = state_machine_.data()._dfa_alphabet[dfa_state_];
- std::size_t const* dfa_ = &state_machine_.data()._dfa[dfa_state_]->front ();
+ std::size_t dfa_alphabet_ = internals_._dfa_alphabet[dfa_state_];
+ std::size_t const* dfa_ = &internals_._dfa[dfa_state_]->front ();
std::size_t const* ptr_ = dfa_ + dfa_alphabet_;
Iterator curr_ = start_token_;
Modified: branches/release/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/lexertl/static_functor_data.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -318,7 +318,9 @@
: base_type(data, first, last)
, actions_(data.actions_), hold_()
, value_(iterator_range<Iterator>(first, last))
- , has_hold_(false), has_value_(false) {}
+ , has_value_(false)
+ , has_hold_(false)
+ {}
// invoke attached semantic actions, if defined
BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state
Modified: branches/release/boost/spirit/home/lex/lexer/lexertl/token.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/lexertl/token.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/lexertl/token.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,6 +18,7 @@
#include <boost/spirit/home/support/detail/lexer/generator.hpp>
#include <boost/spirit/home/support/detail/lexer/rules.hpp>
#include <boost/spirit/home/support/detail/lexer/consts.hpp>
+#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
Modified: branches/release/boost/spirit/home/lex/lexer/string_token_def.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/string_token_def.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/string_token_def.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -17,6 +17,7 @@
#include <boost/spirit/home/lex/meta_compiler.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at.hpp>
@@ -26,25 +27,37 @@
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
+
+ // enables strings
template <typename T>
struct use_terminal<lex::domain, T
- , typename enable_if<traits::is_string<T> >::type> // enables strings
+ , typename enable_if<traits::is_string<T> >::type>
: mpl::true_ {};
+ // enables string(str)
template <typename CharEncoding, typename A0>
struct use_terminal<lex::domain
, terminal_ex<
- tag::char_code<tag::string, CharEncoding> // enables string(str)
- , fusion::vector1<A0> >
- > : traits::is_string<A0> {};
+ tag::char_code<tag::string, CharEncoding>
+ , fusion::vector1<A0> > >
+ : traits::is_string<A0> {};
+ // enables string(str, ID)
+ template <typename CharEncoding, typename A0, typename A1>
+ struct use_terminal<lex::domain
+ , terminal_ex<
+ tag::char_code<tag::string, CharEncoding>
+ , fusion::vector2<A0, A1> > >
+ : traits::is_string<A0> {};
}}
namespace boost { namespace spirit { namespace lex
{
// use string from standard character set by default
- using spirit::standard::string_type;
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::standard::string;
+#endif
+ using spirit::standard::string_type;
///////////////////////////////////////////////////////////////////////////
//
@@ -52,17 +65,18 @@
// represents a string based token definition
//
///////////////////////////////////////////////////////////////////////////
- template <typename String, typename CharEncoding = char_encoding::standard>
+ template <typename String, typename IdType = std::size_t
+ , typename CharEncoding = char_encoding::standard>
struct string_token_def
- : primitive_lexer<string_token_def<String, CharEncoding> >
+ : primitive_lexer<string_token_def<String, IdType, CharEncoding> >
{
typedef typename
remove_const<typename traits::char_type_of<String>::type>::type
char_type;
typedef std::basic_string<char_type> string_type;
- string_token_def(typename add_reference<String>::type str)
- : str_(str), id_(std::size_t(~0)), unique_id_(std::size_t(~0))
+ string_token_def(typename add_reference<String>::type str, IdType const& id)
+ : str_(str), id_(id), unique_id_(std::size_t(~0))
, token_state_(std::size_t(~0))
{}
@@ -88,8 +102,8 @@
token_state_ = state_id;
typedef typename LexerDef::id_type id_type;
- if (std::size_t(~0) == id_)
- id_ = lexdef.get_next_id();
+ if (IdType(~0) == id_)
+ id_ = IdType(lexdef.get_next_id());
unique_id_ = lexdef.add_token (state.c_str(), str_, id_, target);
}
@@ -102,7 +116,7 @@
std::size_t state() const { return token_state_; }
string_type str_;
- mutable std::size_t id_;
+ mutable IdType id_;
mutable std::size_t unique_id_;
mutable std::size_t token_state_;
};
@@ -120,7 +134,7 @@
result_type operator()(
typename add_reference<const_string>::type str, unused_type) const
{
- return result_type(str);
+ return result_type(str, std::size_t(~0));
}
};
@@ -132,15 +146,33 @@
, Modifiers>
{
typedef typename add_const<A0>::type const_string;
- typedef string_token_def<const_string, CharEncoding> result_type;
+ typedef string_token_def<const_string, std::size_t, CharEncoding>
+ result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
- return result_type(fusion::at_c<0>(term.args));
+ return result_type(fusion::at_c<0>(term.args), std::size_t(~0));
}
};
+ template <typename Modifiers, typename CharEncoding, typename A0, typename A1>
+ struct make_primitive<
+ terminal_ex<
+ tag::char_code<tag::string, CharEncoding>
+ , fusion::vector2<A0, A1> >
+ , Modifiers>
+ {
+ typedef typename add_const<A0>::type const_string;
+ typedef string_token_def<const_string, A1, CharEncoding> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, unused_type) const
+ {
+ return result_type(
+ fusion::at_c<0>(term.args), fusion::at_c<1>(term.args));
+ }
+ };
}}} // namespace boost::spirit::lex
#endif
Modified: branches/release/boost/spirit/home/lex/lexer/terminals.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/lexer/terminals.hpp (original)
+++ branches/release/boost/spirit/home/lex/lexer/terminals.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,7 +18,6 @@
// Define a more convenient name for an omitted token attribute type
typedef spirit::omit_type omit;
using spirit::omit_type;
-
}}}
#endif
Modified: branches/release/boost/spirit/home/lex/qi/in_state.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/qi/in_state.hpp (original)
+++ branches/release/boost/spirit/home/lex/qi/in_state.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -27,7 +27,6 @@
>::type
, Skipper
>::type {};
-
}}}
#endif
Modified: branches/release/boost/spirit/home/lex/qi/plain_token.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/qi/plain_token.hpp (original)
+++ branches/release/boost/spirit/home/lex/qi/plain_token.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -52,7 +52,10 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::token;
+#endif
+ using spirit::token_type;
///////////////////////////////////////////////////////////////////////////
template <typename TokenId>
Modified: branches/release/boost/spirit/home/lex/qi/plain_tokenid.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/qi/plain_tokenid.hpp (original)
+++ branches/release/boost/spirit/home/lex/qi/plain_tokenid.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -51,7 +51,10 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::tokenid;
+#endif
+ using spirit::tokenid_type;
///////////////////////////////////////////////////////////////////////////
// The plain_tokenid represents a simple token defined by the lexer inside
Modified: branches/release/boost/spirit/home/lex/qi/state_switcher.hpp
==============================================================================
--- branches/release/boost/spirit/home/lex/qi/state_switcher.hpp (original)
+++ branches/release/boost/spirit/home/lex/qi/state_switcher.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -138,13 +138,13 @@
template <typename State>
reset_state_on_exit(Iterator& it_, State state_)
: it(it_)
- , state(detail::set_lexer_state(it_, traits::get_c_string(state_)))
+ , state(set_lexer_state(it_, traits::get_c_string(state_)))
{}
~reset_state_on_exit()
{
// reset the state of the underlying lexer instance
- detail::set_lexer_state(it, state);
+ set_lexer_state(it, state);
}
Iterator& it;
Modified: branches/release/boost/spirit/home/phoenix/core/actor.hpp
==============================================================================
--- branches/release/boost/spirit/home/phoenix/core/actor.hpp (original)
+++ branches/release/boost/spirit/home/phoenix/core/actor.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -56,6 +56,11 @@
typedef typename Eval::template result<Env>::type type;
};
+#if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable: 4522) // multiple assignment operators specified warning
+#endif
+
template <typename Eval>
struct actor : Eval
{
@@ -86,6 +91,18 @@
>::type
nullary_result;
+ actor& operator=(actor const& rhs)
+ {
+ Eval::operator=(rhs);
+ return *this;
+ }
+
+ actor& operator=(actor& rhs)
+ {
+ Eval::operator=(rhs);
+ return *this;
+ }
+
nullary_result
operator()() const
{
@@ -137,12 +154,12 @@
// Bring in the rest of the constructors and function call operators
#include <boost/spirit/home/phoenix/core/detail/actor.hpp>
-
- private:
- // silence MSVC warning C4512: assignment operator could not be generated
- actor& operator= (actor const&);
};
+#if defined(BOOST_MSVC)
+# pragma warning(pop)
+#endif
+
// Forward declaration: The intent to overload the comma must be
// stated early on to avoid the subtle problem that arises when
// the header file where the comma operator overload is defined,
Modified: branches/release/boost/spirit/home/phoenix/core/value.hpp
==============================================================================
--- branches/release/boost/spirit/home/phoenix/core/value.hpp (original)
+++ branches/release/boost/spirit/home/phoenix/core/value.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,7 +1,7 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
- Distributed under the Boost Software License, Version 1.0. (See accompanying
+ Distributed under the 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 PHOENIX_CORE_VALUE_HPP
@@ -44,7 +44,7 @@
}
template <typename T>
- struct value
+ struct value
{
BOOST_STATIC_ASSERT(
mpl::not_<is_reference<T> >::value != 0);
@@ -57,6 +57,9 @@
typedef T type;
};
+ value()
+ : val() {}
+
value(T const& arg)
: val(arg) {}
@@ -71,14 +74,14 @@
};
template <typename Actor>
- struct actor_value
+ struct actor_value
{
typedef typename Actor::no_nullary no_nullary;
template <typename Env>
struct result
{
- typedef typename
+ typedef typename
remove_reference<
typename eval_result<Actor, Env>::type
>::type
@@ -124,7 +127,7 @@
}
};
- // Sometimes it is necessary to auto-convert references to
+ // Sometimes it is necessary to auto-convert references to
// a value<T>. This happens when we are re-currying. This
// cannot happen through the standard public actor interfaces.
template <typename T>
Modified: branches/release/boost/spirit/home/qi/action/action.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/action/action.hpp (original)
+++ branches/release/boost/spirit/home/qi/action/action.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -44,6 +44,7 @@
action(Subject const& subject, Action f)
: subject(subject), f(f) {}
+#ifndef BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
@@ -68,12 +69,65 @@
if (traits::action_dispatch<Subject>()(f, attr, context))
return true;
- // reset iterators if semantic action failed the match
+ // reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
+#else
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ Iterator save = first;
+ if (subject.parse(first, last, context, skipper, attr)) // Use the attribute as-is
+ {
+ // call the function, passing the attribute, the context.
+ // The client can return false to fail parsing.
+ if (traits::action_dispatch<Subject>()(f, attr, context))
+ return true;
+
+ // reset iterators if semantic action failed the match
+ // retrospectively
+ first = save;
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , unused_type) const
+ {
+ typedef typename attribute<Context, Iterator>::type attr_type;
+ typedef traits::make_attribute<attr_type, unused_type> make_attribute;
+
+ // synthesize the attribute since one is not supplied
+ typedef traits::transform_attribute<
+ typename make_attribute::type, attr_type, domain> transform;
+
+ typename make_attribute::type made_attr = make_attribute::call(unused_type());
+ typename transform::type attr = transform::pre(made_attr);
+
+ Iterator save = first;
+ if (subject.parse(first, last, context, skipper, attr))
+ {
+ // call the function, passing the attribute, the context.
+ // The client can return false to fail parsing.
+ if (traits::action_dispatch<Subject>()(f, attr, context))
+ return true;
+
+ // reset iterators if semantic action failed the match
+ // retrospectively
+ first = save;
+ }
+ return false;
+ }
+#endif
template <typename Context>
info what(Context& context) const
Modified: branches/release/boost/spirit/home/qi/auto/auto.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auto/auto.hpp (original)
+++ branches/release/boost/spirit/home/qi/auto/auto.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -35,7 +35,10 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::auto_;
+#endif
+ using spirit::auto_type;
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
@@ -73,7 +76,7 @@
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
- struct make_primitive<tag::auto_, Modifiers>
+ struct make_primitive<tag::auto_, Modifiers>
{
typedef auto_parser<Modifiers> result_type;
Modified: branches/release/boost/spirit/home/qi/auto/meta_create.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auto/meta_create.hpp (original)
+++ branches/release/boost/spirit/home/qi/auto/meta_create.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -90,7 +90,7 @@
template <typename T>
struct meta_create_impl<T, typename enable_if<
- spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
+ spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
>::type>
: meta_create_sequence<T> {};
@@ -140,74 +140,74 @@
struct meta_create<char>
{
typedef spirit::standard::char_type type;
- static type const& call() { return spirit::standard::char_; }
+ static type call() { return type(); }
};
template <>
struct meta_create<signed char>
{
typedef spirit::standard::char_type type;
- static type const& call() { return spirit::standard::char_; }
+ static type call() { return type(); }
};
template <>
struct meta_create<wchar_t>
{
typedef spirit::standard_wide::char_type type;
- static type const& call() { return spirit::standard_wide::char_; }
+ static type call() { return type(); }
};
template <>
struct meta_create<unsigned char>
{
typedef spirit::standard::char_type type;
- static type const& call() { return spirit::standard::char_; }
+ static type call() { return type(); }
};
// boolean generator
template <>
struct meta_create<bool>
{
- typedef spirit::bool__type type;
- static type const& call() { return spirit::bool_; }
+ typedef spirit::bool_type type;
+ static type call() { return type(); }
};
// integral generators
template <>
struct meta_create<int>
{
- typedef spirit::int__type type;
- static type const& call() { return spirit::int_; }
+ typedef spirit::int_type type;
+ static type call() { return type(); }
};
template <>
struct meta_create<short>
{
- typedef spirit::short__type type;
- static type const& call() { return spirit::short_; }
+ typedef spirit::short_type type;
+ static type call() { return type(); }
};
template <>
struct meta_create<long>
{
- typedef spirit::long__type type;
- static type const& call() { return spirit::long_; }
+ typedef spirit::long_type type;
+ static type call() { return type(); }
};
template <>
struct meta_create<unsigned int>
{
- typedef spirit::uint__type type;
- static type const& call() { return spirit::uint_; }
+ typedef spirit::uint_type type;
+ static type call() { return type(); }
};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct meta_create<unsigned short>
{
- typedef spirit::ushort__type type;
- static type const& call() { return spirit::ushort_; }
+ typedef spirit::ushort_type type;
+ static type call() { return type(); }
};
#endif
template <>
struct meta_create<unsigned long>
{
- typedef spirit::ulong__type type;
- static type const& call() { return spirit::ulong_; }
+ typedef spirit::ulong_type type;
+ static type call() { return type(); }
};
#ifdef BOOST_HAS_LONG_LONG
@@ -215,13 +215,13 @@
struct meta_create<boost::long_long_type>
{
typedef spirit::long_long_type type;
- static type const& call() { return spirit::long_long; }
+ static type call() { return type(); }
};
template <>
struct meta_create<boost::ulong_long_type>
{
typedef spirit::ulong_long_type type;
- static type const& call() { return spirit::ulong_long; }
+ static type call() { return type(); }
};
#endif
@@ -229,20 +229,20 @@
template <>
struct meta_create<float>
{
- typedef spirit::float__type type;
- static type const& call() { return spirit::float_; }
+ typedef spirit::float_type type;
+ static type call() { return type(); }
};
template <>
struct meta_create<double>
{
- typedef spirit::double__type type;
- static type const& call() { return spirit::double_; }
+ typedef spirit::double_type type;
+ static type call() { return type(); }
};
template <>
struct meta_create<long double>
{
typedef spirit::long_double_type type;
- static type const& call() { return spirit::long_double; }
+ static type call() { return type(); }
};
}}}
Modified: branches/release/boost/spirit/home/qi/auxiliary/attr.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auxiliary/attr.hpp (original)
+++ branches/release/boost/spirit/home/qi/auxiliary/attr.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,6 +18,7 @@
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_const.hpp>
@@ -29,18 +30,21 @@
///////////////////////////////////////////////////////////////////////////
template <typename A0> // enables attr()
struct use_terminal<
- qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > >
+ qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > >
: mpl::true_ {};
template <> // enables *lazy* attr()
- struct use_lazy_terminal<qi::domain, tag::attr, 1>
+ struct use_lazy_terminal<qi::domain, tag::attr, 1>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::attr;
+#endif
+ using spirit::attr_type;
template <typename Value>
struct attr_parser : primitive_parser<attr_parser<Value> >
@@ -93,6 +97,14 @@
};
}}}
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Attr, typename Context, typename Iterator>
+ struct handles_container<qi::attr_parser<T>, Attr, Context, Iterator>
+ : traits::is_container<Attr> {};
+}}}
+
#endif
Modified: branches/release/boost/spirit/home/qi/auxiliary/eoi.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auxiliary/eoi.hpp (original)
+++ branches/release/boost/spirit/home/qi/auxiliary/eoi.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -31,7 +31,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eoi;
+#endif
using spirit::eoi_type;
struct eoi_parser : primitive_parser<eoi_parser>
Modified: branches/release/boost/spirit/home/qi/auxiliary/eol.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auxiliary/eol.hpp (original)
+++ branches/release/boost/spirit/home/qi/auxiliary/eol.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -31,7 +31,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eol;
+#endif
using spirit::eol_type;
struct eol_parser : primitive_parser<eol_parser>
Modified: branches/release/boost/spirit/home/qi/auxiliary/eps.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auxiliary/eps.hpp (original)
+++ branches/release/boost/spirit/home/qi/auxiliary/eps.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -42,7 +42,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::eps;
+#endif
using spirit::eps_type;
struct eps_parser : primitive_parser<eps_parser>
Modified: branches/release/boost/spirit/home/qi/auxiliary/lazy.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/auxiliary/lazy.hpp (original)
+++ branches/release/boost/spirit/home/qi/auxiliary/lazy.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,7 +18,7 @@
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/lazy.hpp>
-#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
Modified: branches/release/boost/spirit/home/qi/binary/binary.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/binary/binary.hpp (original)
+++ branches/release/boost/spirit/home/qi/binary/binary.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -65,26 +65,31 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using boost::spirit::byte_;
- using boost::spirit::byte__type;
using boost::spirit::word;
- using boost::spirit::word_type;
using boost::spirit::big_word;
- using boost::spirit::big_word_type;
using boost::spirit::little_word;
- using boost::spirit::little_word_type;
using boost::spirit::dword;
- using boost::spirit::dword_type;
using boost::spirit::big_dword;
- using boost::spirit::big_dword_type;
using boost::spirit::little_dword;
- using boost::spirit::little_dword_type;
#ifdef BOOST_HAS_LONG_LONG
using boost::spirit::qword;
- using boost::spirit::qword_type;
using boost::spirit::big_qword;
- using boost::spirit::big_qword_type;
using boost::spirit::little_qword;
+#endif
+#endif
+
+ using boost::spirit::byte_type;
+ using boost::spirit::word_type;
+ using boost::spirit::big_word_type;
+ using boost::spirit::little_word_type;
+ using boost::spirit::dword_type;
+ using boost::spirit::big_dword_type;
+ using boost::spirit::little_dword_type;
+#ifdef BOOST_HAS_LONG_LONG
+ using boost::spirit::qword_type;
+ using boost::spirit::big_qword_type;
using boost::spirit::little_qword_type;
#endif
Modified: branches/release/boost/spirit/home/qi/char/char.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/char/char.hpp (original)
+++ branches/release/boost/spirit/home/qi/char/char.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -96,14 +96,16 @@
// enables lit(...)
template <typename A0>
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_char<A0> >::type>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit; // lit('x') is equivalent to 'x'
+#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/qi/detail/alternative_function.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/alternative_function.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/alternative_function.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -20,6 +20,29 @@
namespace boost { namespace spirit { namespace qi { namespace detail
{
+ template <typename Variant, typename Expected>
+ struct find_substitute
+ {
+ // Get the typr from the variant that can be a substitute for Expected.
+ // If none is found, just return Expected
+
+ typedef Variant variant_type;
+ typedef typename variant_type::types types;
+ typedef typename mpl::end<types>::type end;
+
+ typedef typename
+ mpl::find_if<types, traits::is_substitute<mpl::_1, Expected> >::type
+ iter;
+
+ typedef typename
+ mpl::eval_if<
+ is_same<iter, end>,
+ mpl::identity<Expected>,
+ mpl::deref<iter>
+ >::type
+ type;
+ };
+
template <typename Iterator, typename Context, typename Skipper,
typename Attribute>
struct alternative_function
@@ -40,11 +63,21 @@
}
template <typename Component>
- bool call(Component const& component, mpl::false_) const
+ bool call_optional_or_variant(Component const& component, mpl::true_) const
{
- // if Attribute is a variant or optional, then create an
- // attribute for the Component with its expected type.
- typename traits::attribute_of<Component, Context, Iterator>::type val;
+ // If Attribute is an optional, then create an attribute for the Component
+ // with the type optional::value_type. If the expected attribute is unused type,
+ // use it instead.
+ typedef typename
+ traits::attribute_of<Component, Context, Iterator>::type
+ expected_type;
+
+ typename mpl::if_<
+ is_same<expected_type, unused_type>,
+ unused_type,
+ typename Attribute::value_type>::type
+ val;
+
if (component.parse(first, last, context, skipper, val))
{
traits::assign_to(val, attr);
@@ -54,16 +87,81 @@
}
template <typename Component>
- bool operator()(Component const& component) const
+ bool call_variant(Component const& component, mpl::false_) const
+ {
+ // If Attribute is a variant, then search the variant types for a
+ // suitable substitute type.
+
+ typename
+ find_substitute<Attribute,
+ typename traits::attribute_of<Component, Context, Iterator>::type
+ >::type
+ val;
+
+ if (component.parse(first, last, context, skipper, val))
+ {
+ traits::assign_to(val, attr);
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Component>
+ bool call_variant(Component const& component, mpl::true_) const
+ {
+ // If Attribute is a variant and the expected attribute is
+ // the same type (pass the variant as-is).
+
+ return component.parse(first, last, context, skipper, attr);
+ }
+
+ template <typename Component>
+ bool call_optional_or_variant(Component const& component, mpl::false_) const
+ {
+ // Attribute is a variant...
+
+ typedef typename
+ traits::attribute_of<Component, Context, Iterator>::type
+ expected;
+ return call_variant(component,
+ is_same<Attribute, expected>());
+ }
+
+ template <typename Component>
+ bool call(Component const& component, mpl::false_) const
+ {
+ return call_optional_or_variant(
+ component, spirit::traits::not_is_variant<Attribute, qi::domain>());
+ }
+
+ template <typename Component>
+ bool call_unused(Component const& component, mpl::true_) const
{
// return true if the parser succeeds
- return call(component,
+ return call(component,
mpl::and_<
spirit::traits::not_is_variant<Attribute, qi::domain>,
- spirit::traits::not_is_optional<Attribute, qi::domain>
+ spirit::traits::not_is_optional<Attribute, qi::domain>
>());
}
+ template <typename Component>
+ bool call_unused(Component const& component, mpl::false_) const
+ {
+ return component.parse(first, last, context, skipper, unused);
+ }
+
+ template <typename Component>
+ bool operator()(Component const& component) const
+ {
+ // return true if the parser succeeds
+ typedef typename traits::not_is_unused<
+ typename traits::attribute_of<Component, Context, Iterator>::type
+ >::type predicate;
+
+ return call_unused(component, predicate());
+ }
+
Iterator& first;
Iterator const& last;
Context& context;
Modified: branches/release/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/assign_to.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/assign_to.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -17,7 +17,7 @@
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
-#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/fusion/include/copy.hpp>
#include <boost/ref.hpp>
#include <boost/range/iterator_range.hpp>
@@ -31,7 +31,7 @@
template <typename Attribute, typename Iterator, typename Enable>
struct assign_to_attribute_from_iterators
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, Attribute& attr)
{
if (traits::is_empty(attr))
@@ -47,7 +47,7 @@
struct assign_to_attribute_from_iterators<
reference_wrapper<Attribute>, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last
, reference_wrapper<Attribute> attr)
{
@@ -64,7 +64,7 @@
struct assign_to_attribute_from_iterators<
iterator_range<Iterator>, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last
, iterator_range<Iterator>& attr)
{
@@ -93,7 +93,7 @@
template <typename Attribute, typename T, typename Enable>
struct assign_to_attribute_from_value
{
- typedef typename traits::one_element_sequence<Attribute>::type
+ typedef typename traits::one_element_sequence<Attribute>::type
is_one_element_sequence;
typedef typename mpl::eval_if<
@@ -103,25 +103,25 @@
>::type type;
template <typename T_>
- static void
+ static void
call(T_ const& val, Attribute& attr, mpl::false_)
{
attr = static_cast<Attribute>(val);
}
// This handles the case where the attribute is a single element fusion
- // sequence. We silently assign to the only element and treat it as the
+ // sequence. We silently assign to the only element and treat it as the
// attribute to parse the results into.
template <typename T_>
- static void
+ static void
call(T_ const& val, Attribute& attr, mpl::true_)
{
- typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
+ typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
element_type;
fusion::at_c<0>(attr) = static_cast<element_type>(val);
}
- static void
+ static void
call(T const& val, Attribute& attr)
{
call(val, attr, is_one_element_sequence());
@@ -131,7 +131,7 @@
template <typename Attribute>
struct assign_to_attribute_from_value<Attribute, Attribute>
{
- static void
+ static void
call(Attribute const& val, Attribute& attr)
{
attr = val;
@@ -141,7 +141,7 @@
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<reference_wrapper<Attribute>, T>
{
- static void
+ static void
call(T const& val, reference_wrapper<Attribute> attr)
{
assign_to(val.get(), attr);
@@ -149,14 +149,39 @@
};
template <typename Attribute>
- struct assign_to_attribute_from_value<optional<Attribute>, unused_type>
+ struct assign_to_attribute_from_value<boost::optional<Attribute>, unused_type>
{
- static void
- call(unused_type, optional<Attribute> const&)
+ static void
+ call(unused_type, boost::optional<Attribute> const&)
{
}
};
+ namespace detail
+ {
+ template <typename A, typename B>
+ struct is_same_size_sequence
+ : mpl::bool_<fusion::result_of::size<A>::value
+ == fusion::result_of::size<B>::value>
+ {};
+ }
+
+ template <typename Attribute, typename T>
+ struct assign_to_attribute_from_value<Attribute, T,
+ mpl::and_<
+ fusion::traits::is_sequence<Attribute>,
+ fusion::traits::is_sequence<T>,
+ detail::is_same_size_sequence<Attribute, T>
+ >
+ >
+ {
+ static void
+ call(T const& val, Attribute& attr)
+ {
+ fusion::copy(val, attr);
+ }
+ };
+
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T, typename Enable>
struct assign_to_container_from_value
@@ -168,33 +193,74 @@
traits::push_back(attr, val);
}
- // T is a container (but not a string)
+ // T is a container (but not a string), and T is convertible to the
+ // value_type of the Attribute container
template <typename T_>
- static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
+ static void
+ append_to_container_not_string(T_ const& val, Attribute& attr, mpl::true_)
{
- typedef typename traits::container_iterator<T_ const>::type
+ traits::push_back(attr, val);
+ }
+
+ // T is a container (but not a string), generic overload
+ template <typename T_>
+ static void
+ append_to_container_not_string(T_ const& val, Attribute& attr, mpl::false_)
+ {
+ typedef typename traits::container_iterator<T_ const>::type
iterator_type;
+
iterator_type end = traits::end(val);
for (iterator_type i = traits::begin(val); i != end; traits::next(i))
- push_back(attr, traits::deref(i));
+ traits::push_back(attr, traits::deref(i));
}
- // T is a string
+ // T is a container (but not a string)
+ template <typename T_>
+ static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
+ {
+ typedef typename container_value<Attribute>::type value_type;
+ typedef typename is_convertible<T, value_type>::type is_value_type;
+
+ append_to_container_not_string(val, attr, is_value_type());
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // T is a string
template <typename Iterator>
static void append_to_string(Attribute& attr, Iterator begin, Iterator end)
{
for (Iterator i = begin; i != end; ++i)
- push_back(attr, *i);
+ traits::push_back(attr, *i);
}
- template <typename T_, typename Pred>
- static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
+ // T is string, but not convertible to value_type of container
+ template <typename T_>
+ static void append_to_container(T_ const& val, Attribute& attr, mpl::false_)
{
typedef typename char_type_of<T_>::type char_type;
+
append_to_string(attr, traits::get_begin<char_type>(val)
, traits::get_end<char_type>(val));
}
+ // T is string, and convertible to value_type of container
+ template <typename T_>
+ static void append_to_container(T_ const& val, Attribute& attr, mpl::true_)
+ {
+ traits::push_back(attr, val);
+ }
+
+ template <typename T_, typename Pred>
+ static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
+ {
+ typedef typename container_value<Attribute>::type value_type;
+ typedef typename is_convertible<T, value_type>::type is_value_type;
+
+ append_to_container(val, attr, is_value_type());
+ }
+
+ ///////////////////////////////////////////////////////////////////////
static void call(T const& val, Attribute& attr)
{
typedef typename traits::is_container<T>::type is_container;
@@ -207,7 +273,7 @@
template <typename Attribute, typename T>
struct assign_to_container_from_value<reference_wrapper<Attribute>, T>
{
- static void
+ static void
call(T const& val, reference_wrapper<Attribute> attr)
{
assign_to(val.get(), attr);
@@ -215,10 +281,10 @@
};
template <typename Attribute>
- struct assign_to_container_from_value<optional<Attribute>, unused_type>
+ struct assign_to_container_from_value<boost::optional<Attribute>, unused_type>
{
- static void
- call(unused_type, optional<Attribute> const&)
+ static void
+ call(unused_type, boost::optional<Attribute> const&)
{
}
};
@@ -227,18 +293,18 @@
namespace detail
{
// overload for non-container attributes
- template <typename T, typename Attribute, typename P1, typename P2>
+ template <typename T, typename Attribute>
inline void
- assign_to(T const& val, Attribute& attr, P1, P2)
+ assign_to(T const& val, Attribute& attr, mpl::false_)
{
assign_to_attribute_from_value<Attribute, T>::call(val, attr);
}
- // overload for containers (but not for variants or optionals
+ // overload for containers (but not for variants or optionals
// holding containers)
template <typename T, typename Attribute>
inline void
- assign_to(T const& val, Attribute& attr, mpl::true_, mpl::true_)
+ assign_to(T const& val, Attribute& attr, mpl::true_)
{
assign_to_container_from_value<Attribute, T>::call(val, attr);
}
@@ -248,13 +314,13 @@
inline void
assign_to(T const& val, Attribute& attr)
{
- typedef typename traits::is_container<Attribute>::type is_container;
typedef typename mpl::and_<
- traits::not_is_variant<Attribute>
- , traits::not_is_optional<Attribute>
+ traits::is_container<Attribute>
+ , traits::not_is_variant<Attribute>
+ , traits::not_is_optional<Attribute>
>::type is_not_wrapped_container;
- detail::assign_to(val, attr, is_container(), is_not_wrapped_container());
+ detail::assign_to(val, attr, is_not_wrapped_container());
}
template <typename T>
Modified: branches/release/boost/spirit/home/qi/detail/attributes.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/attributes.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/attributes.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -10,6 +10,7 @@
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
@@ -19,7 +20,7 @@
{
typedef Transformed type;
- static Transformed pre(Exposed& val) { return Transformed(); }
+ static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed const& attr)
{
@@ -46,7 +47,7 @@
typedef Transformed type;
static Transformed pre(Exposed& val) { return Transformed(val); }
- static void post(Exposed& val, Transformed const& attr) { /* no-op */ }
+ static void post(Exposed&, Transformed const&) { /* no-op */ }
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
@@ -76,18 +77,18 @@
{};
template <typename Exposed, typename Transformed>
- struct transform_attribute<optional<Exposed>, Transformed
- , typename disable_if<is_same<optional<Exposed>, Transformed> >::type>
+ struct transform_attribute<boost::optional<Exposed>, Transformed
+ , typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
{
typedef Transformed& type;
- static Transformed& pre(optional<Exposed>& val)
+ static Transformed& pre(boost::optional<Exposed>& val)
{
if (!val)
val = Transformed();
return boost::get<Transformed>(val);
}
- static void post(optional<Exposed>&, Transformed const&) {}
- static void fail(optional<Exposed>& val)
+ static void post(boost::optional<Exposed>&, Transformed const&) {}
+ static void fail(boost::optional<Exposed>& val)
{
val = none_t(); // leave optional uninitialized if rhs failed
}
Modified: branches/release/boost/spirit/home/qi/detail/construct.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/construct.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/construct.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -20,13 +20,13 @@
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
- // We provide overloads for the assign_to_attribute_from_iterators
+ // We provide overloads for the assign_to_attribute_from_iterators
// customization point for all built in types
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct assign_to_attribute_from_iterators<char, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, char& attr)
{
attr = *first;
@@ -36,7 +36,7 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<signed char, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, signed char& attr)
{
attr = *first;
@@ -46,7 +46,7 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned char, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, unsigned char& attr)
{
attr = *first;
@@ -57,7 +57,7 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<wchar_t, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, wchar_t& attr)
{
attr = *first;
@@ -69,7 +69,7 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned short, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, unsigned short& attr)
{
attr = *first;
@@ -80,64 +80,64 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<bool, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, bool& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, bool_, attr);
+ qi::parse(first_, last, bool_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<short, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, short& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, short_, attr);
+ qi::parse(first_, last, short_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<int, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, int& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, int_, attr);
+ qi::parse(first_, last, int_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned int, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, unsigned int& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, uint_, attr);
+ qi::parse(first_, last, uint_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, long& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, long_, attr);
+ qi::parse(first_, last, long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned long, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, unsigned long& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, ulong_, attr);
+ qi::parse(first_, last, ulong_type(), attr);
}
};
@@ -145,21 +145,21 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<long_long_type, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, long_long_type& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, long_long, attr);
+ qi::parse(first_, last, long_long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<ulong_long_type, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, ulong_long_type& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, ulong_long, attr);
+ qi::parse(first_, last, ulong_long_type(), attr);
}
};
#endif
@@ -167,33 +167,33 @@
template <typename Iterator>
struct assign_to_attribute_from_iterators<float, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, float& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, float_, attr);
+ qi::parse(first_, last, float_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<double, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, double& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, double_, attr);
+ qi::parse(first_, last, double_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long double, Iterator>
{
- static void
+ static void
call(Iterator const& first, Iterator const& last, long double& attr)
{
Iterator first_ = first;
- qi::parse(first_, last, long_double, attr);
+ qi::parse(first_, last, long_double_type(), attr);
}
};
Modified: branches/release/boost/spirit/home/qi/detail/pass_container.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/pass_container.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/pass_container.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,43 +18,223 @@
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
- // has_same_elements: utility to check if the RHS attribute
- // is an STL container and that its value_type is convertible
- // to the LHS.
-
- template <typename LHS, typename RHSAttribute
- , bool IsContainer = traits::is_container<RHSAttribute>::value>
- struct has_same_elements : mpl::false_ {};
-
- template <typename LHS, typename RHSAttribute>
- struct has_same_elements<LHS, RHSAttribute, true>
- : is_convertible<typename RHSAttribute::value_type, LHS> {};
-
- template <typename LHS, typename T>
- struct has_same_elements<LHS, optional<T>, true>
- : has_same_elements<LHS, T> {};
+ // Helper meta-function allowing to evaluate weak substitutability and
+ // negate the result if the predicate (Sequence) is not true
+ template <typename Sequence, typename Attribute, typename ValueType>
+ struct negate_weak_substitute_if_not
+ : mpl::if_<
+ Sequence
+ , typename traits::is_weak_substitute<Attribute, ValueType>::type
+ , typename mpl::not_<
+ traits::is_weak_substitute<Attribute, ValueType>
+ >::type>
+ {};
+
+ // pass_through_container: utility to check decide whether a provided
+ // container attribute needs to be passed through to the current component
+ // or of we need to split the container by passing along instances of its
+ // value type
+
+ // if the expected attribute of the current component is neither a Fusion
+ // sequence nor a container, we will pass through the provided container
+ // only if its value type is not compatible with the component
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename Enable = void>
+ struct pass_through_container_base
+ : negate_weak_substitute_if_not<Sequence, Attribute, ValueType>
+ {};
+
+ // Specialization for fusion sequences, in this case we check whether all
+ // the types in the sequence are convertible to the lhs attribute.
+ //
+ // We return false if the rhs attribute itself is a fusion sequence, which
+ // is compatible with the LHS sequence (we want to pass through this
+ // attribute without it being split apart).
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence = mpl::true_>
+ struct not_compatible_element
+ : mpl::and_<
+ negate_weak_substitute_if_not<Sequence, Attribute, Container>
+ , negate_weak_substitute_if_not<Sequence, Attribute, ValueType> >
+ {};
+
+ // If the value type of the container is not a Fusion sequence, we pass
+ // through the container if each of the elements of the Attribute
+ // sequence is compatible with either the container or its value type.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence
+ , bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
+ struct pass_through_container_fusion_sequence
+ {
+ typedef typename mpl::find_if<
+ Attribute, not_compatible_element<Container, ValueType, mpl::_1>
+ >::type iter;
+ typedef typename mpl::end<Attribute>::type end;
+
+ typedef typename is_same<iter, end>::type type;
+ };
+
+ // If both, the Attribute and the value type of the provided container
+ // are Fusion sequences, we pass the container only if the two
+ // sequences are not compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence, true>
+ {
+ typedef typename mpl::find_if<
+ Attribute
+ , not_compatible_element<Container, ValueType, mpl::_1, Sequence>
+ >::type iter;
+ typedef typename mpl::end<Attribute>::type end;
+
+ typedef typename is_same<iter, end>::type type;
+ };
-#define BOOST_SPIRIT_IS_CONVERTIBLE(z, N, data) \
- has_same_elements<LHS, BOOST_PP_CAT(T, N)>::value || \
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_base<Container, ValueType, Attribute
+ , Sequence
+ , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence>
+ {};
+
+ // Specialization for containers
+ //
+ // If the value type of the attribute of the current component is not
+ // a Fusion sequence, we have to pass through the provided container if
+ // both are compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename AttributeValueType
+ , bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
+ struct pass_through_container_container
+ : mpl::or_<
+ traits::is_weak_substitute<Attribute, Container>
+ , traits::is_weak_substitute<AttributeValueType, Container> >
+ {};
+
+ // If the value type of the exposed container attribute is a Fusion
+ // sequence, we use the already existing logic for those.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence, typename AttributeValueType>
+ struct pass_through_container_container<
+ Container, ValueType, Attribute, Sequence, AttributeValueType, true>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, AttributeValueType, Sequence>
+ {};
+
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_base<
+ Container, ValueType, Attribute, Sequence
+ , typename enable_if<traits::is_container<Attribute> >::type>
+ : detail::pass_through_container_container<
+ Container, ValueType, Attribute, Sequence
+ , typename traits::container_value<Attribute>::type>
+ {};
+
+ // Specialization for exposed optional attributes
+ //
+ // If the type embedded in the exposed optional is not a Fusion
+ // sequence we pass through the container attribute if it is compatible
+ // either to the optionals embedded type or to the containers value
+ // type.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence
+ , bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
+ struct pass_through_container_optional
+ : mpl::or_<
+ traits::is_weak_substitute<Attribute, Container>
+ , traits::is_weak_substitute<Attribute, ValueType> >
+ {};
+
+ // If the embedded type of the exposed optional attribute is a Fusion
+ // sequence, we use the already existing logic for those.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container_optional<
+ Container, ValueType, Attribute, Sequence, true>
+ : pass_through_container_fusion_sequence<
+ Container, ValueType, Attribute, Sequence>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container
+ : pass_through_container_base<Container, ValueType, Attribute, Sequence>
+ {};
+
+ // Handle optional attributes
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, ValueType, boost::optional<Attribute>, Sequence>
+ : pass_through_container_optional<
+ Container, ValueType, Attribute, Sequence>
+ {};
+
+ // If both, the containers value type and the exposed attribute type are
+ // optionals we are allowed to pass through the the container only if the
+ // embedded types of those optionals are not compatible.
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, boost::optional<ValueType>, boost::optional<Attribute>
+ , Sequence>
+ : mpl::not_<traits::is_weak_substitute<Attribute, ValueType> >
+ {};
+
+ // Specialization for exposed variant attributes
+ //
+ // We pass through the container attribute if at least one of the embedded
+ // types in the variant requires to pass through the attribute
+
+#define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \
+ pass_through_container<Container, ValueType, \
+ BOOST_PP_CAT(T, N), Sequence>::type::value || \
/***/
- // Note: variants are treated as containers if one of the held types is a
- // container (see support/container.hpp).
- template <typename LHS, BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct has_same_elements<
- LHS, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, true>
+ template <typename Container, typename ValueType, typename Sequence
+ , BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct pass_through_container<Container, ValueType
+ , boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
- , BOOST_SPIRIT_IS_CONVERTIBLE, _) false> {};
+ , BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
+ {};
-#undef BOOST_SPIRIT_IS_CONVERTIBLE
+#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
+}}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // forwarding customization point for domain qi::domain
+ template <typename Container, typename ValueType, typename Attribute
+ , typename Sequence>
+ struct pass_through_container<
+ Container, ValueType, Attribute, Sequence, qi::domain>
+ : qi::detail::pass_through_container<
+ Container, ValueType, Attribute, Sequence>
+ {};
+}}}
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+ ///////////////////////////////////////////////////////////////////////////
// This function handles the case where the attribute (Attr) given
// the sequence is an STL container. This is a wrapper around F.
// The function F does the actual parsing.
- template <typename F, typename Attr>
+ template <typename F, typename Attr, typename Sequence>
struct pass_container
{
typedef typename F::context_type context_type;
@@ -66,7 +246,7 @@
// this is for the case when the current element exposes an attribute
// which is pushed back onto the container
template <typename Component>
- bool dispatch_attribute_element(Component const& component, mpl::false_) const
+ bool dispatch_container(Component const& component, mpl::false_) const
{
// synthesized attribute needs to be default constructed
typename traits::container_value<Attr>::type val =
@@ -84,34 +264,16 @@
return r;
}
- // this is for the case when the current element expects an attribute
- // which is a container itself, this element will push its data
- // directly into the attribute container
+ // this is for the case when the current element is able to handle an
+ // attribute which is a container itself, this element will push its
+ // data directly into the attribute container
template <typename Component>
- bool dispatch_attribute_element(Component const& component, mpl::true_) const
+ bool dispatch_container(Component const& component, mpl::true_) const
{
return f(component, attr);
}
- // This handles the distinction between elements in a sequence expecting
- // containers themselves and elements expecting non-containers as their
- // attribute. Note: is_container treats optional<T>, where T is a
- // container as a container as well.
- template <typename Component>
- bool dispatch_attribute(Component const& component, mpl::true_) const
- {
- typedef typename traits::attribute_of<
- Component, context_type, iterator_type>::type attribute_type;
-
- typedef mpl::and_<
- traits::is_container<attribute_type>
- , traits::handles_container<Component, Attr, context_type
- , iterator_type>
- > predicate;
-
- return dispatch_attribute_element(component, predicate());
- }
-
+ ///////////////////////////////////////////////////////////////////////
// this is for the case when the current element doesn't expect an
// attribute
template <typename Component>
@@ -120,31 +282,26 @@
return f(component, unused);
}
- // This handles the case where the attribute of the component
- // is not an STL container or its element is not convertible
- // to the target attribute's (Attr) value_type.
+ // the current element expects an attribute
template <typename Component>
- bool dispatch_main(Component const& component, mpl::false_) const
+ bool dispatch_attribute(Component const& component, mpl::true_) const
{
- // we need to dispatch again depending on the type of the attribute
- // of the current element (component). If this is has no attribute
- // we shouldn't push an element into the container.
- typedef traits::not_is_unused<
- typename traits::attribute_of<
- Component, context_type, iterator_type
- >::type
- > predicate;
+ typedef typename traits::container_value<Attr>::type value_type;
+ typedef typename traits::attribute_of<
+ Component, context_type, iterator_type>::type
+ rhs_attribute;
- return dispatch_attribute(component, predicate());
- }
+ // this predicate detects, whether the attribute of the current
+ // element is a substitute for the value type of the container
+ // attribute
+ typedef mpl::and_<
+ traits::handles_container<
+ Component, Attr, context_type, iterator_type>
+ , traits::pass_through_container<
+ Attr, value_type, rhs_attribute, Sequence, qi::domain>
+ > predicate;
- // This handles the case where the attribute of the component is
- // an STL container *and* its value_type is convertible to the
- // target attribute's (Attr) value_type.
- template <typename Component>
- bool dispatch_main(Component const& component, mpl::true_) const
- {
- return f(component, attr);
+ return dispatch_container(component, predicate());
}
// Dispatches to dispatch_main depending on the attribute type
@@ -152,18 +309,19 @@
template <typename Component>
bool operator()(Component const& component) const
{
- typedef typename traits::container_value<Attr>::type lhs;
- typedef typename traits::attribute_of<
- Component, context_type, iterator_type>::type
- rhs_attribute;
+ // we need to dispatch depending on the type of the attribute
+ // of the current element (component). If this is has no attribute
+ // we shouldn't pass an attribute at all.
+ typedef typename traits::not_is_unused<
+ typename traits::attribute_of<
+ Component, context_type, iterator_type
+ >::type
+ >::type predicate;
- typedef mpl::and_<
- has_same_elements<lhs, rhs_attribute>
- , traits::handles_container<Component, Attr, context_type
- , iterator_type>
- > predicate;
+ // ensure the attribute is actually a container type
+ traits::make_container(attr);
- return dispatch_main(component, predicate());
+ return dispatch_attribute(component, predicate());
}
F f;
@@ -174,12 +332,22 @@
pass_container& operator= (pass_container const&);
};
- // Utility function to make a pass_container
+ ///////////////////////////////////////////////////////////////////////////
+ // Utility function to make a pass_container for container components
+ // (kleene, list, plus, repeat)
+ template <typename F, typename Attr>
+ inline pass_container<F, Attr, mpl::false_>
+ make_pass_container(F const& f, Attr& attr)
+ {
+ return pass_container<F, Attr, mpl::false_>(f, attr);
+ }
+
+ // Utility function to make a pass_container for sequences
template <typename F, typename Attr>
- pass_container<F, Attr>
- inline make_pass_container(F const& f, Attr& attr)
+ inline pass_container<F, Attr, mpl::true_>
+ make_sequence_pass_container(F const& f, Attr& attr)
{
- return pass_container<F, Attr>(f, attr);
+ return pass_container<F, Attr, mpl::true_>(f, attr);
}
}}}}
Modified: branches/release/boost/spirit/home/qi/directive/as.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/as.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/as.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -34,10 +34,10 @@
struct as
: stateful_tag_type<T, tag::as>
{
- BOOST_SPIRIT_ASSERT_MSG(
- (traits::is_container<T>::type::value),
- error_type_must_be_a_container,
- (T));
+ //~ BOOST_SPIRIT_ASSERT_MSG(
+ //~ (traits::is_container<T>::type::value),
+ //~ error_type_must_be_a_container,
+ //~ (T));
};
}}}
@@ -48,26 +48,28 @@
///////////////////////////////////////////////////////////////////////////
// enables as_string[...]
template <>
- struct use_directive<qi::domain, tag::as_string>
+ struct use_directive<qi::domain, tag::as_string>
: mpl::true_ {};
// enables as_wstring[...]
template <>
- struct use_directive<qi::domain, tag::as_wstring>
+ struct use_directive<qi::domain, tag::as_wstring>
: mpl::true_ {};
// enables as<T>[...]
template <typename T>
- struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
- : mpl::true_
+ struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
+ : mpl::true_
{};
}}
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::as_string;
- using spirit::as_string_type;
using spirit::as_wstring;
+#endif
+ using spirit::as_string_type;
using spirit::as_wstring_type;
template <typename Subject, typename T>
@@ -99,6 +101,19 @@
return false;
}
+ template <typename Iterator, typename Context, typename Skipper>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper, T& attr) const
+ {
+ Iterator i = first;
+ if (subject.parse(i, last, context, skipper, attr))
+ {
+ first = i;
+ return true;
+ }
+ return false;
+ }
+
template <typename Context>
info what(Context& context) const
{
@@ -132,7 +147,7 @@
return result_type(subject);
}
};
-
+
template <typename T, typename Subject, typename Modifiers>
struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
{
@@ -157,7 +172,7 @@
, typename Context, typename Iterator>
struct handles_container<qi::as_directive<Subject, T>, Attribute
, Context, Iterator>
- : mpl::false_ {};
+ : mpl::false_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/directive/hold.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/hold.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/hold.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -33,7 +33,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::hold;
+#endif
using spirit::hold_type;
template <typename Subject>
Modified: branches/release/boost/spirit/home/qi/directive/lexeme.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/lexeme.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/lexeme.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -33,7 +33,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lexeme;
+#endif
using spirit::lexeme_type;
template <typename Subject>
Modified: branches/release/boost/spirit/home/qi/directive/matches.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/matches.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/matches.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -32,7 +32,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::matches;
+#endif
using spirit::matches_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/qi/directive/no_skip.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/no_skip.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/no_skip.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -35,7 +35,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::no_skip;
+#endif
using spirit::no_skip_type;
// same as lexeme[], but does not pre-skip
Modified: branches/release/boost/spirit/home/qi/directive/omit.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/omit.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/omit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -32,7 +32,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::omit;
+#endif
using spirit::omit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/qi/directive/raw.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/raw.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/raw.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -35,7 +35,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::raw;
+#endif
using spirit::raw_type;
template <typename Subject>
Modified: branches/release/boost/spirit/home/qi/directive/repeat.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/repeat.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/repeat.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -18,11 +19,12 @@
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/fusion/include/at.hpp>
-#include <boost/foreach.hpp>
#include <vector>
namespace boost { namespace spirit
@@ -69,9 +71,11 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::repeat;
- using spirit::repeat_type;
using spirit::inf;
+#endif
+ using spirit::repeat_type;
using spirit::inf_type;
template <typename T>
@@ -152,57 +156,26 @@
repeat_parser(Subject const& subject, LoopIter const& iter)
: subject(subject), iter(iter) {}
- template <typename Iterator, typename Context
- , typename Skipper, typename ValueType, typename Attribute
- , typename LoopVar>
- bool parse_minimal(Iterator &first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr, ValueType& val, LoopVar& i) const
+ template <typename F>
+ bool parse_container(F f) const
{
- // this scope allows save and required_attr to be reclaimed
- // immediately after we're done with the required minimum
- // iteration.
- Iterator save = first;
- std::vector<ValueType> required_attr;
- for (; !iter.got_min(i); ++i)
+ typename LoopIter::type i = iter.start();
+ for (/**/; !iter.got_min(i); ++i)
{
- if (!subject.parse(save, last, context, skipper, val) ||
- !traits::push_back(required_attr, val))
- {
+ if (f (subject))
return false;
- }
-
- first = save;
- traits::clear(val);
}
- // if we got the required number of items, these are copied
- // over (appended) to the 'real' attribute
- BOOST_FOREACH(ValueType const& v, required_attr)
+ // parse some more up to the maximum specified
+ typename F::iterator_type save = f.f.first;
+ for (/**/; !iter.got_max(i); ++i)
{
- traits::push_back(attr, v);
+ if (f (subject))
+ break;
+ save = f.f.first;
}
- return true;
- }
- template <typename Iterator, typename Context
- , typename Skipper, typename LoopVar>
- bool parse_minimal(Iterator &first, Iterator const& last
- , Context& context, Skipper const& skipper
- , unused_type, unused_type, LoopVar& i) const
- {
- // this scope allows save and required_attr to be reclaimed
- // immediately after we're done with the required minimum
- // iteration.
- Iterator save = first;
- for (; !iter.got_min(i); ++i)
- {
- if (!subject.parse(save, last, context, skipper, unused))
- {
- return false;
- }
- first = save;
- }
+ f.f.first = save;
return true;
}
@@ -212,35 +185,18 @@
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
- // create a local value if Attribute is not unused_type
- typedef typename traits::container_value<Attribute>::type
- value_type;
- value_type val = value_type();
- typename LoopIter::type i = iter.start();
+ typedef detail::fail_function<Iterator, Context, Skipper>
+ fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr);
- // parse the minimum required
- Iterator save = first;
- if (!iter.got_min(i) &&
- !parse_minimal(save, last, context, skipper, attr, val, i))
- {
+ Iterator iter = first;
+ fail_function f(iter, last, context, skipper);
+ if (!parse_container(detail::make_pass_container(f, attr)))
return false;
- }
-
- // parse some more up to the maximum specified
- for (/**/; !iter.got_max(i); ++i) {
- if (!subject.parse(save, last, context, skipper, val) ||
- !traits::push_back(attr, val))
- {
- break;
- }
- first = save;
- traits::clear(val);
- }
- first = save;
+ first = f.first;
return true;
}
@@ -334,7 +290,7 @@
template <typename Subject, typename LoopIter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::repeat_parser<Subject, LoopIter>
- , Attribute, Context, Iterator>
+ , Attribute, Context, Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/qi/directive/skip.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/directive/skip.hpp (original)
+++ branches/release/boost/spirit/home/qi/directive/skip.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -52,7 +52,9 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::skip;
+#endif
using spirit::skip_type;
template <typename Subject>
Modified: branches/release/boost/spirit/home/qi/domain.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/domain.hpp (original)
+++ branches/release/boost/spirit/home/qi/domain.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -38,6 +38,21 @@
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
+ using spirit::_pass_type;
+ using spirit::_val_type;
+ using spirit::_a_type;
+ using spirit::_b_type;
+ using spirit::_c_type;
+ using spirit::_d_type;
+ using spirit::_e_type;
+ using spirit::_f_type;
+ using spirit::_g_type;
+ using spirit::_h_type;
+ using spirit::_i_type;
+ using spirit::_j_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
using spirit::_pass;
using spirit::_val;
using spirit::_a;
@@ -50,7 +65,10 @@
using spirit::_h;
using spirit::_i;
using spirit::_j;
+
+#endif
}
+
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/nonterminal.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/nonterminal.hpp (original)
+++ branches/release/boost/spirit/home/qi/nonterminal.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -16,5 +16,6 @@
#include <boost/spirit/home/qi/nonterminal/error_handler.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler.hpp>
#include <boost/spirit/home/qi/nonterminal/simple_trace.hpp>
+#include <boost/spirit/home/qi/nonterminal/success_handler.hpp>
#endif
Modified: branches/release/boost/spirit/home/qi/nonterminal/debug_handler.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/nonterminal/debug_handler.hpp (original)
+++ branches/release/boost/spirit/home/qi/nonterminal/debug_handler.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -90,7 +90,7 @@
struct simple_trace;
- namespace detail
+ namespace detail
{
// This class provides an extra level of indirection through a
// template to produce the simple_trace type. This way, the use
@@ -98,7 +98,7 @@
// that compilers eagerly type-checking template definitions
// won't complain that simple_trace is incomplete.
template<typename T>
- struct get_simple_trace
+ struct get_simple_trace
{
typedef simple_trace type;
};
@@ -130,8 +130,16 @@
#if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
#else
- #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r);
+ #define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
#endif
#endif
+#define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
+ BOOST_SPIRIT_DEBUG_NODE(name); \
+ /***/
+
+#define BOOST_SPIRIT_DEBUG_NODES(seq) \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
+ /***/
+
#endif
Modified: branches/release/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp (original)
+++ branches/release/boost/spirit/home/qi/nonterminal/detail/parameterized.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,6 +14,7 @@
#include <boost/ref.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/qi/parser.hpp>
namespace boost { namespace spirit { namespace qi
@@ -59,4 +60,16 @@
};
}}}
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Params, typename Attribute
+ , typename Context, typename Iterator>
+ struct handles_container<qi::parameterized_nonterminal<Subject, Params>
+ , Attribute, Context, Iterator>
+ : handles_container<typename remove_const<Subject>::type
+ , Attribute, Context, Iterator>
+ {};
+}}}
+
#endif
Modified: branches/release/boost/spirit/home/qi/nonterminal/rule.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/nonterminal/rule.hpp (original)
+++ branches/release/boost/spirit/home/qi/nonterminal/rule.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -47,6 +47,21 @@
{
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
+ using spirit::_pass_type;
+ using spirit::_val_type;
+ using spirit::_a_type;
+ using spirit::_b_type;
+ using spirit::_c_type;
+ using spirit::_d_type;
+ using spirit::_e_type;
+ using spirit::_f_type;
+ using spirit::_g_type;
+ using spirit::_h_type;
+ using spirit::_i_type;
+ using spirit::_j_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
using spirit::_pass;
using spirit::_val;
using spirit::_a;
@@ -60,6 +75,8 @@
using spirit::_i;
using spirit::_j;
+#endif
+
using spirit::info;
using spirit::locals;
@@ -224,7 +241,7 @@
}
#else
// both friend functions have to be defined out of class as VC7.1
- // will complain otherwise
+ // will complain otherwise
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
@@ -259,7 +276,7 @@
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, domain>
+ typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
@@ -271,7 +288,7 @@
context_type context(attr_);
// If you are seeing a compilation error here stating that the
- // forth parameter can't be converted to a required target type
+ // fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
@@ -305,7 +322,7 @@
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, domain>
+ typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
@@ -317,7 +334,7 @@
context_type context(attr_, params, caller_context);
// If you are seeing a compilation error here stating that the
- // forth parameter can't be converted to a required target type
+ // fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
@@ -371,7 +388,7 @@
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
- typedef typename
+ typedef typename
rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
encoding_modifier_type;
Modified: branches/release/boost/spirit/home/qi/nonterminal/simple_trace.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/nonterminal/simple_trace.hpp (original)
+++ branches/release/boost/spirit/home/qi/nonterminal/simple_trace.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -66,7 +66,7 @@
template <typename Iterator>
void print_some(
char const* tag
- , int indent
+ , int /*indent*/
, Iterator first, Iterator const& last) const
{
print_indent(get_indent());
Modified: branches/release/boost/spirit/home/qi/numeric/bool.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/bool.hpp (original)
+++ branches/release/boost/spirit/home/qi/numeric/bool.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -32,7 +32,7 @@
struct bool_policies;
///////////////////////////////////////////////////////////////////////
- // This is the class that the user can instantiate directly in
+ // This is the class that the user can instantiate directly in
// order to create a customized bool parser
template <typename T, typename BoolPolicies = bool_policies<T> >
struct bool_parser
@@ -64,7 +64,7 @@
///////////////////////////////////////////////////////////////////////////
template <typename A0> // enables lit(...)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, bool> >::type>
: mpl::true_ {};
@@ -75,7 +75,7 @@
> : mpl::true_ {};
template <> // enables *lazy* bool_(...)
- struct use_lazy_terminal<qi::domain, tag::bool_, 1>
+ struct use_lazy_terminal<qi::domain, tag::bool_, 1>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
@@ -103,14 +103,15 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::bool_;
- using spirit::bool__type;
using spirit::true_;
- using spirit::true__type;
using spirit::false_;
- using spirit::false__type;
-
using spirit::lit; // lit(true) is equivalent to true
+#endif
+ using spirit::bool_type;
+ using spirit::true_type;
+ using spirit::false_type;
using spirit::lit_type;
namespace detail
@@ -121,7 +122,7 @@
template <typename Iterator, typename Attribute>
static bool parse(Iterator& first, Iterator const& last
, Attribute& attr, BoolPolicies const& p, bool allow_true = true
- , bool disallow_false = false)
+ , bool disallow_false = false)
{
if (first == last)
return false;
@@ -214,7 +215,7 @@
no_case
, is_same<bool_policies<T>, Policies>
>
- , any_bool_parser<T, no_case_bool_policies<T> >
+ , any_bool_parser<T, no_case_bool_policies<T> >
, any_bool_parser<T, Policies> >::type
result_type;
@@ -236,7 +237,7 @@
no_case
, is_same<bool_policies<T>, Policies>
>
- , literal_bool_parser<T, no_case_bool_policies<T>, false>
+ , literal_bool_parser<T, no_case_bool_policies<T>, false>
, literal_bool_parser<T, Policies, false> >::type
result_type;
@@ -247,7 +248,7 @@
}
};
- template <typename T, typename Modifiers, bool b
+ template <typename T, typename Modifiers, bool b
, typename Policies = bool_policies<T> >
struct make_predefined_direct_bool
{
@@ -259,7 +260,7 @@
no_case
, is_same<bool_policies<T>, Policies>
>
- , literal_bool_parser<T, no_case_bool_policies<T>, false>
+ , literal_bool_parser<T, no_case_bool_policies<T>, false>
, literal_bool_parser<T, Policies, false> >::type
result_type;
@@ -281,7 +282,7 @@
no_case
, is_same<bool_policies<T>, Policies>
>
- , literal_bool_parser<T, no_case_bool_policies<T> >
+ , literal_bool_parser<T, no_case_bool_policies<T> >
, literal_bool_parser<T, Policies> >::type
result_type;
@@ -313,7 +314,7 @@
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Policies, typename Modifiers>
struct make_primitive<
- tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
+ tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
: make_bool<T, Modifiers, Policies> {};
template <typename T, typename Policies, typename A0, typename Modifiers>
Modified: branches/release/boost/spirit/home/qi/numeric/int.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/int.hpp (original)
+++ branches/release/boost/spirit/home/qi/numeric/int.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -27,19 +27,19 @@
namespace tag
{
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct int_parser {};
}
namespace qi
{
///////////////////////////////////////////////////////////////////////
- // This one is the class that the user can instantiate directly in
+ // This one is the class that the user can instantiate directly in
// order to create a customized int parser
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
, int MaxDigits = -1>
struct int_parser
- : spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
+ : spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
{};
}
@@ -53,10 +53,10 @@
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, signed short> >::type>
: mpl::true_ {};
-
+
template <typename A0> // enables short_(n)
struct use_terminal<qi::domain
, terminal_ex<tag::short_, fusion::vector1<A0> > >
@@ -69,11 +69,11 @@
//[primitive_parsers_enable_int
template <> // enables int_
struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
- //]
+ //]
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, signed> >::type>
: mpl::true_ {};
@@ -84,16 +84,16 @@
template <> // enables *lazy* int_(n)
struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
-
+
///////////////////////////////////////////////////////////////////////////
//[primitive_parsers_enable_long
template <> // enables long_
struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
- //]
-
+ //]
+
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, signed long> >::type>
: mpl::true_ {};
@@ -104,7 +104,7 @@
template <> // enables *lazy* long_(n)
struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
-
+
///////////////////////////////////////////////////////////////////////////
#ifdef BOOST_HAS_LONG_LONG
//[primitive_parsers_enable_long_long
@@ -114,7 +114,7 @@
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, boost::long_long_type> >::type>
: mpl::true_ {};
@@ -130,14 +130,14 @@
///////////////////////////////////////////////////////////////////////////
// enables any custom int_parser
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct use_terminal<qi::domain
, tag::int_parser<T, Radix, MinDigits, MaxDigits> >
: mpl::true_ {};
// enables any custom int_parser(n)
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits, typename A0>
+ , int MaxDigits, typename A0>
struct use_terminal<qi::domain
, terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
, fusion::vector1<A0> >
@@ -145,7 +145,7 @@
// enables *lazy* custom int_parser(n)
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct use_lazy_terminal<qi::domain
, tag::int_parser<T, Radix, MinDigits, MaxDigits>, 1
> : mpl::true_ {};
@@ -153,18 +153,22 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::short_;
- using spirit::short__type;
using spirit::int_;
- using spirit::int__type;
using spirit::long_;
- using spirit::long__type;
#ifdef BOOST_HAS_LONG_LONG
using spirit::long_long;
- using spirit::long_long_type;
#endif
-
using spirit::lit; // lit(1) is equivalent to 1
+#endif
+ using spirit::short_type;
+ using spirit::int_type;
+ using spirit::long_type;
+ using spirit::lit_type;
+#ifdef BOOST_HAS_LONG_LONG
+ using spirit::long_long_type;
+#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
@@ -236,7 +240,8 @@
{
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
qi::skip_over(first, last, skipper);
-
+
+ Iterator save = first;
T attr_;
if (extract::call(first, last, attr_) && (attr_ == n_))
@@ -245,6 +250,7 @@
return true;
}
+ first = save;
return false;
}
@@ -275,7 +281,7 @@
}
};
//]
-
+
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
, int MaxDigits = -1>
struct make_direct_int
@@ -288,7 +294,7 @@
return result_type(fusion::at_c<0>(term.args));
}
};
-
+
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
, int MaxDigits = -1>
struct make_literal_int
@@ -300,7 +306,7 @@
return result_type(fusion::at_c<0>(term.args));
}
};
-
+
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers, typename A0>
struct make_primitive<
@@ -384,7 +390,7 @@
///////////////////////////////////////////////////////////////////////////
#ifdef BOOST_HAS_LONG_LONG
- //[primitive_parsers_long_long_primitive
+ //[primitive_parsers_long_long_primitive
template <typename Modifiers>
struct make_primitive<tag::long_long, Modifiers>
: make_int<boost::long_long_type> {};
Modified: branches/release/boost/spirit/home/qi/numeric/real.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/real.hpp (original)
+++ branches/release/boost/spirit/home/qi/numeric/real.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -32,11 +32,11 @@
struct real_policies;
///////////////////////////////////////////////////////////////////////
- // This is the class that the user can instantiate directly in
+ // This is the class that the user can instantiate directly in
// order to create a customized real parser
template <typename T = double, typename Policies = real_policies<T> >
struct real_parser
- : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
+ : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
{
typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
@@ -64,19 +64,19 @@
///////////////////////////////////////////////////////////////////////////
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, float> >::type>
: mpl::true_ {};
-
+
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, double> >::type>
: mpl::true_ {};
-
+
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, long double> >::type>
: mpl::true_ {};
@@ -97,15 +97,15 @@
> : mpl::true_ {};
template <> // enables *lazy* float_(...)
- struct use_lazy_terminal<qi::domain, tag::float_, 1>
+ struct use_lazy_terminal<qi::domain, tag::float_, 1>
: mpl::true_ {};
template <> // enables *lazy* double_(...)
- struct use_lazy_terminal<qi::domain, tag::double_, 1>
+ struct use_lazy_terminal<qi::domain, tag::double_, 1>
: mpl::true_ {};
- template <> // enables *lazy* double_(...)
- struct use_lazy_terminal<qi::domain, tag::long_double, 1>
+ template <> // enables *lazy* long_double_(...)
+ struct use_lazy_terminal<qi::domain, tag::long_double, 1>
: mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
@@ -133,14 +133,17 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::float_;
- using spirit::float__type;
using spirit::double_;
- using spirit::double__type;
using spirit::long_double;
- using spirit::long_double_type;
-
using spirit::lit; // lit(1.0) is equivalent to 1.0
+#endif
+
+ using spirit::float_type;
+ using spirit::double_type;
+ using spirit::long_double_type;
+ using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// This is the actual real number parser
@@ -210,6 +213,7 @@
typedef detail::real_impl<T, RealPolicies> extract;
qi::skip_over(first, last, skipper);
+ Iterator save = first;
T attr_;
if (extract::parse(first, last, attr_, RealPolicies()) &&
@@ -219,6 +223,7 @@
return true;
}
+ first = save;
return false;
}
@@ -275,7 +280,7 @@
terminal_ex<tag::lit, fusion::vector1<A0> >
, Modifiers, typename enable_if<is_same<A0, float> >::type>
: make_literal_real<float> {};
-
+
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<tag::lit, fusion::vector1<A0> >
@@ -291,7 +296,7 @@
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Policies, typename Modifiers>
struct make_primitive<
- tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
+ tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
: make_real<T, Policies> {};
template <typename T, typename Policies, typename A0, typename Modifiers>
Modified: branches/release/boost/spirit/home/qi/numeric/uint.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/uint.hpp (original)
+++ branches/release/boost/spirit/home/qi/numeric/uint.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -27,19 +27,19 @@
namespace tag
{
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct uint_parser {};
}
namespace qi
{
///////////////////////////////////////////////////////////////////////
- // This one is the class that the user can instantiate directly in
+ // This one is the class that the user can instantiate directly in
// order to create a customized int parser
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
, int MaxDigits = -1>
struct uint_parser
- : spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
+ : spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
{};
}
@@ -51,7 +51,7 @@
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, unsigned short> >::type>
: mpl::true_ {};
@@ -69,7 +69,7 @@
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, unsigned> >::type>
: mpl::true_ {};
@@ -80,14 +80,14 @@
template <> // enables *lazy* uint_(n)
struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
-
+
///////////////////////////////////////////////////////////////////////////
template <> // enables ulong_
struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, unsigned long> >::type>
: mpl::true_ {};
@@ -106,7 +106,7 @@
template <typename A0> // enables lit(n)
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
: mpl::true_ {};
@@ -158,14 +158,14 @@
///////////////////////////////////////////////////////////////////////////
// enables any custom uint_parser
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct use_terminal<qi::domain
, tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
: mpl::true_ {};
// enables any custom uint_parser(n)
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits, typename A0>
+ , int MaxDigits, typename A0>
struct use_terminal<qi::domain
, terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
, fusion::vector1<A0> >
@@ -173,7 +173,7 @@
// enables *lazy* custom uint_parser(n)
template <typename T, unsigned Radix, unsigned MinDigits
- , int MaxDigits>
+ , int MaxDigits>
struct use_lazy_terminal<qi::domain
, tag::uint_parser<T, Radix, MinDigits, MaxDigits>, 1
> : mpl::true_ {};
@@ -181,22 +181,31 @@
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::bin;
using spirit::oct;
using spirit::hex;
using spirit::ushort_;
- using spirit::ushort__type;
using spirit::uint_;
- using spirit::uint__type;
using spirit::ulong_;
- using spirit::ulong__type;
#ifdef BOOST_HAS_LONG_LONG
using spirit::ulong_long;
- using spirit::ulong_long_type;
#endif
-
using spirit::lit; // lit(1) is equivalent to 1
+#endif
+
+ using spirit::bin_type;
+ using spirit::oct_type;
+ using spirit::hex_type;
+
+ using spirit::ushort_type;
+ using spirit::uint_type;
+ using spirit::ulong_type;
+#ifdef BOOST_HAS_LONG_LONG
+ using spirit::ulong_long_type;
+#endif
+ using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
// This is the actual uint parser
@@ -263,7 +272,8 @@
{
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
qi::skip_over(first, last, skipper);
-
+
+ Iterator save = first;
T attr_;
if (extract::call(first, last, attr_) && (attr_ == n_))
@@ -272,6 +282,7 @@
return true;
}
+ first = save;
return false;
}
@@ -357,7 +368,7 @@
tag::uint_parser<T, Radix, MinDigits, MaxDigits>
, Modifiers>
: make_uint<T, Radix, MinDigits, MaxDigits> {};
-
+
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename A0, typename Modifiers>
struct make_primitive<
Modified: branches/release/boost/spirit/home/qi/operator/expect.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/expect.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/expect.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -95,8 +96,8 @@
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::expect<Elements>, Attribute, Context
- , Iterator>
- : nary_handles_container<Elements, Attribute, Context, Iterator> {};
+ , Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/operator/kleene.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/kleene.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/kleene.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -15,6 +16,8 @@
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
@@ -33,7 +36,6 @@
namespace boost { namespace spirit { namespace qi
{
-
//[composite_parsers_kleene
template <typename Subject>
struct kleene : unary_parser<kleene<Subject> >
@@ -57,28 +59,31 @@
kleene(Subject const& subject)
: subject(subject) {}
+ template <typename F>
+ bool parse_container(F f) const
+ {
+ while (!f (subject))
+ ;
+ return true;
+ }
+
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
- // create a local value if Attribute is not unused_type
- typedef typename traits::container_value<Attribute>::type
- value_type;
- value_type val = value_type();
-
// ensure the attribute is actually a container type
traits::make_container(attr);
- // Repeat while subject parses ok
- Iterator save = first;
- while (subject.parse(save, last, context, skipper, val) &&
- traits::push_back(attr, val)) // push the parsed value into our attribute
- {
- first = save;
- traits::clear(val);
- }
+ typedef detail::fail_function<Iterator, Context, Skipper>
+ fail_function;
+
+ Iterator iter = first;
+ fail_function f(iter, last, context, skipper);
+ parse_container(detail::make_pass_container(f, attr));
+
+ first = f.first;
return true;
}
@@ -120,9 +125,9 @@
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
- , typename Iterator>
+ , typename Iterator>
struct handles_container<qi::kleene<Subject>, Attribute
- , Context, Iterator>
+ , Context, Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/qi/operator/list.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/list.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/list.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -15,6 +16,8 @@
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
@@ -55,36 +58,42 @@
list(Left const& left, Right const& right)
: left(left), right(right) {}
+ template <typename F>
+ bool parse_container(F f) const
+ {
+ // in order to succeed we need to match at least one element
+ if (f (left))
+ return false;
+
+ typename F::iterator_type save = f.f.first;
+ while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
+ && !f (left))
+ {
+ save = f.f.first;
+ }
+
+ f.f.first = save;
+ return true;
+ }
+
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
- // create a local value if Attribute is not unused_type
- typedef typename traits::container_value<Attribute>::type
- value_type;
- value_type val = value_type();
+ typedef detail::fail_function<Iterator, Context, Skipper>
+ fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr);
- Iterator save = first;
- if (!left.parse(save, last, context, skipper, val) ||
- !traits::push_back(attr, val))
- {
+ Iterator iter = first;
+ fail_function f(iter, last, context, skipper);
+ if (!parse_container(detail::make_pass_container(f, attr)))
return false;
- }
- first = save;
- while (right.parse(save, last, context, skipper, unused)
- && (traits::clear(val), true)
- && left.parse(save, last, context, skipper, val))
- {
- if (!traits::push_back(attr, val))
- break;
- first = save;
- }
+ first = f.first;
return true;
}
@@ -119,7 +128,7 @@
template <typename Left, typename Right, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::list<Left, Right>, Attribute, Context
- , Iterator>
+ , Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/qi/operator/optional.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/optional.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/optional.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -16,6 +17,7 @@
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
@@ -58,9 +60,9 @@
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
+ bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
- , Attribute& attr) const
+ , Attribute& attr, mpl::false_) const
{
// create a local value if Attribute is not unused_type
typename spirit::result_of::optional_value<Attribute>::type val;
@@ -73,6 +75,29 @@
return true;
}
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr, mpl::true_) const
+ {
+ subject.parse(first, last, context, skipper, attr);
+ return true;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ typedef typename spirit::result_of::optional_value<Attribute>::type
+ attribute_type;
+
+ return parse_impl(first, last, context, skipper, attr
+ , traits::is_container<attribute_type>());
+ }
+
template <typename Context>
info what(Context& context) const
{
@@ -102,8 +127,8 @@
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::optional<Subject>, Attribute
- , Context, Iterator>
- : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+ , Context, Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/operator/plus.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/plus.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/plus.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -15,6 +16,8 @@
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/qi/detail/fail_function.hpp>
+#include <boost/spirit/home/qi/detail/pass_container.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/support/info.hpp>
@@ -53,37 +56,36 @@
plus(Subject const& subject)
: subject(subject) {}
+ template <typename F>
+ bool parse_container(F f) const
+ {
+ // in order to succeed we need to match at least one element
+ if (f (subject))
+ return false;
+
+ while (!f (subject))
+ ;
+ return true;
+ }
+
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
- // create a local value if Attribute is not unused_type
- typedef typename traits::container_value<Attribute>::type
- value_type;
- value_type val = value_type();
+ typedef detail::fail_function<Iterator, Context, Skipper>
+ fail_function;
// ensure the attribute is actually a container type
traits::make_container(attr);
- Iterator save = first;
- if (!subject.parse(save, last, context, skipper, val) ||
- !traits::push_back(attr, val))
- {
+ Iterator iter = first;
+ fail_function f(iter, last, context, skipper);
+ if (!parse_container(detail::make_pass_container(f, attr)))
return false;
- }
- first = save;
- traits::clear(val);
-
- while (subject.parse(save, last, context, skipper, val))
- {
- if (!traits::push_back(attr, val))
- break;
-
- first = save;
- traits::clear(val);
- }
+
+ first = f.first;
return true;
}
@@ -116,7 +118,7 @@
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::plus<Subject>, Attribute, Context
- , Iterator>
+ , Iterator>
: mpl::true_ {};
}}}
Modified: branches/release/boost/spirit/home/qi/operator/sequence.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/sequence.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/sequence.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -88,8 +89,8 @@
template <typename Elements, typename Attribute, typename Context
, typename Iterator>
struct handles_container<qi::sequence<Elements>, Attribute, Context
- , Iterator>
- : nary_handles_container<Elements, Attribute, Context, Iterator> {};
+ , Iterator>
+ : mpl::true_ {};
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/operator/sequence_base.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/operator/sequence_base.hpp (original)
+++ branches/release/boost/spirit/home/qi/operator/sequence_base.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,5 +1,6 @@
/*=============================================================================
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)
@@ -103,7 +104,7 @@
Iterator iter = first;
// return false if *any* of the parsers fail
if (fusion::any(elements
- , detail::make_pass_container(
+ , detail::make_sequence_pass_container(
Derived::fail_function(iter, last, context, skipper), attr_))
)
return false;
Modified: branches/release/boost/spirit/home/qi/parse.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/parse.hpp (original)
+++ branches/release/boost/spirit/home/qi/parse.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -12,6 +12,8 @@
#pragma once
#endif
+#include <boost/spirit/home/support/context.hpp>
+#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/qi/detail/parse.hpp>
#include <boost/concept_check.hpp>
@@ -42,10 +44,25 @@
, Expr const& expr)
{
Iterator first = first_;
- return parse(first, last, expr);
+ return qi::parse(first, last, expr);
}
///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ struct make_context
+ {
+ typedef context<fusion::cons<T&>, locals<> > type;
+ };
+
+ template <>
+ struct make_context<unused_type>
+ {
+ typedef unused_type type;
+ };
+ }
+
template <typename Iterator, typename Expr, typename Attr>
inline bool
parse(
@@ -65,7 +82,8 @@
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
- return compile<qi::domain>(expr).parse(first, last, unused, unused, attr);
+ typename detail::make_context<Attr>::type context(attr);
+ return compile<qi::domain>(expr).parse(first, last, context, unused, attr);
}
template <typename Iterator, typename Expr, typename Attr>
@@ -77,7 +95,7 @@
, Attr& attr)
{
Iterator first = first_;
- return parse(first, last, expr, attr);
+ return qi::parse(first, last, expr, attr);
}
///////////////////////////////////////////////////////////////////////////
@@ -110,7 +128,7 @@
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
Iterator first = first_;
- return phrase_parse(first, last, expr, skipper, post_skip);
+ return qi::phrase_parse(first, last, expr, skipper, post_skip);
}
///////////////////////////////////////////////////////////////////////////
@@ -142,8 +160,9 @@
skipper_type;
skipper_type const skipper_ = compile<qi::domain>(skipper);
+ typename detail::make_context<Attr>::type context(attr);
if (!compile<qi::domain>(expr).parse(
- first, last, unused, skipper_, attr))
+ first, last, context, skipper_, attr))
return false;
if (post_skip == skip_flag::postskip)
@@ -162,7 +181,7 @@
, Attr& attr)
{
Iterator first = first_;
- return phrase_parse(first, last, expr, skipper, post_skip, attr);
+ return qi::phrase_parse(first, last, expr, skipper, post_skip, attr);
}
///////////////////////////////////////////////////////////////////////////
@@ -175,7 +194,7 @@
, Skipper const& skipper
, Attr& attr)
{
- return phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
+ return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
}
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
@@ -188,9 +207,8 @@
, Attr& attr)
{
Iterator first = first_;
- return phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
+ return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
}
-
}}}
#endif
Modified: branches/release/boost/spirit/home/qi/stream/detail/iterator_source.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/stream/detail/iterator_source.hpp (original)
+++ branches/release/boost/spirit/home/qi/stream/detail/iterator_source.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -24,10 +24,10 @@
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
- typedef boost::iostreams::source_tag category;
+ typedef boost::iostreams::seekable_device_tag category;
- iterator_source (Iterator& first_, Iterator const& last_)
- : first(first_), last(last_)
+ iterator_source (Iterator const& first_, Iterator const& last_)
+ : first(first_), last(last_), pos(0)
{}
// Read up to n characters from the input sequence into the buffer s,
@@ -45,11 +45,30 @@
if (++first == last)
break;
}
+
+ pos += bytes_read;
return bytes_read;
}
- Iterator& first;
+ // Write is implemented only to satisfy the requirements of a
+ // boost::iostreams::seekable_device. We need to have see support to
+ // be able to figure out how many characters have been actually
+ // consumed by the stream.
+ std::streamsize write(const char*, std::streamsize)
+ {
+ BOOST_ASSERT(false); // not supported
+ return -1;
+ }
+
+ std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
+ {
+ BOOST_ASSERT(way == std::ios_base::cur); // only support queries
+ return pos; // return current position
+ }
+
+ Iterator first;
Iterator const& last;
+ std::streamsize pos;
private:
// silence MSVC warning C4512: assignment operator could not be generated
Modified: branches/release/boost/spirit/home/qi/stream/stream.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/stream/stream.hpp (original)
+++ branches/release/boost/spirit/home/qi/stream/stream.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -37,10 +37,14 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::stream;
using spirit::wstream;
+#endif
+ using spirit::stream_type;
+ using spirit::wstream_type;
- template <typename Char = char, typename T = spirit::hold_any>
+ template <typename Char = char, typename T = spirit::basic_hold_any<char> >
struct stream_parser
: primitive_parser<stream_parser<Char, T> >
{
@@ -60,8 +64,16 @@
typedef boost::iostreams::stream<source_device> instream;
qi::skip_over(first, last, skipper);
- instream in(first, last);
+
+ instream in(first, last); // copies 'first'
in >> attr; // use existing operator>>()
+
+ // advance the iterator if everything is ok
+ if (in.good()) {
+ std::streamsize pos = in.tellg();
+ std::advance(first, pos);
+ }
+
return in.good() || in.eof();
}
Modified: branches/release/boost/spirit/home/qi/string/lit.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/string/lit.hpp (original)
+++ branches/release/boost/spirit/home/qi/string/lit.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -65,14 +65,16 @@
// enables lit(...)
template <typename A0>
struct use_terminal<qi::domain
- , terminal_ex<tag::lit, fusion::vector1<A0> >
+ , terminal_ex<tag::lit, fusion::vector1<A0> >
, typename enable_if<traits::is_string<A0> >::type>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::lit;
+#endif
using spirit::lit_type;
///////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/qi/string/symbols.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/string/symbols.hpp (original)
+++ branches/release/boost/spirit/home/qi/string/symbols.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -398,6 +398,15 @@
};
}}}
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char, typename T, typename Lookup, typename Filter
+ , typename Attr, typename Context, typename Iterator>
+ struct handles_container<qi::symbols<Char, T, Lookup, Filter>, Attr, Context, Iterator>
+ : traits::is_container<Attr> {};
+}}}
+
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
Modified: branches/release/boost/spirit/home/support/argument.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/argument.hpp (original)
+++ branches/release/boost/spirit/home/support/argument.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -25,11 +25,32 @@
# define SPIRIT_ARGUMENTS_LIMIT PHOENIX_LIMIT
#endif
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
#define SPIRIT_DECLARE_ARG(z, n, data) \
+ typedef phoenix::actor<argument<n> > const \
+ BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
phoenix::actor<argument<n> > const \
BOOST_PP_CAT(_, BOOST_PP_INC(n)) = argument<n>();
+ /***/
+
+#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> > const \
+ 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); \
+ /***/
-#define SPIRIT_USING_ARGUMENT(z, n, data) using spirit::BOOST_PP_CAT(_, n);
+#endif
namespace boost { namespace spirit
{
@@ -117,27 +138,41 @@
};
// _0 refers to the whole attribute as generated by the lhs parser
- phoenix::actor<attribute_context> const _0 = attribute_context();
+ typedef phoenix::actor<attribute_context> const _0_type;
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+ _0_type _0 = attribute_context();
+#endif
// _1, _2, ... refer to the attributes of the single components the lhs
// parser is composed of
- phoenix::actor<argument<0> > const _1 = argument<0>();
- phoenix::actor<argument<1> > const _2 = argument<1>();
- phoenix::actor<argument<2> > const _3 = argument<2>();
+ typedef phoenix::actor<argument<0> > const _1_type;
+ typedef phoenix::actor<argument<1> > const _2_type;
+ typedef phoenix::actor<argument<2> > const _3_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+ _1_type _1 = argument<0>();
+ _2_type _2 = argument<1>();
+ _3_type _3 = argument<2>();
+#endif
// '_pass' may be used to make a match fail in retrospective
- phoenix::actor<phoenix::argument<2> > const _pass = phoenix::argument<2>();
+ typedef phoenix::actor<phoenix::argument<2> > const _pass_type;
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+ _pass_type _pass = phoenix::argument<2>();
+#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
}}
Modified: branches/release/boost/spirit/home/support/attributes.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/attributes.hpp (original)
+++ branches/release/boost/spirit/home/support/attributes.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -27,6 +27,7 @@
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/is_view.hpp>
+#include <boost/fusion/include/mpl.hpp>
#include <boost/foreach.hpp>
#include <boost/utility/value_init.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -39,12 +40,14 @@
#include <boost/mpl/distance.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/equal.hpp>
#include <boost/proto/proto_fwd.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/variant.hpp>
#include <boost/range/iterator_range.hpp>
#include <vector>
#include <utility>
+#include <ios>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
@@ -55,6 +58,100 @@
// components.
///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
+ // Find out if T can be a (strong) substitute for Expected attribute
+ template <typename T, typename Expected, typename Enable /*= void*/>
+ struct is_substitute : is_same<T, Expected> {};
+
+ template <typename T, typename Expected>
+ struct is_substitute<optional<T>, optional<Expected> >
+ : is_substitute<T, Expected> {};
+
+ template <typename T, typename Expected>
+ struct is_substitute<T, Expected,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_sequence<Expected>,
+ mpl::equal<T, Expected, is_substitute<mpl::_1, mpl::_2> >
+ >
+ >::type>
+ : mpl::true_ {};
+
+ namespace detail
+ {
+ template <typename T, typename Expected>
+ struct value_type_is_substitute
+ : is_substitute<
+ typename container_value<T>::type
+ , typename container_value<Expected>::type>
+ {};
+ }
+
+ template <typename T, typename Expected>
+ struct is_substitute<T, Expected,
+ typename enable_if<
+ mpl::and_<
+ is_container<T>,
+ is_container<Expected>,
+ detail::value_type_is_substitute<T, Expected>
+ >
+ >::type>
+ : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Find out if T can be a weak substitute for Expected attribute
+ template <typename T, typename Expected, typename Enable /*= void*/>
+ struct is_weak_substitute : is_convertible<T, Expected> {};
+
+ template <typename T, typename Expected>
+ struct is_weak_substitute<optional<T>, optional<Expected> >
+ : is_weak_substitute<T, Expected> {};
+
+ template <typename T, typename Expected>
+ struct is_weak_substitute<T, Expected,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_sequence<Expected>,
+ mpl::equal<T, Expected, is_weak_substitute<mpl::_1, mpl::_2> > >
+ >::type>
+ : mpl::true_ {};
+
+ // If this is not defined, the main template definition above will return
+ // true if T is convertible to the first type in a fusion::vector. We
+ // globally declare any non-Fusion sequence T as not compatible with any
+ // Fusion sequence Expected.
+ template <typename T, typename Expected>
+ struct is_weak_substitute<T, Expected,
+ typename enable_if<
+ mpl::and_<
+ mpl::not_<fusion::traits::is_sequence<T> >
+ , fusion::traits::is_sequence<Expected> >
+ >::type>
+ : mpl::false_ {};
+
+ namespace detail
+ {
+ template <typename T, typename Expected>
+ struct value_type_is_weak_substitute
+ : is_weak_substitute<
+ typename container_value<T>::type
+ , typename container_value<Expected>::type>
+ {};
+ }
+
+ template <typename T, typename Expected>
+ struct is_weak_substitute<T, Expected,
+ typename enable_if<
+ mpl::and_<
+ is_container<T>,
+ is_container<Expected>,
+ detail::value_type_is_weak_substitute<T, Expected> >
+ >::type>
+ : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable/* = void*/>
struct is_proxy : mpl::false_ {};
@@ -101,7 +198,7 @@
namespace detail
{
// A component is compatible to a given Attribute type if the
- // Attribute is the same as the expected type of the component or if
+ // Attribute is the same as the expected type of the component or if
// it is convertible to the expected type.
template <typename Expected, typename Attribute>
struct attribute_is_compatible
@@ -115,7 +212,7 @@
template <typename Container>
struct is_hold_any_container
- : is_same<hold_any, typename traits::container_value<Container>::type>
+ : traits::is_hold_any<typename traits::container_value<Container>::type>
{};
}
@@ -124,7 +221,7 @@
struct compute_compatible_component_variant
: mpl::or_<
traits::detail::attribute_is_compatible<Expected, Attribute>
- , is_same<hold_any, Expected>
+ , traits::is_hold_any<Expected>
, mpl::eval_if<
is_container<Expected>
, traits::detail::is_hold_any_container<Expected>
@@ -161,7 +258,7 @@
mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
compatible_type;
- // return whether the given type is compatible with the Expected type
+ // return whether the given type is compatible with the Expected type
static bool is_compatible(int which)
{
return which == distance::value;
@@ -251,7 +348,6 @@
template <typename Attribute, typename Enable/* = void*/>
struct attribute_type : mpl::identity<Attribute> {};
-
///////////////////////////////////////////////////////////////////////////
// Retrieve the size of a fusion sequence (compile time)
///////////////////////////////////////////////////////////////////////////
@@ -395,7 +491,7 @@
template <typename T>
struct build_optional
{
- typedef optional<T> type;
+ typedef boost::optional<T> type;
};
template <>
@@ -436,38 +532,38 @@
///////////////////////////////////////////////////////////////////////////
// sequence_attribute_transform
- //
+ //
// This transform is invoked for every attribute in a sequence allowing
- // to modify the attribute type exposed by a component to the enclosing
+ // to modify the attribute type exposed by a component to the enclosing
// sequence component. By default no transformation is performed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Domain>
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
struct sequence_attribute_transform
: mpl::identity<Attribute>
{};
///////////////////////////////////////////////////////////////////////////
// permutation_attribute_transform
- //
+ //
// This transform is invoked for every attribute in a sequence allowing
- // to modify the attribute type exposed by a component to the enclosing
- // permutation component. By default a build_optional transformation is
+ // to modify the attribute type exposed by a component to the enclosing
+ // permutation component. By default a build_optional transformation is
// performed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Domain>
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
struct permutation_attribute_transform
: traits::build_optional<Attribute>
{};
///////////////////////////////////////////////////////////////////////////
// sequential_or_attribute_transform
- //
+ //
// This transform is invoked for every attribute in a sequential_or allowing
- // to modify the attribute type exposed by a component to the enclosing
- // sequential_or component. By default a build_optional transformation is
+ // to modify the attribute type exposed by a component to the enclosing
+ // sequential_or component. By default a build_optional transformation is
// performed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Domain>
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
struct sequential_or_attribute_transform
: traits::build_optional<Attribute>
{};
@@ -573,7 +669,7 @@
template <typename Sequence, int size>
struct build_collapsed_variant<Sequence, false, size>
{
- typedef optional<
+ typedef boost::optional<
typename spirit::detail::as_variant<
typename fusion::result_of::pop_front<Sequence>::type
>::type
@@ -599,7 +695,7 @@
template <typename Sequence>
struct build_collapsed_variant<Sequence, false, 2>
{
- typedef optional<
+ typedef boost::optional<
typename mpl::deref<
typename mpl::next<
typename mpl::begin<Sequence>::type
@@ -612,12 +708,12 @@
///////////////////////////////////////////////////////////////////////////
// alternative_attribute_transform
- //
+ //
// This transform is invoked for every attribute in an alternative allowing
- // to modify the attribute type exposed by a component to the enclosing
+ // to modify the attribute type exposed by a component to the enclosing
// alternative component. By default no transformation is performed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Domain>
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
struct alternative_attribute_transform
: mpl::identity<Attribute>
{};
@@ -708,7 +804,9 @@
// not care about the attribute. For semantic actions, however, we need to
// have a real value to pass to the semantic action. If the client did not
// provide one, we will have to synthesize the value. This class takes care
- // of that.
+ // of that. *Note that this behavior has changed. From Boost 1.47, semantic
+ // actions always take in the passed attribute as-is if the PP constant:
+ // BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT is defined.
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename ActualAttribute>
struct make_attribute
@@ -894,9 +992,9 @@
// optionals
template <typename T>
- struct clear_value<optional<T> >
+ struct clear_value<boost::optional<T> >
{
- static void call(optional<T>& val)
+ static void call(boost::optional<T>& val)
{
if (val)
val = none_t(); // leave optional uninitialized
@@ -1011,7 +1109,7 @@
{
bool first = true;
typename container_iterator<T_ const>::type iend = traits::end(val);
- for (typename container_iterator<T_ const>::type i = traits::begin(val);
+ for (typename container_iterator<T_ const>::type i = traits::begin(val);
!traits::compare(i, iend); traits::next(i))
{
if (!first)
@@ -1064,7 +1162,7 @@
}
template <typename Out>
- inline void print_attribute(Out& out, unused_type)
+ inline void print_attribute(Out&, unused_type)
{
}
Modified: branches/release/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ branches/release/boost/spirit/home/support/attributes_fwd.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -50,6 +50,18 @@
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>
@@ -63,7 +75,7 @@
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Enable = void>
struct attribute_type;
-
+
///////////////////////////////////////////////////////////////////////////
// Retrieve the size of a fusion sequence (compile time)
///////////////////////////////////////////////////////////////////////////
@@ -132,6 +144,9 @@
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
@@ -149,7 +164,7 @@
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);
@@ -191,7 +206,7 @@
template <typename T, typename Enable = void>
struct is_container;
-
+
template <typename T, typename Enable = void>
struct is_iterator_range;
@@ -200,6 +215,10 @@
, 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>
@@ -260,7 +279,7 @@
///////////////////////////////////////////////////////////////////////////
// transform attribute types exposed from compound operator components
- ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Domain>
struct alternative_attribute_transform;
Modified: branches/release/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/common_terminals.hpp (original)
+++ branches/release/boost/spirit/home/support/common_terminals.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -63,74 +63,74 @@
{};
// Our basic terminals
- BOOST_SPIRIT_DEFINE_TERMINALS(
- ( verbatim )
- ( no_delimit )
- ( lexeme )
- ( no_skip )
- ( omit )
- ( raw )
- ( as_string )
- ( as_wstring )
- ( inf )
- ( eol )
- ( eoi )
- ( buffer )
- ( true_ )
- ( false_ )
- ( matches )
- ( hold )
- ( strict )
- ( relaxed )
- ( duplicate )
+ 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_EX(
- ( lit )
- ( bin )
- ( oct )
- ( hex )
- ( bool_ )
- ( ushort_ )
- ( ulong_ )
- ( uint_ )
- ( short_ )
- ( long_ )
- ( int_ )
- ( ulong_long )
- ( long_long )
- ( float_ )
- ( double_ )
- ( long_double )
- ( repeat )
- ( eps )
- ( pad )
- ( byte_ )
- ( word )
- ( big_word )
- ( little_word )
- ( dword )
- ( big_dword )
- ( little_dword )
- ( qword )
- ( big_qword )
- ( little_qword )
- ( skip )
- ( delimit )
- ( stream )
- ( wstream )
- ( left_align )
- ( right_align )
- ( center )
- ( maxwidth )
- ( set_state )
- ( in_state )
- ( token )
- ( tokenid )
- ( attr )
- ( columns )
- ( auto_ )
+ 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 )
+ ( 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 )
+ ( attr, attr_type )
+ ( columns, columns_type )
+ ( auto_, auto_type )
)
// special tags (used mainly for stateful tag types)
@@ -152,6 +152,15 @@
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(); \
@@ -164,6 +173,17 @@
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; \
@@ -172,6 +192,9 @@
inline void silence_unused_warnings_##name() { (void) name; } \
/***/
+
+#endif
+
#define BOOST_SPIRIT_DEFINE_CHAR_CODES(charset) \
namespace boost { namespace spirit { namespace tag { namespace charset \
{ \
Modified: branches/release/boost/spirit/home/support/container.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/container.hpp (original)
+++ branches/release/boost/spirit/home/support/container.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -55,7 +55,7 @@
{};
template <typename T>
- struct is_container<optional<T> >
+ struct is_container<boost::optional<T> >
: is_container<T>
{};
@@ -70,7 +70,7 @@
{};
#undef BOOST_SPIRIT_IS_CONTAINER
-
+
template <typename T, typename Enable/* = void*/>
struct is_iterator_range
: mpl::false_
@@ -119,7 +119,7 @@
// this will be instantiated if the optional holds a container
template <typename T>
- struct container_value<optional<T> >
+ struct container_value<boost::optional<T> >
: container_value<T>
{};
@@ -211,16 +211,16 @@
};
template <typename T>
- struct optional_attribute<optional<T> >
+ struct optional_attribute<boost::optional<T> >
{
typedef T const& type;
- static type call(optional<T> const& val)
+ static type call(boost::optional<T> const& val)
{
return boost::get<T>(val);
}
- static bool is_valid(optional<T> const& val)
+ static bool is_valid(boost::optional<T> const& val)
{
return val;
}
@@ -268,7 +268,7 @@
template <typename Container, typename T>
struct push_back_container<optional<Container>, T>
{
- static bool call(optional<Container>& c, T const& val)
+ static bool call(boost::optional<Container>& c, T const& val)
{
if (!c)
c = Container();
@@ -369,7 +369,7 @@
template <typename Container, typename Enable/* = void*/>
struct make_container_attribute
{
- static void call(Container& c)
+ static void call(Container&)
{
// for static types this function does nothing
}
@@ -509,13 +509,13 @@
};
template <typename T>
- struct optional_value<optional<T> >
+ struct optional_value<boost::optional<T> >
{
typedef T type;
};
template <typename T>
- struct optional_value<optional<T> const>
+ struct optional_value<boost::optional<T> const>
{
typedef T const type;
};
Modified: branches/release/boost/spirit/home/support/context.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/context.hpp (original)
+++ branches/release/boost/spirit/home/support/context.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,6 +14,7 @@
#include <boost/preprocessor/repetition/repeat_from_to.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/phoenix/core/actor.hpp>
#include <boost/spirit/home/phoenix/core/argument.hpp>
#include <boost/fusion/include/at.hpp>
@@ -27,11 +28,30 @@
# define SPIRIT_ATTRIBUTES_LIMIT PHOENIX_LIMIT
#endif
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
+ typedef phoenix::actor<attribute<n> > const \
+ BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
phoenix::actor<attribute<n> > const \
BOOST_PP_CAT(_r, n) = attribute<n>();
-#define SPIRIT_USING_ATTRIBUTE(z, n, data) using spirit::BOOST_PP_CAT(_r, n);
+#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> > const \
+ 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
{
@@ -163,35 +183,60 @@
}
};
+ typedef phoenix::actor<attribute<0> > const _val_type;
+ typedef phoenix::actor<attribute<0> > const _r0_type;
+ typedef phoenix::actor<attribute<1> > const _r1_type;
+ typedef phoenix::actor<attribute<2> > const _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
- phoenix::actor<attribute<0> > const _val = attribute<0>();
- phoenix::actor<attribute<0> > const _r0 = attribute<0>();
- phoenix::actor<attribute<1> > const _r1 = attribute<1>();
- phoenix::actor<attribute<2> > const _r2 = attribute<2>();
+ _val_type _val = attribute<0>();
+ _r0_type _r0 = attribute<0>();
+ _r1_type _r1 = attribute<1>();
+ _r2_type _r2 = attribute<2>();
+
+#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> > const _a_type;
+ typedef phoenix::actor<local_variable<1> > const _b_type;
+ typedef phoenix::actor<local_variable<2> > const _c_type;
+ typedef phoenix::actor<local_variable<3> > const _d_type;
+ typedef phoenix::actor<local_variable<4> > const _e_type;
+ typedef phoenix::actor<local_variable<5> > const _f_type;
+ typedef phoenix::actor<local_variable<6> > const _g_type;
+ typedef phoenix::actor<local_variable<7> > const _h_type;
+ typedef phoenix::actor<local_variable<8> > const _i_type;
+ typedef phoenix::actor<local_variable<9> > const _j_type;
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
// _a, _b, ... refer to the local variables of a rule
- phoenix::actor<local_variable<0> > const _a = local_variable<0>();
- phoenix::actor<local_variable<1> > const _b = local_variable<1>();
- phoenix::actor<local_variable<2> > const _c = local_variable<2>();
- phoenix::actor<local_variable<3> > const _d = local_variable<3>();
- phoenix::actor<local_variable<4> > const _e = local_variable<4>();
- phoenix::actor<local_variable<5> > const _f = local_variable<5>();
- phoenix::actor<local_variable<6> > const _g = local_variable<6>();
- phoenix::actor<local_variable<7> > const _h = local_variable<7>();
- phoenix::actor<local_variable<8> > const _i = local_variable<8>();
- phoenix::actor<local_variable<9> > const _j = local_variable<9>();
+ _a_type _a = local_variable<0>();
+ _b_type _b = local_variable<1>();
+ _c_type _c = local_variable<2>();
+ _d_type _d = local_variable<3>();
+ _e_type _e = local_variable<4>();
+ _f_type _f = local_variable<5>();
+ _g_type _g = local_variable<6>();
+ _h_type _h = local_variable<7>();
+ _i_type _i = local_variable<8>();
+ _j_type _j = local_variable<9>();
+#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;
@@ -203,6 +248,7 @@
using spirit::_h;
using spirit::_i;
using spirit::_j;
+#endif
}
}}
Modified: branches/release/boost/spirit/home/support/detail/hold_any.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/detail/hold_any.hpp (original)
+++ branches/release/boost/spirit/home/support/detail/hold_any.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -58,6 +58,7 @@
namespace detail
{
// function pointer table
+ template <typename Char>
struct fxn_ptr_table
{
boost::detail::sp_typeinfo const& (*get_type)();
@@ -65,18 +66,18 @@
void (*destruct)(void**);
void (*clone)(void* const*, void**);
void (*move)(void* const*, void**);
- std::istream& (*stream_in)(std::istream&, void**);
- std::ostream& (*stream_out)(std::ostream&, void* const*);
+ 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>
+ template <typename Small>
struct fxns;
- template<>
+ template <>
struct fxns<mpl::true_>
{
- template<typename T>
+ template<typename T, typename Char>
struct type
{
static boost::detail::sp_typeinfo const& get_type()
@@ -101,12 +102,14 @@
*reinterpret_cast<T*>(dest) =
*reinterpret_cast<T const*>(src);
}
- static std::istream& stream_in (std::istream& i, void** obj)
+ static std::basic_istream<Char>&
+ stream_in (std::basic_istream<Char>& i, void** obj)
{
i >> *reinterpret_cast<T*>(obj);
return i;
}
- static std::ostream& stream_out(std::ostream& o, void* const* obj)
+ static std::basic_ostream<Char>&
+ stream_out(std::basic_ostream<Char>& o, void* const* obj)
{
o << *reinterpret_cast<T const*>(obj);
return o;
@@ -115,10 +118,10 @@
};
// static functions for big value-types (bigger than a void*)
- template<>
+ template <>
struct fxns<mpl::false_>
{
- template<typename T>
+ template<typename T, typename Char>
struct type
{
static boost::detail::sp_typeinfo const& get_type()
@@ -145,12 +148,14 @@
**reinterpret_cast<T**>(dest) =
**reinterpret_cast<T* const*>(src);
}
- static std::istream& stream_in(std::istream& i, void** obj)
+ static std::basic_istream<Char>&
+ stream_in(std::basic_istream<Char>& i, void** obj)
{
i >> **reinterpret_cast<T**>(obj);
return i;
}
- static std::ostream& stream_out(std::ostream& o, void* const* obj)
+ static std::basic_ostream<Char>&
+ stream_out(std::basic_ostream<Char>& o, void* const* obj)
{
o << **reinterpret_cast<T* const*>(obj);
return o;
@@ -158,22 +163,23 @@
};
};
- template<typename T>
+ template <typename T>
struct get_table
{
typedef mpl::bool_<(sizeof(T) <= sizeof(void*))> is_small;
- static fxn_ptr_table* get()
+ template <typename Char>
+ static fxn_ptr_table<Char>* get()
{
- static fxn_ptr_table static_table =
+ static fxn_ptr_table<Char> static_table =
{
- fxns<is_small>::template type<T>::get_type,
- fxns<is_small>::template type<T>::static_delete,
- fxns<is_small>::template type<T>::destruct,
- fxns<is_small>::template type<T>::clone,
- fxns<is_small>::template type<T>::move,
- fxns<is_small>::template type<T>::stream_in,
- fxns<is_small>::template type<T>::stream_out
+ 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;
}
@@ -182,8 +188,9 @@
///////////////////////////////////////////////////////////////////////
struct empty {};
- inline std::istream&
- operator>> (std::istream& i, 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
@@ -199,21 +206,23 @@
return i;
}
- inline std::ostream&
- operator<< (std::ostream& o, empty const&)
+ template <typename Char>
+ inline std::basic_ostream<Char>&
+ operator<< (std::basic_ostream<Char>& o, empty const&)
{
return o;
}
}
///////////////////////////////////////////////////////////////////////////
- class hold_any
+ template <typename Char>
+ class basic_hold_any
{
public:
// constructors
template <typename T>
- explicit hold_any(T const& x)
- : table(spirit::detail::get_table<T>::get()), object(0)
+ 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);
@@ -221,26 +230,26 @@
object = new T(x);
}
- hold_any()
- : table(spirit::detail::get_table<spirit::detail::empty>::get()),
+ basic_hold_any()
+ : table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
object(0)
{
}
- hold_any(hold_any const& x)
- : table(spirit::detail::get_table<spirit::detail::empty>::get()),
+ basic_hold_any(basic_hold_any const& x)
+ : table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
object(0)
{
assign(x);
}
- ~hold_any()
+ ~basic_hold_any()
{
table->static_delete(&object);
}
// assignment
- hold_any& assign(hold_any const& x)
+ basic_hold_any& assign(basic_hold_any const& x)
{
if (&x != this) {
// are we copying between the same type?
@@ -258,11 +267,11 @@
}
template <typename T>
- hold_any& assign(T const& x)
+ basic_hold_any& assign(T const& x)
{
// are we copying between the same type?
- spirit::detail::fxn_ptr_table* x_table =
- spirit::detail::get_table<T>::get();
+ 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
@@ -292,13 +301,13 @@
// assignment operator
template <typename T>
- hold_any& operator=(T const& x)
+ basic_hold_any& operator=(T const& x)
{
return assign(x);
}
// utility functions
- hold_any& swap(hold_any& x)
+ basic_hold_any& swap(basic_hold_any& x)
{
std::swap(table, x.table);
std::swap(object, x.object);
@@ -330,7 +339,7 @@
bool empty() const
{
- return table == spirit::detail::get_table<spirit::detail::empty>::get();
+ return table == spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
}
void reset()
@@ -338,7 +347,7 @@
if (!empty())
{
table->static_delete(&object);
- table = spirit::detail::get_table<spirit::detail::empty>::get();
+ table = spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
object = 0;
}
}
@@ -347,31 +356,35 @@
// type has a corresponding operator defined, which is completely safe
// because spirit::hold_any is used only in contexts where these operators
// do exist
- friend std::istream& operator>> (std::istream& i, hold_any& obj)
+ 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);
}
- friend std::ostream& operator<< (std::ostream& o, hold_any const& obj)
+ 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>
- friend T* any_cast(hold_any *);
+ 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* table;
+ spirit::detail::fxn_ptr_table<Char>* table;
void* object;
};
// boost::any-like casting
- template <typename T>
- inline T* any_cast (hold_any* operand)
+ 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 ?
@@ -381,14 +394,14 @@
return 0;
}
- template <typename T>
- inline T const* any_cast(hold_any const* operand)
+ template <typename T, typename Char>
+ inline T const* any_cast(basic_hold_any<Char> const* operand)
{
- return any_cast<T>(const_cast<hold_any*>(operand));
+ return any_cast<T>(const_cast<basic_hold_any<Char>*>(operand));
}
- template <typename T>
- T any_cast(hold_any& operand)
+ template <typename T, typename Char>
+ T any_cast(basic_hold_any<Char>& operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
@@ -408,8 +421,8 @@
return *result;
}
- template <typename T>
- T const& any_cast(hold_any const& operand)
+ template <typename T, typename Char>
+ T const& any_cast(basic_hold_any<Char> const& operand)
{
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
@@ -419,10 +432,23 @@
BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
#endif
- return any_cast<nonref const&>(const_cast<hold_any &>(operand));
+ 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
///////////////////////////////////////////////////////////////////////////////
Modified: branches/release/boost/spirit/home/support/iterators/detail/combine_policies.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/iterators/detail/combine_policies.hpp (original)
+++ branches/release/boost/spirit/home/support/iterators/detail/combine_policies.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -95,7 +95,7 @@
: Ownership, Checking, Storage
{
multi_pass_unique() {}
- multi_pass_unique(T const& x) {}
+ multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
@@ -173,7 +173,7 @@
: Ownership, Storage
{
multi_pass_unique() {}
- multi_pass_unique(T const& x) {}
+ multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
@@ -262,7 +262,7 @@
: Checking, Storage
{
multi_pass_unique() {}
- multi_pass_unique(T const& x) {}
+ multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
Modified: branches/release/boost/spirit/home/support/iterators/line_pos_iterator.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/iterators/line_pos_iterator.hpp (original)
+++ branches/release/boost/spirit/home/support/iterators/line_pos_iterator.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,17 +14,13 @@
namespace boost { namespace spirit
{
-
- ////////////////////////////////////////////////////////////////////////////
- // line_pos_iterator: a lightweight line position iterator. This iterator
- // adapter only stores the current line number, nothing else. Unlike spirit
- // classic's position_iterator, it does not store the column number and does
- // not need an end iterator. The current column can be computed, if needed.
- // Some line oriented utilities are provided including computation of the
- // current column.
- ////////////////////////////////////////////////////////////////////////////
-
- //[line_pos_iterator
+ //[line_pos_iterator_class
+ /*`The `line_pos_iterator` is a lightweight line position iterator.
+ This iterator adapter only stores the current line number, nothing else.
+ Unlike __classic__'s `position_iterator`, it does not store the
+ column number and does not need an end iterator. The current column can
+ be computed, if needed. */
+ //`[heading Class Reference]
template <class Iterator>
class line_pos_iterator : public boost::iterator_adaptor<
line_pos_iterator<Iterator> // Derived
@@ -40,12 +36,12 @@
std::size_t position() const;
private:
- friend class boost::iterator_core_access;
+ friend class boost::iterator_core_access;
- void increment();
+ void increment();
- std::size_t line; /*< The line position. >*/
- typename std::iterator_traits<Iterator>::value_type prev;
+ std::size_t line; // The line position.
+ typename std::iterator_traits<Iterator>::value_type prev;
};
//]
@@ -87,32 +83,31 @@
}
//[line_pos_iterator_utilities
+ //`[heading get_line]
template <class Iterator>
- inline std::size_t get_line(Iterator); /*< Get the line position. Returns -1
- if Iterator is not a
- line_pos_iterator. >*/
+ inline std::size_t get_line(Iterator);
+ /*`Get the line position. Returns -1 if Iterator is not a
+ `line_pos_iterator`. */
+ //`[heading get_line_start]
template <class Iterator>
- inline Iterator get_line_start(Iterator lower_bound,
- Iterator current); /*< Get an iterator to
- the beginning of the
- line. Applicable to any
- iterator. >*/
-
+ inline Iterator get_line_start(Iterator lower_bound, Iterator current);
+ /*`Get an iterator to the beginning of the line. Applicable to any
+ iterator. */
+
+ //`[heading get_current_line]
template <class Iterator>
inline iterator_range<Iterator>
- get_current_line(Iterator lower_bound,
- Iterator current,
- Iterator upper_bound); /*< Get the iterator range
- containing the current line.
- Applicable to any iterator. >*/
-
- template <class Iterator>
- inline std::size_t get_column(Iterator lower_bound,
- Iterator current,
- std::size_t tabs = 4); /*< Get the current
- column. Applicable to
- any iterator. >*/
+ get_current_line(Iterator lower_bound, Iterator current,
+ Iterator upper_bound);
+ /*`Get an `iterator_range` containing the current line. Applicable to any
+ iterator. */
+
+ //`[heading get_column]
+ template <class Iterator>
+ inline std::size_t get_column(Iterator lower_bound, Iterator current,
+ std::size_t tabs = 4);
+ /*`Get the current column. Applicable to any iterator. */
//]
template <class Iterator>
Modified: branches/release/boost/spirit/home/support/lazy.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/lazy.hpp (original)
+++ branches/release/boost/spirit/home/support/lazy.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -11,8 +11,8 @@
#pragma once
#endif
+#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/proto/proto.hpp>
-#include <boost/spirit/home/phoenix/core/actor.hpp>
#include <boost/spirit/home/support/modify.hpp>
namespace boost { namespace spirit
Modified: branches/release/boost/spirit/home/support/string_traits.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/string_traits.hpp (original)
+++ branches/release/boost/spirit/home/support/string_traits.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -172,6 +172,8 @@
template <typename T>
struct extract_c_string<T const>
{
+ typedef typename extract_c_string<T>::char_type char_type;
+
static typename extract_c_string<T>::char_type const* call (T const str)
{
return extract_c_string<T>::call(str);
@@ -182,6 +184,8 @@
template <typename T>
struct extract_c_string<T&>
{
+ typedef typename extract_c_string<T>::char_type char_type;
+
static typename extract_c_string<T>::char_type const* call (T& str)
{
return extract_c_string<T>::call(str);
@@ -192,6 +196,8 @@
template <typename T>
struct extract_c_string<T const&>
{
+ typedef typename extract_c_string<T>::char_type char_type;
+
static typename extract_c_string<T>::char_type const* call (T const& str)
{
return extract_c_string<T>::call(str);
@@ -205,11 +211,6 @@
typedef std::basic_string<T, Traits, Allocator> string;
- static T const* call (string& str)
- {
- return str.c_str();
- }
-
static T const* call (string const& str)
{
return str.c_str();
Modified: branches/release/boost/spirit/home/support/terminal.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/terminal.hpp (original)
+++ branches/release/boost/spirit/home/support/terminal.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -18,6 +18,7 @@
#include <boost/spirit/home/support/meta_compiler.hpp>
#include <boost/spirit/home/support/detail/make_vector.hpp>
#include <boost/spirit/home/support/unused.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
namespace boost { namespace spirit
{
@@ -404,7 +405,7 @@
///////////////////////////////////////////////////////////////////////////
namespace result_of
{
- // Calculate the type of the compound terminal if generated by one of
+ // Calculate the type of the compound terminal if generated by one of
// the spirit::terminal::operator() overloads above
// The terminal type itself is passed through without modification
@@ -442,7 +443,7 @@
{
template <typename Data, typename Tag
, typename DataTag1 = unused_type, typename DataTag2 = unused_type>
- struct stateful_tag
+ struct stateful_tag
{
typedef Data data_type;
@@ -460,7 +461,7 @@
template <typename Data, typename Tag
, typename DataTag1 = unused_type, typename DataTag2 = unused_type>
struct stateful_tag_type
- : spirit::terminal<tag::stateful_tag<Data, Tag, DataTag1, DataTag2> >
+ : spirit::terminal<tag::stateful_tag<Data, Tag, DataTag1, DataTag2> >
{
typedef tag::stateful_tag<Data, Tag, DataTag1, DataTag2> tag_type;
@@ -496,38 +497,81 @@
// Common placeholders are placed in the main boost::spirit namespace
// (see common_terminals.hpp)
-#define BOOST_SPIRIT_TERMINAL(name) \
+#define BOOST_SPIRIT_TERMINAL_X(x, y) ((x, y)) BOOST_SPIRIT_TERMINAL_Y
+#define BOOST_SPIRIT_TERMINAL_Y(x, y) ((x, y)) BOOST_SPIRIT_TERMINAL_X
+#define BOOST_SPIRIT_TERMINAL_X0
+#define BOOST_SPIRIT_TERMINAL_Y0
+
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
+#define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \
+ namespace tag { struct name {}; } \
+ typedef boost::proto::terminal<tag::name>::type type_name; \
+ type_name const name = {{}}; \
+ inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \
+ /***/
+
+#else
+
+#define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \
namespace tag { struct name {}; } \
- typedef boost::proto::terminal<tag::name>::type name##_type; \
- name##_type const name = {{}}; \
- inline void silence_unused_warnings__##name() { (void) name; } \
+ typedef boost::proto::terminal<tag::name>::type type_name; \
+ /***/
+
+#endif
+
+#define BOOST_SPIRIT_TERMINAL(name) \
+ BOOST_SPIRIT_TERMINAL_NAME(name, name ## _type) \
/***/
-#define BOOST_SPIRIT_DEFINE_TERMINALS_A(r, _, name) \
- BOOST_SPIRIT_TERMINAL(name) \
+#define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_A(r, _, names) \
+ BOOST_SPIRIT_TERMINAL_NAME( \
+ BOOST_PP_TUPLE_ELEM(2, 0, names), \
+ BOOST_PP_TUPLE_ELEM(2, 1, names) \
+ ) \
/***/
-#define BOOST_SPIRIT_DEFINE_TERMINALS(seq) \
- BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_A, _, seq) \
+#define BOOST_SPIRIT_DEFINE_TERMINALS_NAME(seq) \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_NAME_A, _, \
+ BOOST_PP_CAT(BOOST_SPIRIT_TERMINAL_X seq, 0)) \
/***/
// Define a spirit extended terminal. This macro may be placed in any namespace.
// Common placeholders are placed in the main boost::spirit namespace
// (see common_terminals.hpp)
-#define BOOST_SPIRIT_TERMINAL_EX(name) \
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+
+#define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \
+ namespace tag { struct name {}; } \
+ typedef boost::spirit::terminal<tag::name> type_name; \
+ type_name const name = type_name(); \
+ inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \
+ /***/
+
+#else
+
+#define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \
namespace tag { struct name {}; } \
- typedef boost::spirit::terminal<tag::name> name##_type; \
- name##_type const name = name##_type(); \
- inline void silence_unused_warnings__##name() { (void) name; } \
+ typedef boost::spirit::terminal<tag::name> type_name; \
+ /***/
+
+#endif
+
+#define BOOST_SPIRIT_TERMINAL_EX(name) \
+ BOOST_SPIRIT_TERMINAL_NAME_EX(name, name ## _type) \
/***/
-#define BOOST_SPIRIT_DEFINE_TERMINALS_EX_A(r, _, name) \
- BOOST_SPIRIT_TERMINAL_EX(name) \
+#define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX_A(r, _, names) \
+ BOOST_SPIRIT_TERMINAL_NAME_EX( \
+ BOOST_PP_TUPLE_ELEM(2, 0, names), \
+ BOOST_PP_TUPLE_ELEM(2, 1, names) \
+ ) \
/***/
-#define BOOST_SPIRIT_DEFINE_TERMINALS_EX(seq) \
- BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_EX_A, _, seq) \
+#define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(seq) \
+ BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX_A, _, \
+ BOOST_PP_CAT(BOOST_SPIRIT_TERMINAL_X seq, 0)) \
/***/
#endif
Copied: branches/release/boost/spirit/home/support/utree.hpp (from r68408, /branches/release/boost/spirit/home/support/utree.hpp)
==============================================================================
--- /branches/release/boost/spirit/home/support/utree.hpp (original)
+++ branches/release/boost/spirit/home/support/utree.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -11,6 +11,7 @@
#pragma once
#endif
+#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
#include <boost/spirit/home/support/utree/utree.hpp>
#include <boost/spirit/home/support/utree/operators.hpp>
#include <boost/spirit/home/support/utree/detail/utree_detail2.hpp>
Copied: branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp (from r68408, /branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp)
==============================================================================
--- /branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -617,7 +617,31 @@
function_base*
stored_function<F>::clone() const
{
- return new stored_function<F>(*this);
+ return new stored_function<F>(f);
+ }
+
+ template <typename F>
+ referenced_function<F>::referenced_function(F& f)
+ : f(f)
+ {
+ }
+
+ template <typename F>
+ referenced_function<F>::~referenced_function()
+ {
+ };
+
+ template <typename F>
+ utree referenced_function<F>::operator()(scope const& env) const
+ {
+ return f(env);
+ }
+
+ template <typename F>
+ function_base*
+ referenced_function<F>::clone() const
+ {
+ return new referenced_function<F>(f);
}
inline utree::utree(utree::invalid_type)
@@ -719,6 +743,14 @@
pf = new stored_function<F>(pf_);
set_type(type::function_type);
}
+
+ template <typename F>
+ inline utree::utree(referenced_function<F> const& pf_)
+ {
+ s.initialize();
+ pf = new referenced_function<F>(pf_);
+ set_type(type::function_type);
+ }
template <typename Iter>
inline utree::utree(boost::iterator_range<Iter> r)
@@ -864,10 +896,19 @@
}
template <typename F>
- utree& utree::operator=(stored_function<F> const& pf)
+ utree& utree::operator=(stored_function<F> const& pf_)
+ {
+ free();
+ pf = new stored_function<F>(pf_);
+ set_type(type::function_type);
+ return *this;
+ }
+
+ template <typename F>
+ utree& utree::operator=(referenced_function<F> const& pf_)
{
free();
- pf = new stored_function<F>(pf);
+ pf = new referenced_function<F>(pf_);
set_type(type::function_type);
return *this;
}
Copied: branches/release/boost/spirit/home/support/utree/operators.hpp (from r68408, /branches/release/boost/spirit/home/support/utree/operators.hpp)
==============================================================================
--- /branches/release/boost/spirit/home/support/utree/operators.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/operators.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -15,6 +15,7 @@
#endif
#include <exception>
+#include <ios>
#include <boost/spirit/home/support/utree/utree.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/throw_exception.hpp>
@@ -287,41 +288,59 @@
// We assume anything except false is true
// binary
- utree operator()(bool a, bool b) const
+ template <typename A, typename B>
+ utree operator()(A const& a, B const& b) const
{
- return Base::eval(a, b); // for boolean types
+ return dispatch(a, b
+ , boost::is_arithmetic<A>()
+ , boost::is_arithmetic<B>());
}
// binary
- template <typename A>
- utree operator()(A const& a, bool b) const
+ template <typename A, typename B>
+ utree dispatch(A const& a, B const& b, mpl::true_, mpl::true_) const
+ {
+ return Base::eval(a, b); // for arithmetic types
+ }
+
+ // binary
+ template <typename A, typename B>
+ utree dispatch(A const& a, B const& b, mpl::false_, mpl::true_) const
{
return Base::eval(true, b);
}
// binary
- template <typename B>
- utree operator()(bool a, B const& b) const
+ template <typename A, typename B>
+ utree dispatch(A const& a, B const& b, mpl::true_, mpl::false_) const
{
return Base::eval(a, true);
}
// binary
template <typename A, typename B>
- utree operator()(A const& a, B const& b) const
+ utree dispatch(A const& a, B const& b, mpl::false_, mpl::false_) const
{
return Base::eval(true, true);
}
+
+ // unary
+ template <typename A>
+ utree operator()(A const& a) const
+ {
+ return dispatch(a, boost::is_arithmetic<A>());
+ }
// unary
- utree operator()(bool a) const
+ template <typename A>
+ utree dispatch(A const& a, mpl::true_) const
{
return Base::eval(a);
}
// unary
template <typename A>
- utree operator()(A const& a) const
+ utree dispatch(A const& a, mpl::false_) const
{
return Base::eval(true);
}
Copied: branches/release/boost/spirit/home/support/utree/utree.hpp (from r68408, /branches/release/boost/spirit/home/support/utree/utree.hpp)
==============================================================================
--- /branches/release/boost/spirit/home/support/utree/utree.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/utree.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -192,6 +192,16 @@
virtual utree operator()(scope const& env) const;
virtual function_base* clone() const;
};
+
+ template <typename F>
+ struct referenced_function : function_base
+ {
+ F& f;
+ referenced_function(F& f);
+ virtual ~referenced_function();
+ virtual utree operator()(scope const& env) const;
+ virtual function_base* clone() const;
+ };
//]
///////////////////////////////////////////////////////////////////////////
@@ -361,6 +371,13 @@
utree(stored_function<F> const&);
template <class F>
reference operator=(stored_function<F> const&);
+
+ // This initializes a `function_type` node, storing by reference
+ // instead of copying the function object.
+ template <class F>
+ utree(referenced_function<F> const&);
+ template <class F>
+ reference operator=(referenced_function<F> const&);
// This initializes either a `string_type`, a `symbol_type`, or a
// `binary_type` node (depending on the template parameter `type_`),
@@ -458,7 +475,7 @@
reference operator[](size_type);
const_reference operator[](size_type) const;
- // This clears the utree instance and resets its type to 'invalid_type'
+ // This clears the utree instance and resets its type to `invalid_type`
void clear();
void swap(utree&);
Copied: branches/release/boost/spirit/home/support/utree/utree_traits.hpp (from r68408, /branches/release/boost/spirit/home/support/utree/utree_traits.hpp)
==============================================================================
--- /branches/release/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/utree_traits.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -59,6 +59,11 @@
}
return false;
}
+
+ inline bool is_uninitialized(utree const& ut)
+ {
+ return traits::which(ut) == utree_type::invalid_type;
+ }
}
// this specialization tells Spirit how to extract the type of the value
@@ -154,6 +159,28 @@
};
///////////////////////////////////////////////////////////////////////////
+ // these specializations are needed because utree::value_type == utree
+ template <>
+ struct is_substitute<utree, utree>
+ : mpl::true_
+ {};
+
+ template <>
+ struct is_weak_substitute<utree, utree>
+ : mpl::true_
+ {};
+
+ template <>
+ struct is_substitute<utree::list_type, utree::list_type>
+ : mpl::true_
+ {};
+
+ template <>
+ struct is_weak_substitute<utree::list_type, utree::list_type>
+ : mpl::true_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
// this specialization tells Spirit.Qi to allow assignment to an utree from
// a variant
namespace detail
@@ -507,8 +534,15 @@
{
static void call(utree& ut)
{
- if (!detail::is_list(ut))
- ut = empty_list;
+ if (!detail::is_list(ut)) {
+ if (detail::is_uninitialized(ut))
+ ut = empty_list;
+ else {
+ utree retval (empty_list);
+ retval.push_back(ut);
+ ut.swap(retval);
+ }
+ }
}
};
@@ -547,21 +581,47 @@
// or a grammar exposes an utree as it's attribute
namespace detail
{
- // checks if the attr is the explicit utree list type, utree::list_type
- template <typename Attribute>
- struct attribute_is_not_utree_list
+ // Checks whether the exposed Attribute allows to handle utree or
+ // utree::list_type directly. Returning mpl::false_ from this meta
+ // function will force a new utree instance to be created for each
+ // invocation of the embedded parser.
+
+ // The purpose of using utree::list_type as an attribute is to force a
+ // new sub-node in the result.
+ template <typename Attribute, typename Enable = void>
+ struct handles_utree_list_container
: mpl::and_<
mpl::not_<is_same<utree::list_type, Attribute> >,
traits::is_container<Attribute> >
{};
+
+ // The following specializations make sure that the actual handling of
+ // an utree (or utree::list_type) attribute is deferred to the embedded
+ // parsers of a sequence, alternative or optional component.
+ template <typename Attribute>
+ struct handles_utree_list_container<Attribute
+ , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
+ : mpl::true_
+ {};
+
+ template <typename Attribute>
+ struct handles_utree_list_container<boost::optional<Attribute> >
+ : mpl::true_
+ {};
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct handles_utree_list_container<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ : mpl::true_
+ {};
}
template <
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::attribute_is_not_utree_list<typename attribute_of<
+ , utree, Context, IteratorB>
+ : detail::handles_utree_list_container<typename attribute_of<
qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
@@ -570,8 +630,8 @@
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::attribute_is_not_utree_list<typename attribute_of<
+ , utree, Context, IteratorB>
+ : detail::handles_utree_list_container<typename attribute_of<
qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
@@ -580,8 +640,8 @@
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<qi::rule<IteratorA, T1, T2, T3, T4>
- , utree::list_type, Context, IteratorB>
- : detail::attribute_is_not_utree_list<typename attribute_of<
+ , utree::list_type, Context, IteratorB>
+ : detail::handles_utree_list_container<typename attribute_of<
qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
@@ -590,30 +650,69 @@
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<qi::grammar<IteratorA, T1, T2, T3, T4>
- , utree::list_type, Context, IteratorB>
- : detail::attribute_is_not_utree_list<typename attribute_of<
+ , utree::list_type, Context, IteratorB>
+ : detail::handles_utree_list_container<typename attribute_of<
qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Sequence>
+ struct pass_through_container<
+ utree, utree, Attribute, Sequence, qi::domain>
+ : detail::handles_utree_list_container<Attribute>
+ {};
+
+ template <typename Attribute, typename Sequence>
+ struct pass_through_container<
+ utree::list_type, utree, Attribute, Sequence, qi::domain>
+ : detail::handles_utree_list_container<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
namespace detail
{
- // checks if the attr is utree
- template <typename Attribute>
- struct attribute_is_not_utree
+ // Checks whether the exposed Attribute allows to handle utree or
+ // utree::list_type directly. Returning mpl::false_ from this meta
+ // function will force a new utree instance to be created for each
+ // invocation of the embedded parser.
+
+ // The purpose of using utree::list_type as an attribute is to force a
+ // new sub-node in the result.
+ template <typename Attribute, typename Enable = void>
+ struct handles_utree_container
: mpl::and_<
mpl::not_<is_same<utree, Attribute> >,
traits::is_container<Attribute> >
{};
+
+ // The following specializations make sure that the actual handling of
+ // an utree (or utree::list_type) attribute is deferred to the embedded
+ // parsers of a sequence, alternative or optional component.
+ template <typename Attribute>
+ struct handles_utree_container<Attribute
+ , typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
+ : mpl::true_
+ {};
+
+ template <typename Attribute>
+ struct handles_utree_container<boost::optional<Attribute> >
+ : mpl::true_
+ {};
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct handles_utree_container<
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ : mpl::true_
+ {};
}
template <
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<karma::rule<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::attribute_is_not_utree<typename attribute_of<
+ , utree, Context, IteratorB>
+ : detail::handles_utree_container<typename attribute_of<
karma::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
@@ -622,13 +721,20 @@
typename IteratorA, typename IteratorB, typename Context
, typename T1, typename T2, typename T3, typename T4>
struct handles_container<karma::grammar<IteratorA, T1, T2, T3, T4>
- , utree, Context, IteratorB>
- : detail::attribute_is_not_utree<typename attribute_of<
+ , utree, Context, IteratorB>
+ : detail::handles_utree_container<typename attribute_of<
karma::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type>
{};
///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Sequence>
+ struct pass_through_container<
+ utree, utree, Attribute, Sequence, karma::domain>
+ : detail::handles_utree_container<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
// the specialization below tells Spirit how to handle utree if it is used
// with an optional component
template <>
@@ -644,7 +750,7 @@
// only 'invalid_type' utree nodes are not valid
static bool is_valid(utree const& val)
{
- return traits::which(val) != utree_type::invalid_type;
+ return !detail::is_uninitialized(val);
}
};
@@ -943,7 +1049,7 @@
}
template <>
- struct extract_from_attribute<utree, utree::nil_type>
+ struct extract_from_container<utree, utree::nil_type>
{
typedef utree::nil_type type;
@@ -955,7 +1061,7 @@
};
template <>
- struct extract_from_attribute<utree, char>
+ struct extract_from_container<utree, char>
{
typedef char type;
@@ -968,7 +1074,7 @@
};
template <>
- struct extract_from_attribute<utree, bool>
+ struct extract_from_container<utree, bool>
{
typedef bool type;
@@ -980,7 +1086,7 @@
};
template <>
- struct extract_from_attribute<utree, int>
+ struct extract_from_container<utree, int>
{
typedef int type;
@@ -992,7 +1098,7 @@
};
template <>
- struct extract_from_attribute<utree, double>
+ struct extract_from_container<utree, double>
{
typedef double type;
@@ -1004,7 +1110,7 @@
};
template <typename Traits, typename Alloc>
- struct extract_from_attribute<utree, std::basic_string<char, Traits, Alloc> >
+ struct extract_from_container<utree, std::basic_string<char, Traits, Alloc> >
{
typedef std::basic_string<char, Traits, Alloc> type;
@@ -1017,7 +1123,7 @@
};
template <>
- struct extract_from_attribute<utree, utf8_symbol_type>
+ struct extract_from_container<utree, utf8_symbol_type>
{
typedef std::string type;
@@ -1030,7 +1136,7 @@
};
template <>
- struct extract_from_attribute<utree, utf8_string_type>
+ struct extract_from_container<utree, utf8_string_type>
{
typedef std::string type;
@@ -1123,7 +1229,10 @@
static type pre(iterator_range<Iterator> const& t)
{
// return utree the begin iterator points to
- return utree(boost::ref(t.front()));
+ Iterator it = boost::begin(t);
+ utree result(boost::ref(*it));
+ ++it;
+ return result;
}
};
@@ -1156,28 +1265,6 @@
struct transform_attribute<utree::list_type const, Attribute, karma::domain>
: transform_attribute<utree const, Attribute, karma::domain>
{};
-
-#if 0
- // If a rule takes an utree attribute and that utree instance holds nothing
- // more than a list, we dereference this to simplify attribute handling
- // down the stream, i.e. ( ( 1 2 3 ) ) --> ( 1 2 3 ).
- template <>
- struct transform_attribute<utree const, utree, karma::domain>
- {
- typedef utree const& type;
- static utree const& pre(utree const& val)
- {
- if (detail::is_list(val) && 1 == val.size())
- return val.front();
- return val;
- }
- };
-
- template <>
- struct transform_attribute<utree const&, utree, karma::domain>
- : transform_attribute<utree const, utree, karma::domain>
- {};
-#endif
}}}
#endif
Copied: branches/release/boost/spirit/home/support/utree/utree_traits_fwd.hpp (from r68861, /trunk/boost/spirit/home/support/utree/utree_traits_fwd.hpp)
==============================================================================
--- /trunk/boost/spirit/home/support/utree/utree_traits_fwd.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/utree_traits_fwd.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -12,7 +12,7 @@
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
- struct utree;
+ class utree;
}}
namespace boost
Modified: branches/release/boost/spirit/repository/home/qi.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,6 +14,7 @@
#include <boost/spirit/repository/home/qi/primitive.hpp>
#include <boost/spirit/repository/home/qi/directive.hpp>
#include <boost/spirit/repository/home/qi/nonterminal.hpp>
+#include <boost/spirit/repository/home/qi/operator.hpp>
#endif
Modified: branches/release/boost/spirit/repository/home/qi/directive.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/directive.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/directive.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -13,6 +13,7 @@
#include <boost/spirit/repository/home/qi/directive/distinct.hpp>
#include <boost/spirit/repository/home/qi/directive/confix.hpp>
+#include <boost/spirit/repository/home/qi/directive/kwd.hpp>
#endif
Copied: branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp (from r69505, /trunk/boost/spirit/repository/home/qi/directive/kwd.hpp)
==============================================================================
--- /trunk/boost/spirit/repository/home/qi/directive/kwd.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -204,6 +204,26 @@
kwd_infinite_iterator& operator= (kwd_infinite_iterator const&);
};
+ // This class enables the transportation of parameters needed to call
+ // the occurence constraint checker from higher level calls
+ // It also serves to select the correct parse function call
+ // of the keyword parser. The implementation changes depending if it is
+ // called form a keyword parsing loop or not.
+ template <typename Skipper, typename NoCasePass>
+ struct skipper_keyword_marker
+ {
+ typedef NoCasePass no_case_pass;
+
+ skipper_keyword_marker(Skipper const &skipper,bool &flag,int &counter) :
+ skipper(skipper)
+ , flag(flag)
+ , counter(counter)
+ {}
+
+ const Skipper &skipper;
+ bool &flag;
+ int &counter;
+ };
template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase >
struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase > >
@@ -270,7 +290,31 @@
return r;
}
- template <typename Iterator, typename Context
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute,typename NoCasePass>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
+ , Attribute &attr) const
+ {
+
+ typedef typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ subject_attribute;
+
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+ >::type predicate;
+
+ if((no_case_keyword::value && NoCasePass::value) || !NoCasePass::value)
+ {
+ if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
+ return iter.register_successful_parse(skipper.flag,skipper.counter);
+ }
+ return false;
+ }
+
+ template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
@@ -282,7 +326,7 @@
typedef typename mpl::and_<
traits::is_container<Attribute>
- , mpl::not_< traits::detail::attribute_is_compatible< subject_attribute,Attribute > >
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
>::type predicate;
// Parse the keyword
@@ -301,27 +345,7 @@
first = save;
return flag;
}
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool kwd_loop_parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr, bool no_case_pass) const
- {
-
- typedef typename traits::attribute_of<
- Subject, Context, Iterator>::type
- subject_attribute;
-
- typedef typename mpl::and_<
- traits::is_container<Attribute>
- , mpl::not_< traits::detail::attribute_is_compatible< subject_attribute,Attribute > >
- >::type predicate;
-
- if((no_case_keyword::value && no_case_pass) || !no_case_pass)
- return parse_impl(first,last,context,skipper,attr, predicate());
- return false;
- }
+
template <typename Context>
info what(Context& context) const
Modified: branches/release/boost/spirit/repository/home/qi/nonterminal/subrule.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/nonterminal/subrule.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/nonterminal/subrule.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -202,7 +202,7 @@
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
- typename make_attribute::type, subrule_attr_type, domain>
+ typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
@@ -256,7 +256,7 @@
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
- typename make_attribute::type, subrule_attr_type, domain>
+ typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
Copied: branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp (from r69671, /trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp)
==============================================================================
--- /trunk/boost/spirit/repository/home/qi/operator/detail/keywords.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -14,2812 +14,26 @@
namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
+ // This helper class enables jumping over intermediate directives
+ // down the kwd parser iteration count checking policy
+ struct register_successful_parse
{
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
- }
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
+ template <typename Subject>
+ static bool call(Subject const &subject,bool &flag, int &counter)
{
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
- }
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- };
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Elements, typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,typename traits::not_is_unused<Attribute>::type());
-
+ return subject.iter.register_successful_parse(flag,counter);
}
-
- template <typename Subject,typename Index>
- bool call_subject_unused(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- template <typename Subject,typename Index>
- bool call_subject(
- Subject const &subject, Iterator &first, Iterator const &last
- , Context& context, Skipper const& skipper
- , Index& idx ) const
- {
- Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
- {
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- return true;
- }
- save = save;
- return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
+ template <typename Subject, typename Action>
+ static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
{
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
-
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
- // Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
- return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
+ return subject.subject.iter.register_successful_parse(flag,counter);
}
- // Handle normal attributes
- template <typename T> bool call(T &idx, mpl::true_) const{
- return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
+ template <typename Subject>
+ static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
+ {
+ return subject.subject.iter.register_successful_parse(flag,counter);
}
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
};
-
-}}}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
-
// Variant visitor class which handles dispatching the parsing to the selected parser
// This also handles passing the correct attributes and flags/counters to the subject parsers
@@ -2840,7 +54,6 @@
template<typename T> bool operator()(T& idx) const
{
return call(idx,typename traits::not_is_unused<Attribute>::type());
-
}
template <typename Subject,typename Index>
@@ -2850,47 +63,16 @@
, Index& idx ) const
{
Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,unused, NoCasePass::value ))
+ skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+
+ if(subject.parse(first,last,context,marked_skipper,unused))
{
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
return true;
}
save = save;
return false;
}
- template <typename Subject, typename Index, typename Action> bool call_subject_unused(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename traits::make_attribute<attr_type, unused_type> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(unused);
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
template <typename Subject,typename Index>
bool call_subject(
@@ -2898,55 +80,19 @@
, Context& context, Skipper const& skipper
, Index& idx ) const
{
+
Iterator save = first;
- if(subject.kwd_loop_parse(first,last,context,skipper,fusion::at_c<Index::value>(attr), NoCasePass::value ))
+ skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+ if(subject.parse(first,last,context,marked_skipper,fusion::at_c<Index::value>(attr)))
{
- if(subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
return true;
}
save = save;
return false;
- }
-
- template <typename Subject, typename Index, typename Action> bool call_subject(
- spirit::qi::action<Subject, Action> const &subject, Iterator &first
- , Iterator const &last, Context& context, Skipper const& skipper
- , Index &idx) const
- {
-
- typedef typename Subject::template attribute<Context, Iterator>::type attr_type;
- typedef typename fusion::result_of::value_at<Attribute,typename Index::value>::type subject_attribute;
- typedef typename traits::make_attribute<attr_type, subject_attribute> make_attribute;
-
- // create an attribute if one is not supplied
- typedef traits::transform_attribute<
- typename make_attribute::type, attr_type, spirit::qi::domain> transform;
-
- typename make_attribute::type made_attr = make_attribute::call(fusion::at_c<Index::value>(attr));
- typename transform::type local_attr = transform::pre(made_attr);
-
- Iterator save = first;
- if (subject.subject.kwd_loop_parse(first, last, context, skipper, local_attr, NoCasePass::value ))
- {
- if(subject.subject.iter.register_successful_parse(flags[Index::value],counters[Index::value]))
- {
- // call the function, passing the attribute, the context.
- // The client can return false to fail parsing.
- if (traits::action_dispatch<Subject>()(subject.f, local_attr, context))
- return true;
+ }
- }
- }
- // reset iterators if semantic action failed the match
- // retrospectively
- first = save;
- return false;
- }
-
// Handle unused attributes
- template <typename T> bool call(T &idx, mpl::false_) const{
-
- //if( fusion::at_c<T::value>(elements).parse_impl( first, last, context, skipper, unused, mpl::false_() ) )
+ template <typename T> bool call(T &idx, mpl::false_) const{
return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
}
// Handle normal attributes
@@ -2967,4 +113,3 @@
}}}}}
#endif
-
Copied: branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp (from r69671, /trunk/boost/spirit/repository/home/qi/operator/keywords.hpp)
==============================================================================
--- /trunk/boost/spirit/repository/home/qi/operator/keywords.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -20,6 +20,7 @@
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/iter_fold.hpp>
+#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
@@ -27,6 +28,7 @@
#include <boost/spirit/home/qi/string/symbols.hpp>
#include <boost/spirit/home/qi/string/lit.hpp>
#include <boost/spirit/home/qi/action/action.hpp>
+#include <boost/spirit/home/qi/directive/hold.hpp>
#include <boost/mpl/count_if.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/copy.hpp>
@@ -71,6 +73,9 @@
template <typename Subject, typename Action>
struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
+ template <typename Subject>
+ struct is_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_kwd_parser_id<Subject> {};
+
// Keywords operator
template <typename Elements, typename Modifiers>
struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
@@ -160,6 +165,11 @@
{
typedef typename Element::char_type type;
};
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::char_type type;
+ };
// never called, but needed for decltype-based result_of (C++0x)
template <typename Element>
@@ -247,6 +257,11 @@
{
typedef typename Element::no_case_keyword type;
};
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::no_case_keyword type;
+ };
// never called, but needed for decltype-based result_of (C++0x)
template <typename Element>
@@ -379,7 +394,21 @@
flags[Position::value]=parser.iter.flag_init();
return 0;
}
-
+
+ template <typename T, typename Position>
+ int call( const int i, const spirit::qi::hold_directive<T> & parser, const Position position) const
+ {
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.subject.keyword.str),
+ traits::get_end<char_type>(parser.subject.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
shared_ptr<keywords_type> lookup;
flags_type & flags;
@@ -609,9596 +638,3 @@
#endif
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/domain.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, traits::sequence_attribute_transform, Iterator, spirit::qi::domain >::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/domain.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, traits::sequence_attribute_transform, Iterator, spirit::qi::domain >::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/domain.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, traits::sequence_attribute_transform, Iterator, spirit::qi::domain >::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
-
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_ > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::false_> parser_visitor_type;
-
- typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- , mpl::true_> no_case_parser_visitor_type;
-
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
- no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
-/*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
-
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-#if !defined(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
-#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <boost/spirit/home/qi/meta_compiler.hpp>
-#include <boost/spirit/home/qi/detail/permute_function.hpp>
-#include <boost/spirit/home/qi/detail/attributes.hpp>
-#include <boost/spirit/home/support/detail/what_function.hpp>
-#include <boost/spirit/home/support/info.hpp>
-#include <boost/spirit/home/support/unused.hpp>
-#include <boost/fusion/include/iter_fold.hpp>
-#include <boost/optional.hpp>
-#include <boost/foreach.hpp>
-#include <boost/array.hpp>
-#include <boost/spirit/home/qi/string/symbols.hpp>
-#include <boost/spirit/home/qi/string/lit.hpp>
-#include <boost/spirit/home/qi/action/action.hpp>
-#include <boost/mpl/count_if.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/equal_to.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/variant/static_visitor.hpp>
-#include <boost/type_traits/remove_const.hpp>
-#include <boost/type_traits/is_same.hpp>
-
-namespace boost { namespace spirit
-{
- ///////////////////////////////////////////////////////////////////////////
- // Enablers
- ///////////////////////////////////////////////////////////////////////////
- template <>
- struct use_operator<qi::domain, proto::tag::divides > // enables /
- : mpl::true_ {};
-
- template <>
- struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
- : mpl::true_ {};
-}}
-
-namespace boost { namespace spirit { namespace repository { namespace qi
-{
-
- // kwd directive parser type identification
- namespace detail
- {
- BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
-
-
- }
-
- // kwd directive type query
- template <typename T>
- struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
-
- template <typename Subject, typename Action>
- struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
-
- // Keywords operator
- template <typename Elements, typename Modifiers>
- struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
- {
- template <typename Context, typename Iterator>
- struct attribute
- {
- // Put all the element attributes in a tuple
- typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
-
- // Now, build a fusion vector over the attributes. Note
- // that build_fusion_vector 1) removes all unused attributes
- // and 2) may return unused_type if all elements have
- // unused_type(s).
- typedef typename
- traits::build_fusion_vector<all_attributes>::type
- type;
- };
-
- /// Make sure that all subjects are of the kwd type
- typedef typename mpl::count_if<
- Elements,
- mpl::not_<
- is_kwd_parser<
- mpl::_1
- >
- >
- > non_kwd_subject_count;
-
- /// If the assertion fails here then you probably forgot to wrap a
- /// subject of the / operator in a kwd directive
- BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
-
- ///////////////////////////////////////////////////////////////////////////
- // build_parser_tags
- //
- // Builds a boost::variant from an mpl::range_c in order to "mark" every
- // parser of the fusion sequence. The integer constant is used in the parser
- // dispatcher functor in order to use the parser corresponding to the recognised
- // keyword.
- ///////////////////////////////////////////////////////////////////////////
-
- template <typename Sequence>
- struct build_parser_tags
- {
- // Get the sequence size
- typedef typename mpl::size< Sequence >::type sequence_size;
-
- // Create an integer_c constant for every parser in the sequence
- typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
-
- // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
-
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
- };
-
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
-
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, is_same<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
-
- typedef typename kwd_count::asdfa debug;
-
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
- typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
-
- // build a bool array and an integer array which will be used to
- // check that the repetition constraints of the kwd parsers are
- // met and bail out a soon as possible
- typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
- typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
-
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
- {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
- }
-
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
-
- // Variant visitor class which handles dispatching the parsing to the selected parser
- // This also handles passing the correct attributes and flags/counters to the subject parsers
-
- template < typename Iterator ,typename Context ,typename Skipper
- ,typename Flags ,typename Counters ,typename Attribute>
- class parse_dispatcher
- : public boost::static_visitor<bool>
- {
- public:
- parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Flags &flags, Counters &counters, Attribute& attr, bool case_insensitive_pass) :
- elements(elements), first(first), last(last)
- , context(context), skipper(skipper)
- , flags(flags),counters(counters), attr(attr)
- , case_insensitive_pass(case_insensitive_pass) {}
-
- template<typename T> bool operator()(T& idx) const
- {
- return call(idx,case_insensitive_pass,typename traits::not_is_unused<Attribute>::type());
-
- }
- // Handle unused attributes
- template <typename T> bool call(T &idx, bool case_insensitive_pass, mpl::false_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,unused
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
- // Handle normal attributes
- template <typename T> bool call(T &idx,bool case_insensitive_pass, mpl::true_) const{
- return fusion::at_c<T::value>(elements).parse(
- first
- ,last
- ,context
- ,skipper
- ,fusion::at_c<T::value>(attr)
- ,flags[T::value],counters[T::value]
- ,case_insensitive_pass
- );
- }
-
-
- const Elements &elements;
- Iterator &first;
- const Iterator &last;
- Context & context;
- const Skipper &skipper;
- Flags &flags;
- Counters &counters;
- Attribute &attr;
- bool case_insensitive_pass;
- };
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_) const
- {
-
- // Select which parse function to call
- // We need to handle the case where kwd / ikwd directives have been mixed
- // This is where we decide which function should be called.
- return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
- );
- }
-
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
- parser_visitor_type parse_visitor(elements, first, last
- , context, skipper, flags
- , counters, attr, false);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
-
- spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- // Handle the mixed kwd and ikwd case
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
- bool parse_impl(Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
- {
-
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
-
- flags_type flags(flags_init);
- //flags.assign(false);
-
- counters_type counters;
- counters.assign(0);
-
- typedef parse_dispatcher<Iterator, Context, Skipper
- , flags_type, counters_type
- , typename traits::wrap_if_not_tuple<Attribute>::type
- > parser_visitor_type;
-
- parser_visitor_type parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,false);
- parser_visitor_type no_case_parse_visitor(elements,first,last
- ,context,skipper,flags,counters,attr,true);
-
- // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
- // array.
- // The kwd directive sets and increments the counter when a successeful parse occured
- // as well as the slot of the corresponding parser to true in the flags array as soon
- // the minimum repetition requirement is met and keeps that value to true as long as
- // the maximum repetition requirement is met.
- // The parsing takes place here in two steps:
- // 1) parse a keyword and fetch the parser index associated with that keyword
- // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
- while(true)
- {
- spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
- {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
- {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
- save = first;
- }
- else
- {
- // Check that we are leaving the keywords parser in a successfull state
- BOOST_FOREACH(bool &valid,flags)
- {
- if(!valid)
- {
- first = save;
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- template <typename Context>
- info what(Context& context) const
- {
- info result("keywords");
- fusion::for_each(elements,
- spirit::detail::what_function<Context>(result, context));
- return result;
- }
- flags_type flags_init;
- Elements elements;
- shared_ptr<keywords_type> lookup;
-
- };
-}}}}
-
-namespace boost { namespace spirit { namespace qi {
- ///////////////////////////////////////////////////////////////////////////
- // Parser generators: make_xxx function (objects)
- ///////////////////////////////////////////////////////////////////////////
- template <typename Elements, typename Modifiers >
- struct make_composite<proto::tag::divides, Elements, Modifiers >
- {
- typedef repository::qi::keywords<Elements,Modifiers> result_type;
- result_type operator()(Elements ref, unused_type) const
- {
- return result_type(ref);
- }
- };
-
-
-}}}
-
-namespace boost { namespace spirit { namespace traits
-{
- // We specialize this for keywords (see support/attributes.hpp).
- // For keywords, we only wrap the attribute in a tuple IFF
- // it is not already a fusion tuple.
- template <typename Elements, typename Modifiers,typename Attribute>
- struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
- : wrap_if_not_tuple<Attribute> {};
-
- template <typename Elements, typename Modifiers>
- struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
- : nary_has_semantic_action<Elements> {};
-}}}
-
-#endif
-
Modified: branches/release/boost/spirit/repository/home/qi/primitive.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/primitive.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/primitive.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -11,6 +11,7 @@
#pragma once
#endif
+#include <boost/spirit/repository/home/qi/primitive/advance.hpp>
#include <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp>
#include <boost/spirit/repository/home/qi/primitive/iter_pos.hpp>
Modified: branches/release/boost/spirit/version.hpp
==============================================================================
--- branches/release/boost/spirit/version.hpp (original)
+++ branches/release/boost/spirit/version.hpp 2011-03-26 13:09:12 EDT (Sat, 26 Mar 2011)
@@ -1,6 +1,6 @@
/*=============================================================================
- Copyright (c) 2001-2010 Joel de Guzman
- Copyright (c) 2001-2010 Hartmut Kaiser
+ 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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk